Skip to content

fix: use native NSStatusItem for the macOS tray menu#2759

Open
real-alexei wants to merge 2 commits into
amnezia-vpn:devfrom
real-alexei:fix/macos-native-tray-menu
Open

fix: use native NSStatusItem for the macOS tray menu#2759
real-alexei wants to merge 2 commits into
amnezia-vpn:devfrom
real-alexei:fix/macos-native-tray-menu

Conversation

@real-alexei

Copy link
Copy Markdown

On macOS 14+ the status-item menu is tracked out of process, so Qt's QCocoaSystemTrayIcon menu-tracking observer (installed by setContextMenu) fires asynchronously and calls emitActivated(), which reads -[NSEvent clickCount] when NSApp.currentEvent is no longer a mouse event. clickCount then raises NSInternalInconsistencyException, crashing the app the first time the tray menu is opened.

Stop using QSystemTrayIcon on macOS and own the NSStatusItem ourselves (MacOSStatusIcon), attaching the menu's backing native NSMenu via QMenu::toNSMenu(). AppKit shows the menu natively - with menu-bar highlight and correct anchoring - without registering the crashing observer, and Qt keeps the NSMenu in sync with the QActions so the existing menu logic (enable/disable, translations) is reused. The icon stays colored per state and notifications go through UNUserNotificationCenter. Windows and Linux keep QSystemTrayIcon unchanged.

This also wires up the previously-unused MacOSStatusIcon and removes the orphaned neNotificationHandler.h.

On macOS 14+ the status-item menu is tracked out of process, so Qt's
QCocoaSystemTrayIcon menu-tracking observer (installed by setContextMenu)
fires asynchronously and calls emitActivated(), which reads
-[NSEvent clickCount] when NSApp.currentEvent is no longer a mouse event.
clickCount then raises NSInternalInconsistencyException, crashing the app
the first time the tray menu is opened.

Stop using QSystemTrayIcon on macOS and own the NSStatusItem ourselves
(MacOSStatusIcon), attaching the menu's backing native NSMenu via
QMenu::toNSMenu(). AppKit shows the menu natively - with menu-bar highlight
and correct anchoring - without registering the crashing observer, and Qt
keeps the NSMenu in sync with the QActions so the existing menu logic
(enable/disable, translations) is reused. The icon stays colored per state
and notifications go through UNUserNotificationCenter. Windows and Linux
keep QSystemTrayIcon unchanged.

This also wires up the previously-unused MacOSStatusIcon and removes the
orphaned neNotificationHandler.h.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@real-alexei

Copy link
Copy Markdown
Author
image

@real-alexei

Copy link
Copy Markdown
Author

fixes #2718

@real-alexei

Copy link
Copy Markdown
Author

@ygurov @vkamn Please take a look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant