From a8be959b8f623f121847f0556b901e541909af0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Fl=C3=B6ser?= Date: Wed, 22 Nov 2017 17:33:21 +0100 Subject: [PATCH] Implement geometry update blocking in ShellClient Summary: Commit 188491d3922180f1e1bba8fa2cd3fd2aa4a527c0 introduced a regression in ShellClient and broke the QuickTiling test - sorry about that. This change fixes the failing test. The main reason was a slight change in semantics of setGeometry. But the real problem is/was that the geometry update blocking is not supported in ShellClient. This change brings in the checks from Client to ShellClient, thus that the geometry is properly blocked and when unblocked the geometry is updated correctly or a request is sent. What makes it rather difficult is that the geometry update blocker operates on an updated geom while ShellClient::setGeometry needs to compare to the original geom to determine whether a direct update or a request is required. Thanks to supporting geometry update blocking the changeMaximize calls are adjusted to use setGeometry instead of requestingGeometry directly. Overall this is an important improvement and might also allow us to no longer require the special RequestGeometryBlocker in ShellClient. Test Plan: Tests pass Reviewers: #plasma, #kwin Subscribers: plasma-devel, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D8956 --- shell_client.cpp | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/shell_client.cpp b/shell_client.cpp index 01abc5494a..5e4894881a 100644 --- a/shell_client.cpp +++ b/shell_client.cpp @@ -563,7 +563,22 @@ void ShellClient::updateDecoration(bool check_workspace_pos, bool force) void ShellClient::setGeometry(int x, int y, int w, int h, ForceGeometry_t force) { - Q_UNUSED(force) + if (areGeometryUpdatesBlocked()) { + // when the GeometryUpdateBlocker exits the current geom is passed to setGeometry + // thus we need to set it here. + geom = QRect(x, y, w, h); + if (pendingGeometryUpdate() == PendingGeometryForced) + {} // maximum, nothing needed + else if (force == ForceGeometrySet) + setPendingGeometryUpdate(PendingGeometryForced); + else + setPendingGeometryUpdate(PendingGeometryNormal); + return; + } + if (pendingGeometryUpdate() != PendingGeometryNone) { + // reset geometry to the one before blocking, so that we can compare properly + geom = geometryBeforeUpdateBlocking(); + } // TODO: better merge with Client's implementation if (QSize(w, h) == geom.size() && !m_positionAfterResize.isValid()) { // size didn't change, update directly @@ -582,7 +597,6 @@ void ShellClient::doSetGeometry(const QRect &rect) if (!m_unmapped) { addWorkspaceRepaint(visibleRect()); } - const QRect old = geom; geom = rect; if (m_unmapped && m_geomMaximizeRestore.isEmpty() && !geom.isEmpty()) { @@ -597,6 +611,8 @@ void ShellClient::doSetGeometry(const QRect &rect) if (hasStrut()) { workspace()->updateClientArea(); } + const auto old = geometryBeforeUpdateBlocking(); + updateGeometryBeforeUpdateBlocking(); emit geometryShapeChanged(this, old); if (isResize()) { @@ -850,7 +866,7 @@ void ShellClient::changeMaximize(bool horizontal, bool vertical, bool adjust) if (quickTileMode() != oldQuickTileMode) { emit quickTileModeChanged(); } - requestGeometry(workspace()->clientArea(MaximizeArea, this)); + setGeometry(workspace()->clientArea(MaximizeArea, this)); workspace()->raiseClient(this); } else { if (m_maximizeMode == MaximizeRestore) { @@ -861,9 +877,9 @@ void ShellClient::changeMaximize(bool horizontal, bool vertical, bool adjust) } if (m_geomMaximizeRestore.isValid()) { - requestGeometry(m_geomMaximizeRestore); + setGeometry(m_geomMaximizeRestore); } else { - requestGeometry(workspace()->clientArea(PlacementArea, this)); + setGeometry(workspace()->clientArea(PlacementArea, this)); } } } @@ -908,6 +924,7 @@ void ShellClient::setFullScreen(bool set, bool user) } RequestGeometryBlocker requestBlocker(this); StackingUpdatesBlocker blocker1(workspace()); + GeometryUpdatesBlocker blocker2(this); workspace()->updateClientLayer(this); // active fullscreens get different layer updateDecoration(false, false); if (isFullScreen()) {