summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm')
-rw-r--r--src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm100
1 files changed, 46 insertions, 54 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
index 3b5b5fc6f8..cec8301cf6 100644
--- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
+++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
@@ -1,42 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2012 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Christoph Schleifenbaum <christoph.schleifenbaum@kdab.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2012 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Christoph Schleifenbaum <christoph.schleifenbaum@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
/****************************************************************************
**
@@ -92,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()
@@ -100,9 +70,11 @@ 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:NSEventMaskLeftMouseUp | NSEventMaskRightMouseUp | NSEventMaskOtherMouseUp];
+ [m_statusItem.button sendActionOn:NSEventMaskLeftMouseDown | NSEventMaskRightMouseDown | NSEventMaskOtherMouseDown];
}
void QCocoaSystemTrayIcon::cleanup()
@@ -117,8 +89,6 @@ void QCocoaSystemTrayIcon::cleanup()
[m_delegate release];
m_delegate = nil;
-
- m_menu = nullptr;
}
QRect QCocoaSystemTrayIcon::geometry() const
@@ -204,6 +174,7 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
r.moveCenter(fullHeightPixmap.rect().center());
p.drawPixmap(r, pixmap);
}
+ fullHeightPixmap.setDevicePixelRatio(devicePixelRatio);
auto *nsimage = [NSImage imageFromQImage:fullHeightPixmap.toImage()];
[nsimage setTemplate:icon.isMask()];
@@ -213,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)
@@ -261,7 +251,7 @@ void QCocoaSystemTrayIcon::showMessage(const QString &title, const QString &mess
}
}
-void QCocoaSystemTrayIcon::statusItemClicked()
+void QCocoaSystemTrayIcon::emitActivated()
{
auto *mouseEvent = NSApp.currentEvent;
@@ -271,7 +261,7 @@ void QCocoaSystemTrayIcon::statusItemClicked()
activationReason = QPlatformSystemTrayIcon::DoubleClick;
} else {
auto mouseButton = cocoaButton2QtButton(mouseEvent);
- if (mouseButton == Qt::MidButton)
+ if (mouseButton == Qt::MiddleButton)
activationReason = QPlatformSystemTrayIcon::MiddleClick;
else if (mouseButton == Qt::RightButton)
activationReason = QPlatformSystemTrayIcon::Context;
@@ -280,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
@@ -305,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