diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 33c04a8d835..7f21f03d43d 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -1969,10 +1969,15 @@ static inline bool doCheckUnGrabAncestor(QXcbConnection *conn) return true; } -static bool ignoreLeaveEvent(quint8 mode, quint8 detail, QXcbConnection *conn = nullptr) +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) - && mode == XCB_NOTIFY_MODE_GRAB && detail == XCB_NOTIFY_DETAIL_ANCESTOR) + && mode == XCB_NOTIFY_MODE_GRAB && detail == XCB_NOTIFY_DETAIL_ANCESTOR) || (mode == XCB_NOTIFY_MODE_UNGRAB && detail == XCB_NOTIFY_DETAIL_INFERIOR) || detail == XCB_NOTIFY_DETAIL_VIRTUAL || detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL); @@ -1992,14 +1997,13 @@ void QXcbWindow::handleEnterNotifyEvent(int event_x, int event_y, int root_x, in { connection()->setTime(timestamp); - const QPoint global = QPoint(root_x, root_y); - if (ignoreEnterEvent(mode, detail, connection()) || connection()->mousePressWindow()) return; // Updates scroll valuators, as user might have done some scrolling outside our X client. connection()->xi2UpdateScrollingDevices(); + const QPoint global = QPoint(root_x, root_y); const QPoint local(event_x, event_y); QWindowSystemInterface::handleEnterEvent(window(), local, global); } @@ -2009,8 +2013,11 @@ void QXcbWindow::handleLeaveNotifyEvent(int root_x, int root_y, { connection()->setTime(timestamp); - if (ignoreLeaveEvent(mode, detail, connection()) || connection()->mousePressWindow()) + QXcbWindow *mousePressWindow = connection()->mousePressWindow(); + if (ignoreLeaveEvent(mode, detail, connection()) + || (mousePressWindow && windowContainsGlobalPoint(mousePressWindow, root_x, root_y))) { return; + } // check if enter event is buffered auto event = connection()->eventQueue()->peek([](xcb_generic_event_t *event, int type) { @@ -2028,6 +2035,8 @@ 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)) + connection()->setMousePressWindow(nullptr); } free(enter);