From d2b9fb816ed23c4ce670b972fef7adc6fa8e5e35 Mon Sep 17 00:00:00 2001 From: fuleyi Date: Thu, 21 May 2026 13:52:06 +0800 Subject: [PATCH] fix: handle touch outside popup on X11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Add QTouchEvent handling to MouseGrabEventFilter in frame/ utility_x11.cpp. 2. Detect QEvent::TouchBegin and read the first touch point's global position. 3. When the touch happens outside the target popup window geometry, emit outsideMousePressed() and consume the event. 4. Keep the existing mouse-based outside-click logic unchanged while extending the same close-popup behavior to touch input. 5. This fixes an issue on touch-screen devices where, after the plugin area context menu was shown, tapping other areas of the taskbar did not respond because touch interactions outside the popup were not being handled. Log: Fixed taskbar touch no-response issue when plugin area context menu is open Influence: 1. On an X11 touch-screen device, open the plugin area context menu and tap outside the popup on different taskbar areas; verify the popup closes and the tapped area responds correctly. 2. Verify existing mouse behavior is unchanged: right-click to open the menu, then click outside to close it. 3. Test tapping inside the popup to confirm normal menu interaction is preserved. 4. Test repeated open/close operations with both mouse and touch input to ensure there are no stuck grab states or lost events. 5. Verify no regressions for non-touch environments on X11. fix: 处理 X11 下弹窗外部触控关闭逻辑 1. 在 frame/utility_x11.cpp 的 MouseGrabEventFilter 中新增 QTouchEvent 处理逻辑。 2. 检测 QEvent::TouchBegin,并读取第一个触控点的全局坐标。 3. 当触控位置位于目标弹窗窗口几何范围之外时,触发 outsideMousePressed() 并消费该事件。 4. 在保留原有鼠标外部点击处理逻辑不变的基础上,将相同的关闭弹窗行为扩展 到触控输入。 5. 该修改修复了触控屏设备上插件区域右键菜单弹出后,点击任务栏其他区域无 响应的问题,原因是此前未处理弹窗外部的触控事件。 Log: 修复插件区域右键菜单打开时任务栏触控无响应问题 Influence: 1. 在 X11 触控屏设备上打开插件区域右键菜单后,点击弹窗外的不同任务栏区 域,确认弹窗会关闭且被点击区域能够正常响应。 2. 验证现有鼠标行为不受影响:右键打开菜单后,鼠标点击外部仍可正常关闭。 3. 测试在弹窗内部点击,确认菜单本身的交互仍然正常。 4. 使用鼠标和触控反复执行打开/关闭操作,确认不存在 grab 状态残留或事件丢 失问题。 5. 验证 X11 非触控环境下无回归。 PMS: BUG-362159 Change-Id: I3c6ed96f01408c3c966f17ae7b999858c0c9ec46 --- frame/utility_x11.cpp | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/frame/utility_x11.cpp b/frame/utility_x11.cpp index 708faacca..af7b76652 100644 --- a/frame/utility_x11.cpp +++ b/frame/utility_x11.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2024 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -119,13 +120,28 @@ bool MouseGrabEventFilter::eventFilter(QObject *watched, QEvent *event) if (isMainWindow()) { trySelectGrabWindow(static_cast(event)); } + } else if (event->type() == QEvent::TouchBegin) { + // Handle touch events - close popup when touching outside + QTouchEvent *touchEvent = static_cast(event); + if (!touchEvent->points().isEmpty()) { + QEventPoint pt = touchEvent->points().first(); + // Use frameGeometry() to get global coordinates for comparison + const auto bounding = m_target->frameGeometry(); + const auto pos = pt.globalPosition(); + if (!bounding.contains(pos.toPoint())) { + qCDebug(dsLog) << "touch outside menu window:" << m_target->winId(); + emit outsideMousePressed(); + return true; + } + } } return false; } void MouseGrabEventFilter::mousePressEvent(QMouseEvent *e) { - const auto bounding = m_target->geometry(); + // Use frameGeometry() to get global coordinates for comparison with globalPosition() + const auto bounding = m_target->frameGeometry(); const auto pos = e->globalPosition(); if ((e->position().toPoint().isNull() && !pos.isNull()) || !bounding.contains(pos.toPoint())) { @@ -137,14 +153,16 @@ void MouseGrabEventFilter::mousePressEvent(QMouseEvent *e) bool MouseGrabEventFilter::trySelectGrabWindow(QMouseEvent *e) { - const auto bounding = m_target->geometry(); + // Use frameGeometry() to get global coordinates for comparison with globalPosition() + const auto bounding = m_target->frameGeometry(); auto pos = QPointF(e->globalPosition()); if ((e->position().toPoint().isNull() && !pos.isNull()) || !bounding.contains(pos.toPoint())) { for (auto item : Utility::instance()->allChildrenWindows(m_target)) { if (!item->isVisible() || isMainWindow(item)) continue; - if (item->geometry().contains(pos.toPoint())) { + // Use frameGeometry() for child windows too + if (item->frameGeometry().contains(pos.toPoint())) { qCDebug(dsLog) << "grab mouse for the window:" << item->winId(); m_target->setMouseGrabEnabled(false); item->setMouseGrabEnabled(true);