From 39e7b26243fb6cb8485f2e0818ed8937a669962c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Thu, 9 Jun 2016 16:54:06 +0200 Subject: [PATCH] Introduce a RequestGeometryBlocker in ShellClient Summary: The idea is to not send multiple resize requests to a client when we know that we might have multiple geometry changes. E.g. when going from maximized to restored the borders change and trigger a resize in addition to the resize from switching to restored. The implementation is inspired by the GeometryUpdateBlocker. Reviewers: #kwin, #plasma_on_wayland Subscribers: plasma-devel, kwin Tags: #plasma_on_wayland, #kwin Differential Revision: https://phabricator.kde.org/D1808 --- autotests/wayland/maximize_test.cpp | 9 +++++++++ shell_client.cpp | 7 +++++++ shell_client.h | 23 +++++++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/autotests/wayland/maximize_test.cpp b/autotests/wayland/maximize_test.cpp index b694d7f20f..0579409299 100644 --- a/autotests/wayland/maximize_test.cpp +++ b/autotests/wayland/maximize_test.cpp @@ -214,6 +214,15 @@ void TestMaximized::testMaximizedPassedToDeco() QCOMPARE(client->maximizeMode(), MaximizeMode::MaximizeRestore); QCOMPARE(maximizedChangedSpy.count(), 2); QCOMPARE(maximizedChangedSpy.last().first().toBool(), false); + QCOMPARE(bordersChangedSpy.count(), 2); + QVERIFY(decoration->borderTop() != 0); + QVERIFY(decoration->borderLeft() != 0); + QVERIFY(decoration->borderRight() != 0); + QVERIFY(decoration->borderBottom() != 0); + + QVERIFY(sizeChangedSpy.wait()); + QCOMPARE(sizeChangedSpy.count(), 2); + QCOMPARE(sizeChangedSpy.last().first().toSize(), QSize(100, 50)); } void TestMaximized::testInitiallyMaximized() diff --git a/shell_client.cpp b/shell_client.cpp index ee00cd2be7..391707cab1 100644 --- a/shell_client.cpp +++ b/shell_client.cpp @@ -348,6 +348,7 @@ void ShellClient::createDecoration(const QRect &oldGeom) connect(decoration, &KDecoration2::Decoration::bordersChanged, this, [this]() { GeometryUpdatesBlocker blocker(this); + RequestGeometryBlocker requestBlocker(this); QRect oldgeom = geometry(); if (!isShade()) checkWorkspacePosition(oldgeom); @@ -565,6 +566,7 @@ void ShellClient::changeMaximize(bool horizontal, bool vertical, bool adjust) } MaximizeMode oldMode = m_maximizeMode; StackingUpdatesBlocker blocker(workspace()); + RequestGeometryBlocker geometryBlocker(this); // 'adjust == true' means to update the size only, e.g. after changing workspace size if (!adjust) { if (vertical) @@ -801,10 +803,15 @@ bool ShellClient::isInputMethod() const void ShellClient::requestGeometry(const QRect &rect) { + if (m_requestGeometryBlockCounter != 0) { + m_blockedRequestGeometry = rect; + return; + } m_positionAfterResize.setPoint(rect.topLeft()); if (m_shellSurface) { m_shellSurface->requestSize(rect.size() - QSize(borderLeft() + borderRight(), borderTop() + borderBottom())); } + m_blockedRequestGeometry = QRect(); } void ShellClient::clientFullScreenChanged(bool fullScreen) diff --git a/shell_client.h b/shell_client.h index 77f93e10e5..a783d725a8 100644 --- a/shell_client.h +++ b/shell_client.h @@ -172,6 +172,29 @@ private: bool m_transient = false; bool m_internal; qreal m_opacity = 1.0; + + class RequestGeometryBlocker { + public: + RequestGeometryBlocker(ShellClient *client) + : m_client(client) + { + m_client->m_requestGeometryBlockCounter++; + } + ~RequestGeometryBlocker() + { + m_client->m_requestGeometryBlockCounter--; + if (m_client->m_requestGeometryBlockCounter == 0) { + if (m_client->m_blockedRequestGeometry.isValid()) { + m_client->requestGeometry(m_client->m_blockedRequestGeometry); + } + } + } + private: + ShellClient *m_client; + }; + friend class RequestGeometryBlocker; + int m_requestGeometryBlockCounter = 0; + QRect m_blockedRequestGeometry; }; }