From 89024e2bcc1b2c2bae6bd75e85792cc67de9337c Mon Sep 17 00:00:00 2001 From: David Edmundson Date: Mon, 6 Jan 2020 15:10:50 +0000 Subject: [PATCH] Clamp XdgShellClient::clientSize to surface size, not m_windowGeometry Summary: It's perfectly legitimate to call setWindowSize before a buffer is attached. This seems to have happen with plasma surfaces that commit when attaching a shadow, but technically could happen anywhere. By clamping to the applied surface here, we get the wrong window size cached and not re-evaluated when a surface is eventually applied. This leaves us thinking the windowsize is empty but with a massive margin which actually holds the content. We want all internal usages of xdgshellclient to use the window geometry set. Only the wider kwin part needs to care about clamping it to the surface. This fixes popup placement in the plasma panel BUG: 415317 As well as ghost notification popups with no background contrast that you can't interact with. Test Plan: Ran kwin Reviewers: #kwin, zzag Reviewed By: #kwin, zzag Subscribers: romangg, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D26233 --- xdgshellclient.cpp | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/xdgshellclient.cpp b/xdgshellclient.cpp index 477b44a0d4..65b50c4cb1 100644 --- a/xdgshellclient.cpp +++ b/xdgshellclient.cpp @@ -311,9 +311,29 @@ QPoint XdgShellClient::clientContentPos() const return -1 * clientPos(); } +static QRect subSurfaceTreeRect(const SurfaceInterface *surface, const QPoint &position = QPoint()) +{ + QRect rect(position, surface->size()); + + const QList> subSurfaces = surface->childSubSurfaces(); + for (const QPointer &subSurface : subSurfaces) { + if (Q_UNLIKELY(!subSurface)) { + continue; + } + const SurfaceInterface *child = subSurface->surface(); + if (Q_UNLIKELY(!child)) { + continue; + } + rect |= subSurfaceTreeRect(child, position + subSurface->position()); + } + + return rect; +} + QSize XdgShellClient::clientSize() const { - return m_windowGeometry.size(); + const QRect boundingRect = subSurfaceTreeRect(surface()); + return m_windowGeometry.size().boundedTo(boundingRect.size()); } void XdgShellClient::debug(QDebug &stream) const @@ -1163,29 +1183,9 @@ void XdgShellClient::handleWindowClassChanged(const QByteArray &windowClass) setDesktopFileName(windowClass); } -static QRect subSurfaceTreeRect(const SurfaceInterface *surface, const QPoint &position = QPoint()) -{ - QRect rect(position, surface->size()); - - const QList> subSurfaces = surface->childSubSurfaces(); - for (const QPointer &subSurface : subSurfaces) { - if (Q_UNLIKELY(!subSurface)) { - continue; - } - const SurfaceInterface *child = subSurface->surface(); - if (Q_UNLIKELY(!child)) { - continue; - } - rect |= subSurfaceTreeRect(child, position + subSurface->position()); - } - - return rect; -} - void XdgShellClient::handleWindowGeometryChanged(const QRect &windowGeometry) { - const QRect boundingRect = subSurfaceTreeRect(surface()); - m_windowGeometry = windowGeometry & boundingRect; + m_windowGeometry = windowGeometry; m_hasWindowGeometry = true; }