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) { }