Plugin menu items showing as "NSMenuItem" in the app UI and not working

I’m having trouble with my Glyphs Python versions on app version 3.3 (3309). NSMenuItems show up without their proper text and are not functional (see the last two entries in the Glyph menu).

I’m using the homebrew installed python, the macro window would seem to confirm this and the availability of the packages I’ve installed.

The python environment has these packages:

johannes@johannes-musti ~ % brew list | grep python
python-setuptools
python@3.10
python@3.11
python@3.12
python@3.9
johannes@johannes-musti ~ % pip3.11 list           
Package                                           Version
------------------------------------------------- -----------
altgraph                                          0.17.4
appdirs                                           1.4.4
attrs                                             23.2.0
booleanOperations                                 0.9.0
Brotli                                            1.1.0
cffi                                              1.16.0
cffsubr                                           0.3.0
click                                             8.1.7
cocoa-vanilla                                     0.5.0
colorlog                                          6.8.2
cu2qu                                             1.6.7.post2
defcon                                            0.10.2
fontMath                                          0.9.3
fontParts                                         0.10.8
fontPens                                          0.2.4
fonttools                                         4.51.0
fs                                                2.4.16
greenlet                                          3.0.3
hyperglot                                         0.6.3
lxml                                              5.2.2
macholib                                          1.16.3
packaging                                         24.0
pathlib                                           1.0.1
pip                                               24.0
pyclipper                                         1.3.0.post5
pycparser                                         2.22
pyinstaller                                       5.5
pyinstaller-hooks-contrib                         2024.6
pyobjc                                            10.3
pyobjc-core                                       10.3
pyobjc-framework-Accessibility                    10.3
pyobjc-framework-Accounts                         10.3
pyobjc-framework-AddressBook                      10.3
pyobjc-framework-AdServices                       10.3
pyobjc-framework-AdSupport                        10.3
pyobjc-framework-AppleScriptKit                   10.3
pyobjc-framework-AppleScriptObjC                  10.3
pyobjc-framework-ApplicationServices              10.3
pyobjc-framework-AppTrackingTransparency          10.3
pyobjc-framework-AudioVideoBridging               10.3
pyobjc-framework-AuthenticationServices           10.3
pyobjc-framework-AutomaticAssessmentConfiguration 10.3
pyobjc-framework-Automator                        10.3
pyobjc-framework-AVFoundation                     10.3
pyobjc-framework-AVKit                            10.3
pyobjc-framework-AVRouting                        10.3
pyobjc-framework-BackgroundAssets                 10.3
pyobjc-framework-BrowserEngineKit                 10.3
pyobjc-framework-BusinessChat                     10.3
pyobjc-framework-CalendarStore                    10.3
pyobjc-framework-CallKit                          10.3
pyobjc-framework-CFNetwork                        10.3
pyobjc-framework-Cinematic                        10.3
pyobjc-framework-ClassKit                         10.3
pyobjc-framework-CloudKit                         10.3
pyobjc-framework-Cocoa                            10.3
pyobjc-framework-Collaboration                    10.3
pyobjc-framework-ColorSync                        10.3
pyobjc-framework-Contacts                         10.3
pyobjc-framework-ContactsUI                       10.3
pyobjc-framework-CoreAudio                        10.3
pyobjc-framework-CoreAudioKit                     10.3
pyobjc-framework-CoreBluetooth                    10.3
pyobjc-framework-CoreData                         10.3
pyobjc-framework-CoreHaptics                      10.3
pyobjc-framework-CoreLocation                     10.3
pyobjc-framework-CoreMedia                        10.3
pyobjc-framework-CoreMediaIO                      10.3
pyobjc-framework-CoreMIDI                         10.3
pyobjc-framework-CoreML                           10.3
pyobjc-framework-CoreMotion                       10.3
pyobjc-framework-CoreServices                     10.3
pyobjc-framework-CoreSpotlight                    10.3
pyobjc-framework-CoreText                         10.3
pyobjc-framework-CoreWLAN                         10.3
pyobjc-framework-CryptoTokenKit                   10.3
pyobjc-framework-DataDetection                    10.3
pyobjc-framework-DeviceCheck                      10.3
pyobjc-framework-DictionaryServices               10.3
pyobjc-framework-DiscRecording                    10.3
pyobjc-framework-DiscRecordingUI                  10.3
pyobjc-framework-DiskArbitration                  10.3
pyobjc-framework-DVDPlayback                      10.3
pyobjc-framework-EventKit                         10.3
pyobjc-framework-ExceptionHandling                10.3
pyobjc-framework-ExecutionPolicy                  10.3
pyobjc-framework-ExtensionKit                     10.3
pyobjc-framework-ExternalAccessory                10.3
pyobjc-framework-FileProvider                     10.3
pyobjc-framework-FileProviderUI                   10.3
pyobjc-framework-FinderSync                       10.3
pyobjc-framework-FSEvents                         10.3
pyobjc-framework-GameCenter                       10.3
pyobjc-framework-GameController                   10.3
pyobjc-framework-GameKit                          10.3
pyobjc-framework-GameplayKit                      10.3
pyobjc-framework-HealthKit                        10.3
pyobjc-framework-ImageCaptureCore                 10.3
pyobjc-framework-InputMethodKit                   10.3
pyobjc-framework-InstallerPlugins                 10.3
pyobjc-framework-InstantMessage                   10.3
pyobjc-framework-Intents                          10.3
pyobjc-framework-IntentsUI                        10.3
pyobjc-framework-IOBluetooth                      10.3
pyobjc-framework-IOBluetoothUI                    10.3
pyobjc-framework-IOSurface                        10.3
pyobjc-framework-iTunesLibrary                    10.3
pyobjc-framework-KernelManagement                 10.3
pyobjc-framework-LatentSemanticMapping            10.3
pyobjc-framework-LaunchServices                   10.3
pyobjc-framework-libdispatch                      10.3
pyobjc-framework-libxpc                           10.3
pyobjc-framework-LinkPresentation                 10.3
pyobjc-framework-LocalAuthentication              10.3
pyobjc-framework-LocalAuthenticationEmbeddedUI    10.3
pyobjc-framework-MailKit                          10.3
pyobjc-framework-MapKit                           10.3
pyobjc-framework-MediaAccessibility               10.3
pyobjc-framework-MediaLibrary                     10.3
pyobjc-framework-MediaPlayer                      10.3
pyobjc-framework-MediaToolbox                     10.3
pyobjc-framework-Metal                            10.3
pyobjc-framework-MetalFX                          10.3
pyobjc-framework-MetalKit                         10.3
pyobjc-framework-MetalPerformanceShaders          10.3
pyobjc-framework-MetalPerformanceShadersGraph     10.3
pyobjc-framework-MetricKit                        10.3
pyobjc-framework-MLCompute                        10.3
pyobjc-framework-ModelIO                          10.3
pyobjc-framework-MultipeerConnectivity            10.3
pyobjc-framework-NaturalLanguage                  10.3
pyobjc-framework-NetFS                            10.3
pyobjc-framework-Network                          10.3
pyobjc-framework-NetworkExtension                 10.3
pyobjc-framework-NotificationCenter               10.3
pyobjc-framework-OpenDirectory                    10.3
pyobjc-framework-OSAKit                           10.3
pyobjc-framework-OSLog                            10.3
pyobjc-framework-PassKit                          10.3
pyobjc-framework-PencilKit                        10.3
pyobjc-framework-PHASE                            10.3
pyobjc-framework-Photos                           10.3
pyobjc-framework-PhotosUI                         10.3
pyobjc-framework-PreferencePanes                  10.3
pyobjc-framework-PushKit                          10.3
pyobjc-framework-Quartz                           10.3
pyobjc-framework-QuickLookThumbnailing            10.3
pyobjc-framework-ReplayKit                        10.3
pyobjc-framework-SafariServices                   10.3
pyobjc-framework-SafetyKit                        10.3
pyobjc-framework-SceneKit                         10.3
pyobjc-framework-ScreenCaptureKit                 10.3
pyobjc-framework-ScreenSaver                      10.3
pyobjc-framework-ScreenTime                       10.3
pyobjc-framework-ScriptingBridge                  10.3
pyobjc-framework-SearchKit                        10.3
pyobjc-framework-Security                         10.3
pyobjc-framework-SecurityFoundation               10.3
pyobjc-framework-SecurityInterface                10.3
pyobjc-framework-SensitiveContentAnalysis         10.3
pyobjc-framework-ServiceManagement                10.3
pyobjc-framework-SharedWithYou                    10.3
pyobjc-framework-SharedWithYouCore                10.3
pyobjc-framework-ShazamKit                        10.3
pyobjc-framework-Social                           10.3
pyobjc-framework-SoundAnalysis                    10.3
pyobjc-framework-Speech                           10.3
pyobjc-framework-SpriteKit                        10.3
pyobjc-framework-StoreKit                         10.3
pyobjc-framework-Symbols                          10.3
pyobjc-framework-SyncServices                     10.3
pyobjc-framework-SystemConfiguration              10.3
pyobjc-framework-SystemExtensions                 10.3
pyobjc-framework-ThreadNetwork                    10.3
pyobjc-framework-UniformTypeIdentifiers           10.3
pyobjc-framework-UserNotifications                10.3
pyobjc-framework-UserNotificationsUI              10.3
pyobjc-framework-VideoSubscriberAccount           10.3
pyobjc-framework-VideoToolbox                     10.3
pyobjc-framework-Virtualization                   10.3
pyobjc-framework-Vision                           10.3
pyobjc-framework-WebKit                           10.3
PyYAML                                            6.0.1
setuptools                                        65.5.0
six                                               1.16.0
ufo-extractor                                     0.6.0
ufo2ft                                            2.29.0
ufoLib                                            2.2.4
ufoLib2                                           0.13.1
uharfbuzz                                         0.39.1
unicodedata2                                      15.1.0
vanilla                                           0.1.16
xattr                                             1.1.0
zopfli                                            0.2.3

