Commit f045cf30 authored by Kai Uwe Broulik's avatar Kai Uwe Broulik 🍇 Committed by Nate Graham
Browse files

[System Tray] Emit pressed signal on compact representation in popup, too

Some actions, such as middle click to mute, trigger only on press. Some applets
also need a pressed-click because of some legacy autoclose on focus change
bug.

Unfortunately, QML does not disambiguate the "pressed" property and "pressed(mouse)"
signal with argument, so this has to be done awkwardly through QMetaObject on C++ side.

BUG: 426646
BUG: 452893
FIXED-IN: 5.25.0
parent 853c29bf
Pipeline #180487 passed with stage
in 15 minutes and 13 seconds
......@@ -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) {
......
......@@ -13,6 +13,8 @@
#include "systemtraysettings.h"
#include <QMenu>
#include <QMetaMethod>
#include <QMetaObject>
#include <QQuickItem>
#include <QQuickWindow>
#include <QScreen>
......@@ -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) {
......
......@@ -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
*/
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment