diff options
Diffstat (limited to 'src/plugins/platforms/xcb')
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 1 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbdrag.cpp | 4 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbscreen.cpp | 5 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.cpp | 48 |
4 files changed, 57 insertions, 1 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index ca19c3dce8..e94433dd4b 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -44,6 +44,7 @@ #include "qtouchdevice.h" #include <qpa/qwindowsysteminterface.h> #include <QDebug> +#include <cmath> #ifdef XCB_USE_XINPUT2 diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index 3983e90205..9409de2406 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -199,6 +199,7 @@ void QXcbDrag::startDrag() XCB_ATOM_ATOM, 32, drag_types.size(), (const void *)drag_types.constData()); setUseCompositing(current_virtual_desktop->compositingActive()); + setScreen(current_virtual_desktop->screens().constFirst()->screen()); QBasicDrag::startDrag(); if (connection()->mouseGrabber() == Q_NULLPTR) shapedPixmapWindow()->setMouseGrabEnabled(true); @@ -328,6 +329,9 @@ void QXcbDrag::move(const QPoint &globalPos) if (virtualDesktop != current_virtual_desktop) { setUseCompositing(virtualDesktop->compositingActive()); recreateShapedPixmapWindow(static_cast<QPlatformScreen*>(screen)->screen(), deviceIndependentPos); + if (connection()->mouseGrabber() == Q_NULLPTR) + shapedPixmapWindow()->setMouseGrabEnabled(true); + current_virtual_desktop = virtualDesktop; } else { QBasicDrag::moveShapedPixmapWindow(deviceIndependentPos); diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index 041a9992bb..339529edf1 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -214,7 +214,10 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe m_geometry = QRect(QPoint(), m_virtualSize); if (m_availableGeometry.isEmpty()) - m_availableGeometry = m_geometry; + m_availableGeometry = m_geometry & m_virtualDesktop->workArea(); + + if (m_sizeMillimeters.isEmpty()) + m_sizeMillimeters = m_virtualSizeMillimeters; readXResources(); 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) |