Where are things going wrong here; some package missing, wrong version of something? Attached also the full console log from a Glyphs startup without interaction.

Anything I can do to help debug this?

Cheers,
J.

glyphs-startup-log.txt (67.7 KB)

Further debugging, I’ve uninstalled the “vanilla” package… and made sure to install cocoa-vanilla from Georg’s fork specifically: pip install git+https://github.com/schriftgestalt/vanilla.git

Not saying the issue is with Vanilla, but when I do run e.g. this script I do get errors related to vanilla:

Running as script…
Traceback (most recent call last):
  File "<macro panel>", line 800
  File "<macro panel>", line 46, in main
  File "<macro panel>", line 74, in __init__
  File "<macro panel>", line 151, in startGUI
  File "vanillaWindows.py", line 263, in __setattr__
    _setAttr(Window, self, attr, value)
  File "vanillaBase.py", line 404, in _setAttr
    obj._autoLayoutViews[attr] = view
    ^^^^^^^^^^^^^^^^^^^^
AttributeError: 'Window' object has no attribute '_autoLayoutViews'

This being the isolated code triggering the vanilla error when run from the Macro window:

import vanilla
print(vanilla)
from vanilla import Window

w = Window()
w.showSupported = CheckBox(
    "auto",
    "Show supported",
    sizeStyle="regular",
    value=False,
)

