From 8d4204ac0d1354818987c4b0fafcf7abde442626 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Wed, 31 Aug 2016 16:08:25 +0200 Subject: [PATCH] Remove non visible internal windows from the x stacking order Summary: KWin always has a few internal windows around which are not visible. A QWindow created somewhere, but not shown. Such windows should not be part of the stacking order. If they are it breaks code which looks at the top most window in the stacking order like e.g. SlidebackEffect. This change ensures that the stacking order gets updated whenever a ShellClient gets hidden and that internal windows with isShown being false are excluded from the stacking order. BUG: 364483 Reviewers: #kwin, #plasma_on_wayland Subscribers: plasma-devel, kwin Tags: #plasma_on_wayland, #kwin Differential Revision: https://phabricator.kde.org/D2636 --- autotests/integration/internal_window.cpp | 12 ++++++++++++ layers.cpp | 4 +++- workspace.cpp | 7 +++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/autotests/integration/internal_window.cpp b/autotests/integration/internal_window.cpp index ca4d105007..e0ac2b92b5 100644 --- a/autotests/integration/internal_window.cpp +++ b/autotests/integration/internal_window.cpp @@ -208,6 +208,8 @@ void InternalWindowTest::testEnterLeave() QVERIFY(c->isInternal()); QCOMPARE(workspace()->findToplevel(&win), c); QCOMPARE(c->geometry(), QRect(0, 0, 100, 100)); + QVERIFY(c->isShown(false)); + QVERIFY(workspace()->xStackingOrder().contains(c)); QSignalSpy enterSpy(&win, &HelperWindow::entered); QVERIFY(enterSpy.isValid()); @@ -236,6 +238,16 @@ void InternalWindowTest::testEnterLeave() // inside the mask we should still get an enter kwinApp()->platform()->pointerMotion(QPoint(25, 27), timestamp++); QTRY_COMPARE(enterSpy.count(), 2); + + // hide the window, which should be removed from the stacking order + win.hide(); + QTRY_VERIFY(!c->isShown(false)); + QVERIFY(!workspace()->xStackingOrder().contains(c)); + + // show again + win.show(); + QTRY_VERIFY(c->isShown(false)); + QVERIFY(workspace()->xStackingOrder().contains(c)); } void InternalWindowTest::testPointerPressRelease() diff --git a/layers.cpp b/layers.cpp index a368def145..b1c02ccb1b 100644 --- a/layers.cpp +++ b/layers.cpp @@ -719,7 +719,9 @@ ToplevelList Workspace::xStackingOrder() const if (waylandServer()) { const auto clients = waylandServer()->internalClients(); for (auto c: clients) { - x_stacking << c; + if (c->isShown(false)) { + x_stacking << c; + } } } return x_stacking; diff --git a/workspace.cpp b/workspace.cpp index d2971de365..acbbcf4879 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -411,6 +411,13 @@ void Workspace::init() } } ); + connect(c, &ShellClient::windowHidden, this, + [this] { + x_stacking_dirty = true; + updateStackingOrder(true); + updateClientArea(); + } + ); } ); connect(w, &WaylandServer::shellClientRemoved, this,