From a35ffa93d7d3092adfe9daf0c89045aee9d416bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Mon, 4 Jul 2016 15:06:20 +0200 Subject: [PATCH] Use hiddenInternal() for a ShellClient which got unmapped Summary: So far when a ShellClient got unmapped ready_for_painting was set to false. That is the ShellClient was treated in the same way as a not yet shown window. It was completely excluded from painting, a close animation impossible. This change makes use of the functionality available in Client::hiddenInternal(). The window is considered as hidden, thus still excluded from e.g. getting input events, but could be rendered any time as we still have a previous window pixmap (if referenced). This allows to have it considered in the rendering pass, but effects still cannot make use of it as that state is not yet exposed to the effects. Reviewers: #kwin, #plasma_on_wayland Subscribers: plasma-devel, kwin Tags: #plasma_on_wayland, #kwin Differential Revision: https://phabricator.kde.org/D2083 --- abstract_client.h | 1 + autotests/integration/shell_client_test.cpp | 4 ++++ client.h | 2 +- composite.cpp | 7 ++++++- input.cpp | 2 +- scene.cpp | 6 ++---- shell_client.cpp | 8 ++++++-- shell_client.h | 3 +++ 8 files changed, 24 insertions(+), 9 deletions(-) diff --git a/abstract_client.h b/abstract_client.h index 35eee4ad80..3d02289830 100644 --- a/abstract_client.h +++ b/abstract_client.h @@ -294,6 +294,7 @@ public: virtual bool isCloseable() const = 0; // TODO: remove boolean trap virtual bool isShown(bool shaded_is_shown) const = 0; + virtual bool isHiddenInternal() const = 0; // TODO: remove boolean trap virtual void hideClient(bool hide) = 0; virtual bool isFullScreenable() const = 0; diff --git a/autotests/integration/shell_client_test.cpp b/autotests/integration/shell_client_test.cpp index 1d9cff47e5..e7d3a652d9 100644 --- a/autotests/integration/shell_client_test.cpp +++ b/autotests/integration/shell_client_test.cpp @@ -98,6 +98,8 @@ void TestShellClient::testMapUnmapMap() auto client = clientAddedSpy.first().first().value(); QVERIFY(client); QVERIFY(client->isShown(true)); + QCOMPARE(client->isHiddenInternal(), false); + QCOMPARE(client->readyForPainting(), true); QCOMPARE(workspace()->activeClient(), client); // now unmap @@ -108,6 +110,8 @@ void TestShellClient::testMapUnmapMap() surface->attachBuffer(Buffer::Ptr()); surface->commit(Surface::CommitFlag::None); QVERIFY(hiddenSpy.wait()); + QCOMPARE(client->readyForPainting(), true); + QCOMPARE(client->isHiddenInternal(), true); QVERIFY(windowClosedSpy.isEmpty()); QVERIFY(!workspace()->activeClient()); diff --git a/client.h b/client.h index 08e25abe3a..994cc47fcb 100644 --- a/client.h +++ b/client.h @@ -167,7 +167,7 @@ public: /// Is not minimized and not hidden. I.e. normally visible on some virtual desktop. bool isShown(bool shaded_is_shown) const override; - bool isHiddenInternal() const; // For compositing + bool isHiddenInternal() const override; // For compositing ShadeMode shadeMode() const override; // Prefer isShade() void setShade(ShadeMode mode) override; diff --git a/composite.cpp b/composite.cpp index f4d1e3d8ab..e87d8ffe20 100644 --- a/composite.cpp +++ b/composite.cpp @@ -749,9 +749,14 @@ bool Compositor::windowRepaintsPending() const if (!c->repaints().isEmpty()) return true; if (auto w = waylandServer()) { + const bool locked = waylandServer()->isScreenLocked(); const auto &clients = w->clients(); for (auto c : clients) { - if (c->isShown(true) && !c->repaints().isEmpty()) { + if (locked && !c->isLockScreen() && !c->isInputMethod()) { + // ignore not visible windows while locked + continue; + } + if (c->readyForPainting() && !c->repaints().isEmpty()) { return true; } } diff --git a/input.cpp b/input.cpp index 3d88d93c76..69deb308c8 100644 --- a/input.cpp +++ b/input.cpp @@ -1312,7 +1312,7 @@ Toplevel *InputRedirection::findToplevel(const QPoint &pos) continue; } if (AbstractClient *c = dynamic_cast(t)) { - if (!c->isOnCurrentActivity() || !c->isOnCurrentDesktop() || c->isMinimized() || !c->isCurrentTab()) { + if (!c->isOnCurrentActivity() || !c->isOnCurrentDesktop() || c->isMinimized() || !c->isCurrentTab() || c->isHiddenInternal()) { continue; } } diff --git a/scene.cpp b/scene.cpp index 834a731e60..9f31c89182 100644 --- a/scene.cpp +++ b/scene.cpp @@ -800,10 +800,8 @@ void Scene::Window::resetPaintingEnabled() disable_painting |= PAINT_DISABLED_BY_MINIMIZE; if (c->tabGroup() && c != c->tabGroup()->current()) disable_painting |= PAINT_DISABLED_BY_TAB_GROUP; - if (Client *cc = dynamic_cast(c)) { - if (cc->isHiddenInternal()) { - disable_painting |= PAINT_DISABLED; - } + if (c->isHiddenInternal()) { + disable_painting |= PAINT_DISABLED; } } } diff --git a/shell_client.cpp b/shell_client.cpp index 08176e877f..98175d7ccc 100644 --- a/shell_client.cpp +++ b/shell_client.cpp @@ -339,7 +339,12 @@ void ShellClient::markAsMapped() } m_unmapped = false; - setReadyForPainting(); + if (!ready_for_painting) { + setReadyForPainting(); + } else { + addRepaintFull(); + emit windowShown(this); + } if (shouldExposeToWindowManagement()) { setupWindowManagementInterface(); } @@ -868,7 +873,6 @@ void ShellClient::resizeWithChecks(int w, int h, ForceGeometry_t force) void ShellClient::unmap() { m_unmapped = true; - ready_for_painting = false; destroyWindowManagementInterface(); if (Workspace::self()) { addWorkspaceRepaint(visibleRect()); diff --git a/shell_client.h b/shell_client.h index 117bb2e2b6..7da0962609 100644 --- a/shell_client.h +++ b/shell_client.h @@ -72,6 +72,9 @@ public: bool isMovableAcrossScreens() const override; bool isResizable() const override; bool isShown(bool shaded_is_shown) const override; + bool isHiddenInternal() const override { + return m_unmapped; + } void hideClient(bool hide) override; MaximizeMode maximizeMode() const override; QRect geometryRestore() const override {