From 121a30ccef3b6306c1da4f415fe1305dbf2dd901 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 13 Apr 2017 12:25:47 +0200 Subject: [PATCH] QPlatformSystemTrayIcon: Add signal contextMenuRequested() Add a signal passing the global position of the context menu. For platforms that do not provide native menus, QSystemTrayIcon will show a QMenu based menu. Change-Id: I799e4a84ca38e00ea33f3c842ea4ca43ecb8c83f Reviewed-by: J-P Nurmi Reviewed-by: Maurice Kalinowski Reviewed-by: Joerg Bornemann --- src/gui/kernel/qplatformsystemtrayicon.cpp | 11 ++++++++++- src/gui/kernel/qplatformsystemtrayicon.h | 2 ++ src/widgets/util/qsystemtrayicon.cpp | 18 ++++++++++++++++++ src/widgets/util/qsystemtrayicon_win.cpp | 1 + 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qplatformsystemtrayicon.cpp b/src/gui/kernel/qplatformsystemtrayicon.cpp index 5481997b3c..296beda0f9 100644 --- a/src/gui/kernel/qplatformsystemtrayicon.cpp +++ b/src/gui/kernel/qplatformsystemtrayicon.cpp @@ -139,11 +139,20 @@ QPlatformSystemTrayIcon::~QPlatformSystemTrayIcon() Returns \c true if the system tray supports messages on the platform. */ +/*! + \fn void QPlatformSystemTrayIcon::contextMenuRequested(QPoint globalPos, const QPlatformScreen *screen) + This signal is emitted when the context menu is requested. + In particular, on platforms where createMenu() returns nullptr, + its emission will cause QSystemTrayIcon to show a QMenu-based menu. + \sa activated() + \since 5.10 +*/ + /*! \fn void QPlatformSystemTrayIcon::activated(QPlatformSystemTrayIcon::ActivationReason reason) This signal is emitted when the user activates the system tray icon. \a reason specifies the reason for activation. - \sa QSystemTrayIcon::ActivationReason + \sa QSystemTrayIcon::ActivationReason, contextMenuRequested() */ /*! diff --git a/src/gui/kernel/qplatformsystemtrayicon.h b/src/gui/kernel/qplatformsystemtrayicon.h index c52dbfbd78..948a6c099d 100644 --- a/src/gui/kernel/qplatformsystemtrayicon.h +++ b/src/gui/kernel/qplatformsystemtrayicon.h @@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE class QPlatformMenu; +class QPlatformScreen; class QIcon; class QString; class QRect; @@ -88,6 +89,7 @@ public: Q_SIGNALS: void activated(QPlatformSystemTrayIcon::ActivationReason reason); + void contextMenuRequested(QPoint globalPos, const QPlatformScreen *screen); void messageClicked(); }; diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp index cc5026b56d..2249f4c4aa 100644 --- a/src/widgets/util/qsystemtrayicon.cpp +++ b/src/widgets/util/qsystemtrayicon.cpp @@ -61,6 +61,9 @@ #include "qdesktopwidget.h" #include "qbitmap.h" +#include +#include + QT_BEGIN_NAMESPACE static QIcon messageIcon2qIcon(QSystemTrayIcon::MessageIcon icon) @@ -196,8 +199,23 @@ QSystemTrayIcon::~QSystemTrayIcon() void QSystemTrayIcon::setContextMenu(QMenu *menu) { Q_D(QSystemTrayIcon); + QMenu *oldMenu = d->menu.data(); d->menu = menu; d->updateMenu_sys(); + if (oldMenu != menu && d->qpa_sys) { + // Show the QMenu-based menu for QPA plugins that do not provide native menus + if (oldMenu && !oldMenu->platformMenu()) + QObject::disconnect(d->qpa_sys, &QPlatformSystemTrayIcon::contextMenuRequested, menu, nullptr); + if (menu && !menu->platformMenu()) { + QObject::connect(d->qpa_sys, &QPlatformSystemTrayIcon::contextMenuRequested, + menu, + [menu](QPoint globalNativePos, const QPlatformScreen *platformScreen) + { + QScreen *screen = platformScreen ? platformScreen->screen() : nullptr; + menu->popup(QHighDpi::fromNativePixels(globalNativePos, screen), nullptr); + }); + } + } } /*! diff --git a/src/widgets/util/qsystemtrayicon_win.cpp b/src/widgets/util/qsystemtrayicon_win.cpp index 3974e6d055..91a553e28f 100644 --- a/src/widgets/util/qsystemtrayicon_win.cpp +++ b/src/widgets/util/qsystemtrayicon_win.cpp @@ -334,6 +334,7 @@ bool QSystemTrayIconSys::winEvent( MSG *m, long *result ) QSystemTrayIconPrivate::QSystemTrayIconPrivate() : sys(0), + qpa_sys(nullptr), visible(false) { }