diff options
Diffstat (limited to 'src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm | 53 |
1 files changed, 40 insertions, 13 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm index c004cd69b5..cec8301cf6 100644 --- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm +++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm @@ -56,6 +56,12 @@ #include "qcocoascreen.h" #include <QtGui/private/qcoregraphics_p.h> +#warning NSUserNotification was deprecated in macOS 11. \ +We should be using UserNotifications.framework instead. \ +See QTBUG-110998 for more information. +#define NSUserNotificationCenter QT_IGNORE_DEPRECATIONS(NSUserNotificationCenter) +#define NSUserNotification QT_IGNORE_DEPRECATIONS(NSUserNotification) + QT_BEGIN_NAMESPACE void QCocoaSystemTrayIcon::init() @@ -64,6 +70,8 @@ void QCocoaSystemTrayIcon::init() m_delegate = [[QStatusItemDelegate alloc] initWithSysTray:this]; + // In case the status item does not have a menu assigned to it + // we fall back to the item's button to detect activation. m_statusItem.button.target = m_delegate; m_statusItem.button.action = @selector(statusItemClicked); [m_statusItem.button sendActionOn:NSEventMaskLeftMouseDown | NSEventMaskRightMouseDown | NSEventMaskOtherMouseDown]; @@ -81,8 +89,6 @@ void QCocoaSystemTrayIcon::cleanup() [m_delegate release]; m_delegate = nil; - - m_menu = nullptr; } QRect QCocoaSystemTrayIcon::geometry() const @@ -178,12 +184,31 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon) void QCocoaSystemTrayIcon::updateMenu(QPlatformMenu *menu) { - // We don't set the menu property of the NSStatusItem here, - // as that would prevent us from receiving the action for the - // click, and we wouldn't be able to emit the activated signal. - // Instead we show the menu manually when the status item is - // clicked. - m_menu = static_cast<QCocoaMenu *>(menu); + auto *nsMenu = menu ? static_cast<QCocoaMenu *>(menu)->nsMenu() : nil; + if (m_statusItem.menu == nsMenu) + return; + + if (m_statusItem.menu) { + [NSNotificationCenter.defaultCenter removeObserver:m_delegate + name:NSMenuDidBeginTrackingNotification + object:m_statusItem.menu + ]; + } + + m_statusItem.menu = nsMenu; + + if (m_statusItem.menu) { + // When a menu is assigned, NSStatusBarButtonCell will intercept the mouse + // down to pop up the menu, and we never see the NSStatusBarButton action. + // To ensure we emit the 'activated' signal in both cases we detect when + // menu starts tracking, which happens before the menu delegate is sent + // the menuWillOpen callback we use to emit aboutToShow for the menu. + [NSNotificationCenter.defaultCenter addObserver:m_delegate + selector:@selector(statusItemMenuBeganTracking:) + name:NSMenuDidBeginTrackingNotification + object:m_statusItem.menu + ]; + } } void QCocoaSystemTrayIcon::updateToolTip(const QString &toolTip) @@ -226,7 +251,7 @@ void QCocoaSystemTrayIcon::showMessage(const QString &title, const QString &mess } } -void QCocoaSystemTrayIcon::statusItemClicked() +void QCocoaSystemTrayIcon::emitActivated() { auto *mouseEvent = NSApp.currentEvent; @@ -245,9 +270,6 @@ void QCocoaSystemTrayIcon::statusItemClicked() } emit activated(activationReason); - - if (NSMenu *menu = m_menu ? m_menu->nsMenu() : nil) - QT_IGNORE_DEPRECATIONS([m_statusItem popUpStatusItemMenu:menu]); } QT_END_NAMESPACE @@ -270,7 +292,12 @@ QT_END_NAMESPACE - (void)statusItemClicked { - self.platformSystemTray->statusItemClicked(); + self.platformSystemTray->emitActivated(); +} + +- (void)statusItemMenuBeganTracking:(NSNotification*)notification +{ + self.platformSystemTray->emitActivated(); } - (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification |