From 8a029bd1f2cc857b206dc72cea2ebf703c18b1c2 Mon Sep 17 00:00:00 2001 From: Kun Zhang Date: Fri, 24 Jul 2026 15:28:39 +0800 Subject: [PATCH] fix(popup): close window popup on outside touch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Handle touch presses delivered to the parent window as outside presses. 2. Detect grabbed touch presses outside the popup using local coordinates. Log: Close window popups when users touch outside them. Influence: Restores outside-touch closing for popups. fix(popup): 支持触摸外部区域关闭窗口弹窗 1. 将父窗口收到的触摸按下事件作为弹窗外部操作处理。 2. 使用局部坐标识别被弹窗抓取的外部触摸事件。 Log: 修复触摸弹窗外部区域时窗口弹窗无法关闭的问题。 PMS: BUG-370839 Influence: 恢复弹窗的外部触摸关闭行为。 --- src/private/dpopupwindowhandle.cpp | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/private/dpopupwindowhandle.cpp b/src/private/dpopupwindowhandle.cpp index 1f857327..a02db708 100644 --- a/src/private/dpopupwindowhandle.cpp +++ b/src/private/dpopupwindowhandle.cpp @@ -29,6 +29,15 @@ static bool isPopupItem(QQuickItem *item) return item && item->inherits("QQuickPopupItem"); } +static bool isTouchOutsideWindow(const QTouchEvent *event, const QWindow *window) +{ + if (!window || event->points().isEmpty()) + return false; + + const QRectF windowRect(QPointF(), QSizeF(window->size())); + return !windowRect.contains(event->points().constFirst().position()); +} + DPopupWindowHandle::~DPopupWindowHandle() { if (m_trackedItem) @@ -177,9 +186,23 @@ bool DPopupWindowHandle::eventFilter(QObject *watched, QEvent *event) requestPopupFocus(); } - // Close popup on parent window click (only while popup is visible) - if (watched == m_parentWindow && event->type() == QEvent::MouseButtonPress - && m_popup->property("visible").toBool()) { + bool pressedOutside = false; + + if (watched == m_parentWindow) { + pressedOutside = event->type() == QEvent::MouseButtonPress + || event->type() == QEvent::TouchBegin; + } + + // On some platforms a popup window grabs touch input. In that case a + // press outside the popup is still delivered to the popup window, and + // the touch position must be checked against the popup's local geometry. + if (watched == m_popupWin && event->type() == QEvent::TouchBegin) { + const auto *touchEvent = static_cast(event); + pressedOutside = isTouchOutsideWindow(touchEvent, m_popupWin); + } + + // Close popup on a press outside (only while popup is visible). + if (pressedOutside && m_popup->property("visible").toBool()) { int closePolicy = m_popup->property("closePolicy").toInt(); bool closeOnPressOutside = closePolicy & 0x01; bool closeOnPressOutsideParent = closePolicy & 0x02;