diff options
-rw-r--r-- | qtwayland.pro | 6 | ||||
-rw-r--r-- | src/plugins/platforms/wayland_common/qwaylandshellsurface.cpp | 20 | ||||
-rw-r--r-- | src/plugins/platforms/wayland_common/qwaylandshellsurface.h | 1 | ||||
-rw-r--r-- | src/plugins/platforms/wayland_common/qwaylandwindow.cpp | 35 | ||||
-rw-r--r-- | src/plugins/platforms/wayland_common/qwaylandwindow.h | 8 |
5 files changed, 67 insertions, 3 deletions
diff --git a/qtwayland.pro b/qtwayland.pro index 24e104b56..02e8c1463 100644 --- a/qtwayland.pro +++ b/qtwayland.pro @@ -11,7 +11,8 @@ qtCompileTest(xcomposite) load(qt_parts) !config_wayland { - error(QtWayland requires Wayland 1.0.3 or higher) + warning("QtWayland requires Wayland 1.0.3 or higher") + SUBDIRS = } !config_xkbcommon { @@ -19,7 +20,8 @@ load(qt_parts) } !config_wayland_scanner { - error(QtWayland requires wayland-scanner) + warning("QtWayland requires wayland-scanner") + SUBDIRS = } !config_wayland_egl { diff --git a/src/plugins/platforms/wayland_common/qwaylandshellsurface.cpp b/src/plugins/platforms/wayland_common/qwaylandshellsurface.cpp index c9eb5da53..986890732 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshellsurface.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandshellsurface.cpp @@ -138,6 +138,25 @@ void QWaylandShellSurface::updateTransientParent(QWindow *parent) flags); } +void QWaylandShellSurface::setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, int serial) +{ + QWaylandWindow *parent_wayland_window = parent->topLevelWindow(); + if (!parent_wayland_window || !parent_wayland_window->shellSurface()) + return; + + // set_popup expects a position relative to the parent + QPoint transientPos = m_window->geometry().topLeft(); // this is absolute + transientPos -= parent_wayland_window->geometry().topLeft(); + if (parent_wayland_window->decoration()) { + transientPos.setX(transientPos.x() + parent_wayland_window->decoration()->margins().left()); + transientPos.setY(transientPos.y() + parent_wayland_window->decoration()->margins().top()); + } + + wl_shell_surface_set_popup(object(), device->wl_seat(), serial, + parent_wayland_window->wl_surface(), + transientPos.x(), transientPos.y(), 0); +} + void QWaylandShellSurface::setClassName(const char *className) { set_class(className); @@ -162,4 +181,5 @@ void QWaylandShellSurface::shell_surface_configure(uint32_t edges, void QWaylandShellSurface::shell_surface_popup_done() { + QCoreApplication::postEvent(m_window->window(), new QCloseEvent()); } diff --git a/src/plugins/platforms/wayland_common/qwaylandshellsurface.h b/src/plugins/platforms/wayland_common/qwaylandshellsurface.h index 90dd04ff9..9e886cf0a 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshellsurface.h +++ b/src/plugins/platforms/wayland_common/qwaylandshellsurface.h @@ -74,6 +74,7 @@ private: void setTopLevel(); void updateTransientParent(QWindow *parent); + void setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, int serial); void setClassName(const char *_class); diff --git a/src/plugins/platforms/wayland_common/qwaylandwindow.cpp b/src/plugins/platforms/wayland_common/qwaylandwindow.cpp index a322c2bb5..666222107 100644 --- a/src/plugins/platforms/wayland_common/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandwindow.cpp @@ -79,6 +79,8 @@ QWaylandWindow::QWaylandWindow(QWindow *window) , mFrameCallback(0) , mResizeExposedSent(false) , mSentInitialResize(false) + , mMouseDevice(0) + , mMouseSerial(0) , mState(Qt::WindowNoState) { init(mDisplay->createSurface(static_cast<QtWayland::wl_surface *>(this))); @@ -177,11 +179,18 @@ void QWaylandWindow::setGeometry(const QRect &rect) void QWaylandWindow::setVisible(bool visible) { - if (visible) { if (mBuffer) attach(mBuffer->buffer(), 0, 0); + if (window()->type() == Qt::Popup && transientParent()) { + QWaylandWindow *parent = transientParent(); + mMouseDevice = parent->mMouseDevice; + mMouseSerial = parent->mMouseSerial; + + mShellSurface->setPopup(transientParent(), mMouseDevice, mMouseSerial); + } + if (!mSentInitialResize) { QWindowSystemInterface::handleGeometryChange(window(), geometry()); mSentInitialResize = true; @@ -425,8 +434,32 @@ void QWaylandWindow::setDecoration(QWaylandDecoration *decoration) } } +QWaylandWindow *QWaylandWindow::topLevelWindow() +{ + QWaylandWindow *w = this; + while (w->QPlatformWindow::parent()) { + w = static_cast<QWaylandWindow *>(w->QPlatformWindow::parent()); + } + return w; +} + +QWaylandWindow *QWaylandWindow::transientParent() const +{ + if (window()->transientParent()) { + // Take the top level window here, since the transient parent may be some non-native + // QWindow, which cannot have the mMouseDevice and mMouseSerial + return static_cast<QWaylandWindow *>(window()->transientParent()->handle())->topLevelWindow(); + } + return 0; +} + void QWaylandWindow::handleMouse(QWaylandInputDevice *inputDevice, ulong timestamp, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods) { + if (b != Qt::NoButton) { + mMouseSerial = inputDevice->serial(); + mMouseDevice = inputDevice; + } + if (mWindowDecoration) { handleMouseEventWithDecoration(inputDevice, timestamp,local,global,b,mods); return; diff --git a/src/plugins/platforms/wayland_common/qwaylandwindow.h b/src/plugins/platforms/wayland_common/qwaylandwindow.h index a80b3c752..3cd891f65 100644 --- a/src/plugins/platforms/wayland_common/qwaylandwindow.h +++ b/src/plugins/platforms/wayland_common/qwaylandwindow.h @@ -157,11 +157,17 @@ public: inline bool isMaximized() const { return mState == Qt::WindowMaximized; } inline bool isFullscreen() const { return mState == Qt::WindowFullScreen; } + QWaylandWindow *topLevelWindow(); + QWaylandWindow *transientParent() const; + QMutex *resizeMutex() { return &mResizeLock; } + public slots: void doResize(); protected: + virtual void createDecorationInstance() {} + QWaylandDisplay *mDisplay; QWaylandShellSurface *mShellSurface; QWaylandExtendedSurface *mExtendedWindow; @@ -185,6 +191,8 @@ protected: QPoint mOffset; QIcon mWindowIcon; + QWaylandInputDevice *mMouseDevice; + int mMouseSerial; Qt::WindowState mState; |