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 <davidedmundson@kde.org>
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
This commit is contained in:
Vlad Zahorodnii 2024-05-29 14:47:44 +03:00
parent 949bcf8712
commit 1dc1938cd7
5 changed files with 24 additions and 9 deletions

View File

@ -400,7 +400,7 @@ bool QWaylandXdgSurface::handleExpose(const QRegion &region)
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());

View File

@ -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;

View File

@ -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);

View File

@ -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; }

View File

@ -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()));