summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--qtwayland.pro6
-rw-r--r--src/plugins/platforms/wayland_common/qwaylandshellsurface.cpp20
-rw-r--r--src/plugins/platforms/wayland_common/qwaylandshellsurface.h1
-rw-r--r--src/plugins/platforms/wayland_common/qwaylandwindow.cpp35
-rw-r--r--src/plugins/platforms/wayland_common/qwaylandwindow.h8
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;