Interestingly the print of the module yields with that source location, not the pip installed one: <module 'vanilla' from '/Users/johannes/Library/Application Support/Glyphs 3/Scripts/site-packages/vanilla/__init__.py'>

I don’t thing that vanilla has anything to do with the menu items. Can you show the code that adds them?

I’m trying to get this plugin to run (I get the same kind of issue, once I open a font the Window MenuItem of the plugin gets added with the correct shortcut, but the title is also “NSMenuItem”).

When trying to debug this I noticed that my own plugin menu items also show like this.

Thus I am suspecting it is something in my environment with one of the packages required by Glyphs to build its/plugin UIs.

When you install TalkingLeaves as described on the repo (with long pip command), don’t install pyobjc and vanilla (remove it from the end of the pip command). That that would produce conflicts.
You might try to remove the “site-packages” folder in the “Scripts” folder and install the TalkingLeaves dependencies again.
If the problem persists, some other plugin is interfering. I would try to rename the “Repositories” and “Plugins” folder, restart Glyphs and only install your plugin.

Okay, got it working eventually with using the Glyphs Python and vanilla module + installing only the missing dependency.

So for using custom Python versions, is there no way to get vanilla/pyobjc working?

If indeed any custom Python version cannot install vanilla/pyobjc in a way that works for plugins, what point is there having those options? For cases that want a custom python but not use any vanilla/pyobjc?

