From a225fb5d8937d237c6b3f9dd9959288ad1be82fc Mon Sep 17 00:00:00 2001 From: Axel Spoerl Date: Thu, 4 Apr 2024 14:39:23 +0200 Subject: [PATCH] XCB: Suppress leave event, when mouse leaves with button pressed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: QTBUG-124003 Pick-to: 6.6 6.5 6.2 5.15 Change-Id: I232f731b4b5f9e332b1297e5fdae2cadbdf2db1a Reviewed-by: Liang Qi Reviewed-by: Błażej Szczygieł (cherry picked from commit 80bfeb4e793c673d540bd7641fc159338f64af1b) Reviewed-by: Qt Cherry-pick Bot --- src/plugins/platforms/xcb/qxcbwindow.cpp | 20 +++++++++++--------- src/plugins/platforms/xcb/qxcbwindow.h | 1 + 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 87974a61e0b..09d4cd9833a 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -1968,8 +1968,10 @@ void QXcbWindow::handleButtonReleaseEvent(int event_x, int event_y, int root_x, return; } - if (connection()->buttonState() == Qt::NoButton) + if (connection()->buttonState() == Qt::NoButton) { connection()->setMousePressWindow(nullptr); + m_ignorePressedWindowOnMouseLeave = false; + } handleMouseEvent(timestamp, local, global, modifiers, type, source); } @@ -1989,11 +1991,6 @@ static inline bool doCheckUnGrabAncestor(QXcbConnection *conn) return true; } -static bool windowContainsGlobalPoint(QXcbWindow *window, int x, int y) -{ - return window ? window->geometry().contains(window->mapFromGlobal(QPoint(x, y))) : false; -} - static bool ignoreLeaveEvent(quint8 mode, quint8 detail, QXcbConnection *conn) { return ((doCheckUnGrabAncestor(conn) @@ -2017,12 +2014,17 @@ void QXcbWindow::handleEnterNotifyEvent(int event_x, int event_y, int root_x, in { connection()->setTime(timestamp); - if (ignoreEnterEvent(mode, detail, connection()) || connection()->mousePressWindow()) + if (ignoreEnterEvent(mode, detail, connection()) + || (connection()->mousePressWindow() && !m_ignorePressedWindowOnMouseLeave)) { return; + } // Updates scroll valuators, as user might have done some scrolling outside our X client. connection()->xi2UpdateScrollingDevices(); + if (mode == XCB_NOTIFY_MODE_UNGRAB && connection()->queryMouseButtons() != Qt::NoButton) + m_ignorePressedWindowOnMouseLeave = true; + const QPoint global = QPoint(root_x, root_y); const QPoint local(event_x, event_y); QWindowSystemInterface::handleEnterEvent(window(), local, global); @@ -2035,7 +2037,7 @@ void QXcbWindow::handleLeaveNotifyEvent(int root_x, int root_y, QXcbWindow *mousePressWindow = connection()->mousePressWindow(); if (ignoreLeaveEvent(mode, detail, connection()) - || (mousePressWindow && windowContainsGlobalPoint(mousePressWindow, root_x, root_y))) { + || (mousePressWindow && !m_ignorePressedWindowOnMouseLeave)) { return; } @@ -2055,7 +2057,7 @@ void QXcbWindow::handleLeaveNotifyEvent(int root_x, int root_y, QWindowSystemInterface::handleEnterLeaveEvent(enterWindow->window(), window(), local, global); } else { QWindowSystemInterface::handleLeaveEvent(window()); - if (!windowContainsGlobalPoint(this, root_x, root_y)) + if (m_ignorePressedWindowOnMouseLeave) connection()->setMousePressWindow(nullptr); } diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 415dff09ba2..0c047d569b8 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -230,6 +230,7 @@ protected: bool m_alertState = false; bool m_minimized = false; bool m_trayIconWindow = false; + bool m_ignorePressedWindowOnMouseLeave = false; xcb_window_t m_netWmUserTimeWindow = XCB_NONE; QSurfaceFormat m_format;