I’m creating a Python General Plugin and it adds a bunch of menu entries, so should work on layers and others work on master. Right now I have to check if there are selected layers or masters and if not do nothing, but that looks like a bad UX and I’d rather have the menu entries deactivated when they can’t be used, but I have no idea how to do that.
What you are looking for is validateMenuItem:
. Add this method to the object that is the target of the menu item. The method is called with the menu item. Return True
, if the menu item should be enabled, or False
, if not.
The Close Window plugin does this. On line 32, self
is set as the target of the menu item and on line 77 it handles the menu item enabled state:
If you have multiple menu items, check for their selector in validateMenuItem:
to return different results for different menu items.
Thanks for help, but that Objective-C and it is all Greek to me, I’m writing a Python plug-in.
Here is a Python version:
# Close Window
# ============
#
# Copyright 2021 Florian Pircher
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import objc
from AppKit import (
NSEventModifierFlagCommand,
NSEventModifierFlagShift,
NSMenuItem,
)
from GlyphsApp import (Glyphs, FILE_MENU, VIEW_MENU)
from GlyphsApp.plugins import GeneralPlugin
class CloseWindow(GeneralPlugin):
@objc.python_method
def settings(self):
self.name = Glyphs.localize({
"ar": "إغلاق نافذ",
"cs": "Zavřít okno",
"de": "Fenster schließen",
"en": "Close Window",
"es": "Cerrar ventana",
"fr": "Fermer la fenêtre",
"it": "Chiudi la finestra",
"ja": "ウインドウを閉じる",
"ko": "창 닫기",
"pt": "Fechar Janela",
"ru": "Закрыть окно",
"tr": "Pencereyi kapat",
"zh-Hans": "关闭窗口",
"zh-Hant": "關閉視窗",
})
@objc.python_method
def start(self):
closeWindowMenuItem = NSMenuItem.new()
closeWindowMenuItem.setTitle_(self.name)
closeWindowMenuItem.setTarget_(self)
closeWindowMenuItem.setAction_(self.closeWindow_)
if not Glyphs.defaults["com.FlorianPircher.CloseWindow.retainKeyboardEquivalent"]:
viewMenuItem = Glyphs.menu[VIEW_MENU]
viewMenu = viewMenuItem.submenu()
closeTabMenuItemIndex = viewMenu.indexOfItemWithTarget_andAction_(None, "closeEditPage:")
if closeTabMenuItemIndex != -1:
closeTabMenuItem = viewMenu.itemAtIndex_(closeTabMenuItemIndex)
closeTabMenuItem.setKeyEquivalent_("")
closeTabMenuItem.setKeyEquivalentModifierMask_(0)
closeWindowMenuItem.setKeyEquivalent_("W")
closeWindowMenuItem.setKeyEquivalentModifierMask_(NSEventModifierFlagShift | NSEventModifierFlagCommand)
fileMenuItem = Glyphs.menu[FILE_MENU]
fileMenu = fileMenuItem.submenu()
closeMenuItemIndex = fileMenu.indexOfItemWithTarget_andAction_(None, "performClose:")
if closeMenuItemIndex != -1:
fileMenu.insertItem_atIndex_(closeWindowMenuItem, closeMenuItemIndex + 1)
else:
fileMenu.addItem_(closeWindowMenuItem)
def closeWindow_(self, sender):
if Glyphs.font:
Glyphs.font.close()
def validateMenuItem_(self, menuItem):
return Glyphs.font != None
@objc.python_method
def __file__(self):
"""Please leave this method unchanged"""
return __file__
Looking into this, apparently validateMenuItem:
has been deprecated by Apple and is no longer available per default on the upcoming Mac OS 12 (set to be released this fall). As I understand this, just adding a validateMenuItem:
method will not work on macOS 12, you also have to do this:
# ...
NSMenuItemValidation = objc.protocolNamed('NSMenuItemValidation')
class CloseWindow(GeneralPlugin, protocols=[NSMenuItemValidation]):
# ...
But changing the class definition this way only works on macOS 10.14 and later, while Glyphs runs on 10.11 and later.
I think you can ignore this added complexity for now, I just want to add a note here in case the above no longer works on macOS 12.
Thanks! Works like charm (after a fair bit of trial and errors to get this working with my plugin class).