diff options
author | Liang Qi <liang.qi@theqtcompany.com> | 2016-02-24 14:47:20 +0000 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2016-02-24 14:47:20 +0000 |
commit | b736151c2bb6c68f700d38274d740a6e0cf59a49 (patch) | |
tree | 83e110a7205757addba6e86a3c2367e4b52afa05 /src/plugins/platforms/xcb/qxcbwindow.cpp | |
parent | ff76300a5c9f209f625384f35ad0fdb0acebd799 (diff) | |
parent | 1fadc7292b66d4b3984bf5ef36c70b46b07a1c6b (diff) |
Merge "Merge remote-tracking branch 'origin/5.6' into 5.7" into refs/staging/5.7
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbwindow.cpp')
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.cpp | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 240a1dbc74..939fd5e5b4 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -56,6 +56,7 @@ #include "qxcbsystemtraytracker.h" #include <qpa/qplatformintegration.h> +#include <qpa/qplatformcursor.h> #include <algorithm> @@ -267,6 +268,26 @@ static inline XTextProperty* qstringToXTP(Display *dpy, const QString& s) } #endif // XCB_USE_XLIB +// TODO move this into a utility function in QWindow or QGuiApplication +static QWindow *childWindowAt(QWindow *win, const QPoint &p) +{ + foreach (QObject *obj, win->children()) { + if (obj->isWindowType()) { + QWindow *childWin = static_cast<QWindow *>(obj); + if (childWin->isVisible()) { + if (QWindow *recurse = childWindowAt(childWin, p)) + return recurse; + } + } + } + if (!win->isTopLevel() + && !(win->flags() & Qt::WindowTransparentForInput) + && win->geometry().contains(win->parent()->mapFromGlobal(p))) { + return win; + } + return Q_NULLPTR; +} + static const char *wm_window_type_property_id = "_q_xcb_wm_window_type"; QXcbWindow::QXcbWindow(QWindow *window) @@ -861,6 +882,33 @@ void QXcbWindow::hide() connection()->setMouseGrabber(Q_NULLPTR); m_mapped = false; + + // Hiding a modal window doesn't send an enter event to its transient parent when the + // mouse is already over the parent window, so the enter event must be emulated. + if (window()->isModal()) { + // Get the cursor position at modal window screen + const QPoint nativePos = xcbScreen()->cursor()->pos(); + const QPoint cursorPos = QHighDpi::fromNativePixels(nativePos, xcbScreen()->screenForPosition(nativePos)->screen()); + + // Find the top level window at cursor position. + // Don't use QGuiApplication::topLevelAt(): search only the virtual siblings of this window's screen + QWindow *enterWindow = Q_NULLPTR; + foreach (QPlatformScreen *screen, xcbScreen()->virtualSiblings()) { + if (screen->geometry().contains(cursorPos)) { + const QPoint devicePosition = QHighDpi::toNativePixels(cursorPos, screen->screen()); + enterWindow = screen->topLevelAt(devicePosition); + break; + } + } + + if (enterWindow && enterWindow != window()) { + // Find the child window at cursor position, otherwise use the top level window + if (QWindow *childWindow = childWindowAt(enterWindow, cursorPos)) + enterWindow = childWindow; + const QPoint localPos = enterWindow->mapFromGlobal(cursorPos); + QWindowSystemInterface::handleEnterEvent(enterWindow, localPos, cursorPos); + } + } } static QWindow *tlWindow(QWindow *window) |