diff --git a/applets/systemtray/package/contents/ui/items/PlasmoidItem.qml b/applets/systemtray/package/contents/ui/items/PlasmoidItem.qml index e56cfdb65..9dc2b45de 100644 --- a/applets/systemtray/package/contents/ui/items/PlasmoidItem.qml +++ b/applets/systemtray/package/contents/ui/items/PlasmoidItem.qml @@ -40,7 +40,7 @@ AbstractItem { //forward click event to the applet var appletItem = applet.compactRepresentationItem ? applet.compactRepresentationItem : applet.fullRepresentationItem const mouseArea = findMouseArea(appletItem) - if (mouseArea) { + if (mouseArea && mouse.button !== Qt.RightButton) { mouseArea.clicked(mouse) } else if (mouse.button === Qt.LeftButton) {//falback plasmoidContainer.activated(null) @@ -51,6 +51,13 @@ AbstractItem { // SNI has few problems, for example legacy applications that still use XEmbed require mouse to be released. if (mouse.button === Qt.RightButton) { plasmoidContainer.contextMenu(mouse); + } else { + const appletItem = applet.compactRepresentationItem ? applet.compactRepresentationItem : applet.fullRepresentationItem + const mouseArea = findMouseArea(appletItem) + if (mouseArea) { + // HACK QML only sees the "mouseArea.pressed" property, not the signal. + Plasmoid.nativeInterface.emitPressed(mouseArea, mouse); + } } } onContextMenu: if (applet) { diff --git a/applets/systemtray/systemtray.cpp b/applets/systemtray/systemtray.cpp index cb6eeda3c..28e1b1970 100644 --- a/applets/systemtray/systemtray.cpp +++ b/applets/systemtray/systemtray.cpp @@ -13,6 +13,8 @@ #include "systemtraysettings.h" #include +#include +#include #include #include #include @@ -244,6 +246,29 @@ bool SystemTray::isSystemTrayApplet(const QString &appletId) return false; } +void SystemTray::emitPressed(QQuickItem *mouseArea, QObject *mouseEvent) +{ + if (!mouseArea || !mouseEvent) { + return; + } + + // QQuickMouseEvent is also private, so we cannot use QMetaObject::invokeMethod with Q_ARG + const QMetaObject *mo = mouseArea->metaObject(); + + const int pressedIdx = mo->indexOfSignal("pressed(QQuickMouseEvent*)"); + if (pressedIdx < 0) { + qCWarning(SYSTEM_TRAY) << "Failed to find onPressed signal on" << mouseArea; + return; + } + + QMetaMethod pressedMethod = mo->method(pressedIdx); + + if (!pressedMethod.invoke(mouseArea, Q_ARG(QObject *, mouseEvent))) { + qCWarning(SYSTEM_TRAY) << "Failed to invoke onPressed signal on" << mouseArea << "with" << mouseEvent; + return; + } +} + SystemTrayModel *SystemTray::systemTrayModel() { if (!m_systemTrayModel) { diff --git a/applets/systemtray/systemtray.h b/applets/systemtray/systemtray.h index 34c503fe3..413d45f12 100644 --- a/applets/systemtray/systemtray.h +++ b/applets/systemtray/systemtray.h @@ -66,6 +66,14 @@ public: */ Q_INVOKABLE bool isSystemTrayApplet(const QString &appletId); + /** + * @brief Emits the "onPressed(mouse)" signal of a MouseArea + * + * This is needed because calling mouseArea.pressed from QML + * only sees the "pressed" property, not the signal + */ + Q_INVOKABLE void emitPressed(QQuickItem *mouseArea, QObject /*QQuickMouseEvent*/ *mouseEvent); + /** * Needed to preserve keyboard navigation */