From 61c3daf72cf92580450744f50016f1a92b9df3e1 Mon Sep 17 00:00:00 2001 From: Fangxun Zhao Date: Thu, 11 Jun 2026 17:25:25 +0800 Subject: [PATCH] fix: simulate right-click on tray item long press MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Add sendRightClickForSurface method to synthesize right-click events via Wayland seat for tray surfaces 2. Expose shellSurface property in PluginSurface for QML access 3. Handle long press in ShellSurfaceItemProxy TapHandler to trigger right-click on tray items 4. Handle long press in PanelTrayItem MouseArea and prevent normal click from firing after long press Log: Simulate right-click mouse events on tray items when long-pressed via touch input fix: 托盘项长按模拟右键点击 1. 新增 sendRightClickForSurface 方法,通过 Wayland seat 向托盘 表面发送右键点击事件 2. 在 PluginSurface 中暴露 shellSurface 属性供 QML 访问 3. 在 ShellSurfaceItemProxy 的 TapHandler 中处理长按,触发 托盘项右键点击 4. 在 PanelTrayItem 的 MouseArea 中处理长按并防止长按结束后 误触发普通点击 Log: 在触控长按托盘项时模拟右键点击鼠标事件 PMS: BUG-364527 --- panels/dock/DockCompositor.qml | 3 +++ panels/dock/pluginmanagerextension.cpp | 14 +++++++++++++ panels/dock/pluginmanagerextension_p.h | 4 ++++ panels/dock/tray/ShellSurfaceItemProxy.qml | 5 +++++ panels/dock/tray/quickpanel/PanelTrayItem.qml | 20 ++++++++++++++++++- 5 files changed, 45 insertions(+), 1 deletion(-) diff --git a/panels/dock/DockCompositor.qml b/panels/dock/DockCompositor.qml index dd1ed95e9..e206ee7a4 100644 --- a/panels/dock/DockCompositor.qml +++ b/panels/dock/DockCompositor.qml @@ -23,6 +23,9 @@ Item { function notifyXEmbedWindowMoveResult(wid, success) { pluginManager.notifyXEmbedWindowMoveResult(wid, success) } + function sendRightClickForSurface() { + pluginManager.sendRightClickForSurface() + } property ListModel trayPluginSurfaces: ListModel {} property ListModel quickPluginSurfaces: ListModel {} diff --git a/panels/dock/pluginmanagerextension.cpp b/panels/dock/pluginmanagerextension.cpp index c6ff5e517..b130a2257 100644 --- a/panels/dock/pluginmanagerextension.cpp +++ b/panels/dock/pluginmanagerextension.cpp @@ -1008,3 +1008,17 @@ void PluginManager::onTextInputSurfaceEnabled(QWaylandSurface *surface) } } } + +void PluginManager::sendRightClickForSurface() +{ + QWaylandCompositor *compositor = qobject_cast(extensionContainer()); + if (!compositor) + return; + + QWaylandSeat *seat = compositor->defaultSeat(); + if (!seat) + return; + + seat->sendMousePressEvent(Qt::RightButton); + seat->sendMouseReleaseEvent(Qt::RightButton); +} diff --git a/panels/dock/pluginmanagerextension_p.h b/panels/dock/pluginmanagerextension_p.h index 45e94b101..d3b46284c 100644 --- a/panels/dock/pluginmanagerextension_p.h +++ b/panels/dock/pluginmanagerextension_p.h @@ -73,6 +73,10 @@ class PluginManager : public QWaylandCompositorExtensionTemplate, // result: true = success, false = error Q_INVOKABLE void notifyXEmbedWindowMoveResult(uint32_t wid, bool result); + // Called from QML to synthesize a right-click (mouse press + release) + // on the given Wayland surface, e.g. on long press from touch input + Q_INVOKABLE void sendRightClickForSurface(); + uint32_t dockPosition() const; void setDockPosition(uint32_t dockPosition); diff --git a/panels/dock/tray/ShellSurfaceItemProxy.qml b/panels/dock/tray/ShellSurfaceItemProxy.qml index 57dc8cb8b..fe0af9f15 100644 --- a/panels/dock/tray/ShellSurfaceItemProxy.qml +++ b/panels/dock/tray/ShellSurfaceItemProxy.qml @@ -52,6 +52,11 @@ Item { } TapHandler { id: tapHandler + onLongPressed: { + if (tapHandler.point.device.type === PointerDevice.TouchScreen) { + DockCompositor.sendRightClickForSurface() + } + } } onVisibleChanged: function () { diff --git a/panels/dock/tray/quickpanel/PanelTrayItem.qml b/panels/dock/tray/quickpanel/PanelTrayItem.qml index 5e4ccd113..7566ac20f 100644 --- a/panels/dock/tray/quickpanel/PanelTrayItem.qml +++ b/panels/dock/tray/quickpanel/PanelTrayItem.qml @@ -116,6 +116,24 @@ Control { MouseArea { id: mouseHandler anchors.fill: parent - onClicked: root.clicked() + onPressed: function (mouse) { + longPressTriggered = false + isTouchSource = (mouse.source !== Qt.MouseEventNotSynthesized) + } + onPressAndHold: { + if (isTouchSource) { + longPressTriggered = true + DockCompositor.sendRightClickForSurface() + } + } + onClicked: { + if (!longPressTriggered) { + root.clicked() + } + longPressTriggered = false + } + + property bool longPressTriggered: false + property bool isTouchSource: false } }