I believe this is an issue with the version of Vanilla. Installing an older version manually should also work. Similarly, in the future, installing the current version might work again.

I just tried to install the current version of vanilla with pip and the menus still work fine. What exactly do you have installed to trigger the problem?

I think I worked it out. The problem is tied to pyobjc, not vanilla. If you’re on GlyphsPython then you’re using pyobjc 10.2, but if you switch to another Python you’ll get the latest pyobjc 10.3, which seems to introduce a new problem. pyobjc is no longer setting the title when you instantiate NSMenuItem, so you have to change this:

    self.menuItem = NSMenuItem(self.name)

to this:

    self.menuItem = NSMenuItem(self.name)
    self.menuItem.setTitle_(self.name)

Also @jkutilek the same problem is in your Favourites plugin.

EDIT: hold on, that change I suggested breaks it for 10.2 though. Still working on it…

EDIT2: we have to keep the self.name parameter in the NSMenuItem() instantiation in order to work with 10.2 and 10.3, which doesn’t really make sense but basically solves it. But now 10.3 is making TalkingLeaves crash when I try to open the window.

So I think the pyobjc 10.3 update has also broken vanilla, because on a related note, this vanilla issue is resolved if I revert back to 10.2.

1 Like

Looks like the Vanilla team is already aware of the problems with pyobjc 10.3.

@GeorgSeifert you might be interested: pyobjc==10.3 breakage · Issue #610 · ronaldoussoren/pyobjc · GitHub

Thanks for figuring this out.

There is an update to pyobjc available that fixes this: pyobjc==10.3 breakage · Issue #610 · ronaldoussoren/pyobjc · GitHub

2 Likes

Is this supposed to be working again? I get

TypeError: NSMenuItem() does not accept positional arguments

on launch for many plugins. Python 3.10 with pyobjc 10.3.1 and vanilla 0.5.1.dev33+g7ec2205 (current git) with Glyphs 3310.

The only thing that works for me is downgrading pyobjc to 10.2 and using Glyphs 3.2.

Ok, I understand now. It’s not gonna work with the old code again. I have to update most of my plugins.

It is supposed to work as before. I’ll have a look.

Perhaps my code was not optimal before.

I changed all occurrences of

newMenuItem = NSMenuItem(name, self.showWindow_)

to

newMenuItem = NSMenuItem.alloc().init()
newMenuItem.setTitle_(name)
newMenuItem.setAction_(self. self.showWindow_)
newMenuItem.setTarget_(self)

and so it seems to work in both pyobjc < 10.3 and >= 10.3.1.

You are right. The pyobjc problem is not solved, yet. I added a comment in the GitHub issue.

It was. This is how it was intended to be.