From 1dc1938cd7d444ec21bfa2215185ecaf3d370758 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Wed, 29 May 2024 14:47:44 +0300 Subject: [PATCH] Client: Split requests to set window and content geometry Currently, QWaylandShellSurface::setWindowGeometry() serves several purposes. It's used to specify the bounds of the content when using client side decorations (not preferred but the one that's painted) and it's used to tell the compositor the preferred window size. These two use cases are very different in nature. This change introduces QWaylandShellSurface::setContentGeometry() request, which can be used to communicate the bounds of the client side decorated content. The content geometry is specified in the surface-local coordinate system, i.e. 0,0 is the main surface's top left corner. QWaylandShellSurface::setWindowGeometry() takes window geometry in the global coordinate system, excluding the drop shadows. [ChangeLog][QtWaylandClient][Important Behavior Changes] The QWaylandShellSurface::setWindowGeometry() function is no longer suitable for communicating the bounds of client side decorated content. Custom shell implementations should use QWaylandShellSurface::setContentGeometry() instead. Change-Id: I134ce4f0866d3abbe7050ed6769dc586210eac27 Reviewed-by: David Edmundson Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../xdg-shell/qwaylandxdgshell.cpp | 4 ++-- .../xdg-shell/qwaylandxdgshell_p.h | 2 +- .../platforms/wayland/qwaylandshellsurface.cpp | 6 ++++++ .../platforms/wayland/qwaylandshellsurface_p.h | 4 +++- .../platforms/wayland/qwaylandwindow.cpp | 17 ++++++++++++----- 5 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp index 6e5e47da9e7..6ccda7d265f 100644 --- a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp +++ b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp @@ -400,7 +400,7 @@ bool QWaylandXdgSurface::handleExpose(const QRegion ®ion) if (!isExposed() && !region.isEmpty()) { return true; } - setWindowGeometry(window()->windowContentGeometry()); + setContentGeometry(window()->windowContentGeometry()); return false; } @@ -435,7 +435,7 @@ void QWaylandXdgSurface::propagateSizeHints() setSizeHints(); } -void QWaylandXdgSurface::setWindowGeometry(const QRect &rect) +void QWaylandXdgSurface::setContentGeometry(const QRect &rect) { if (window()->isExposed()) set_window_geometry(rect.x(), rect.y(), rect.width(), rect.height()); diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h index d18ce4d7278..c3a3763a145 100644 --- a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h +++ b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h @@ -62,7 +62,7 @@ public: void applyConfigure() override; bool wantsDecorations() const override; void propagateSizeHints() override; - void setWindowGeometry(const QRect &rect) override; + void setContentGeometry(const QRect &rect) override; bool requestActivate() override; bool requestActivateOnShow() override; void setXdgActivationToken(const QString &token) override; diff --git a/src/plugins/platforms/wayland/qwaylandshellsurface.cpp b/src/plugins/platforms/wayland/qwaylandshellsurface.cpp index fde1e1d3fbd..2dc218c2f75 100644 --- a/src/plugins/platforms/wayland/qwaylandshellsurface.cpp +++ b/src/plugins/platforms/wayland/qwaylandshellsurface.cpp @@ -35,6 +35,12 @@ wl_surface *QWaylandShellSurface::wlSurface() return m_window ? m_window->wlSurface() : nullptr; } +void QWaylandShellSurface::setWindowGeometry(const QRect &rect) +{ + setWindowPosition(rect.topLeft()); + setWindowSize(rect.size()); +} + void QWaylandShellSurface::resizeFromApplyConfigure(const QSize &sizeWithMargins, const QPoint &offset) { m_window->resizeFromApplyConfigure(sizeWithMargins, offset); diff --git a/src/plugins/platforms/wayland/qwaylandshellsurface_p.h b/src/plugins/platforms/wayland/qwaylandshellsurface_p.h index 8632efd04de..07fd82edc50 100644 --- a/src/plugins/platforms/wayland/qwaylandshellsurface_p.h +++ b/src/plugins/platforms/wayland/qwaylandshellsurface_p.h @@ -56,6 +56,7 @@ public: virtual void raise() {} virtual void lower() {} virtual void setContentOrientationMask(Qt::ScreenOrientations orientation) { Q_UNUSED(orientation); } + virtual void setContentGeometry(const QRect &rect) { Q_UNUSED(rect); } virtual void sendProperty(const QString &name, const QVariant &value); @@ -66,8 +67,9 @@ public: virtual void propagateSizeHints() {} - virtual void setWindowGeometry(const QRect &rect) { Q_UNUSED(rect); } + virtual void setWindowGeometry(const QRect &rect); virtual void setWindowPosition(const QPoint &position) { Q_UNUSED(position); } + virtual void setWindowSize(const QSize &size) { Q_UNUSED(size); } virtual bool requestActivate() { return false; } virtual bool requestActivateOnShow() { return false; } diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index 1ab9dc33791..4e2163df785 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -431,6 +431,16 @@ void QWaylandWindow::setGeometry_helper(const QRect &rect) void QWaylandWindow::setGeometry(const QRect &r) { + if (mShellSurface) { + if (!mInResizeFromApplyConfigure) { + const QRect frameGeometry = r.marginsAdded(clientSideMargins()).marginsRemoved(windowContentMargins()); + if (qt_window_private(window())->positionAutomatic) + mShellSurface->setWindowSize(frameGeometry.size()); + else + mShellSurface->setWindowGeometry(frameGeometry); + } + } + auto rect = r; if (fixedToplevelPositions && !QPlatformWindow::parent() && window()->type() != Qt::Popup && window()->type() != Qt::ToolTip) { @@ -454,11 +464,8 @@ void QWaylandWindow::setGeometry(const QRect &r) if (isExposed() && !mInResizeFromApplyConfigure && exposeGeometry != mLastExposeGeometry) sendExposeEvent(exposeGeometry); - if (mShellSurface) { - mShellSurface->setWindowGeometry(windowContentGeometry()); - if (!qt_window_private(window())->positionAutomatic && !mInResizeFromApplyConfigure) - mShellSurface->setWindowPosition(windowGeometry().topLeft()); - } + if (mShellSurface) + mShellSurface->setContentGeometry(windowContentGeometry()); if (isOpaque() && mMask.isEmpty()) setOpaqueArea(QRect(QPoint(0, 0), rect.size()));