From 5ee958ca7e4c37f32b9311124cc2f57126fc602c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Mon, 4 Jul 2016 15:37:30 +0200 Subject: [PATCH] [libkwineffects] Add signals windowShown and windowHidden to EffectsHandler Summary: This allows effects to animate when a window is shown again and when a window gets hidden but not yet closed/destroyed. This situation happens on X11 for e.g. auto hiding panels and on Wayland for pretty much any window which properly unmaps (windowHidden) prior to destroy. Reviewers: #kwin, #plasma_on_wayland Subscribers: plasma-devel, kwin Tags: #plasma_on_wayland, #kwin Differential Revision: https://phabricator.kde.org/D2084 --- autotests/integration/shell_client_test.cpp | 16 ++++++++++++++ effects.cpp | 10 +++++++++ libkwineffects/kwineffects.h | 23 +++++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/autotests/integration/shell_client_test.cpp b/autotests/integration/shell_client_test.cpp index e7d3a652d9..fd7e7ccbf8 100644 --- a/autotests/integration/shell_client_test.cpp +++ b/autotests/integration/shell_client_test.cpp @@ -86,6 +86,10 @@ void TestShellClient::testMapUnmapMap() // this test verifies that mapping a previously mapped window works correctly QSignalSpy clientAddedSpy(waylandServer(), &WaylandServer::shellClientAdded); QVERIFY(clientAddedSpy.isValid()); + QSignalSpy effectsWindowShownSpy(effects, &EffectsHandler::windowShown); + QVERIFY(effectsWindowShownSpy.isValid()); + QSignalSpy effectsWindowHiddenSpy(effects, &EffectsHandler::windowHidden); + QVERIFY(effectsWindowHiddenSpy.isValid()); QScopedPointer surface(Test::createSurface()); QScopedPointer shellSurface(Test::createShellSurface(surface.data())); @@ -101,6 +105,7 @@ void TestShellClient::testMapUnmapMap() QCOMPARE(client->isHiddenInternal(), false); QCOMPARE(client->readyForPainting(), true); QCOMPARE(workspace()->activeClient(), client); + QVERIFY(effectsWindowShownSpy.isEmpty()); // now unmap QSignalSpy hiddenSpy(client, &ShellClient::windowHidden); @@ -114,6 +119,8 @@ void TestShellClient::testMapUnmapMap() QCOMPARE(client->isHiddenInternal(), true); QVERIFY(windowClosedSpy.isEmpty()); QVERIFY(!workspace()->activeClient()); + QCOMPARE(effectsWindowHiddenSpy.count(), 1); + QCOMPARE(effectsWindowHiddenSpy.first().first().value(), client->effectWindow()); QSignalSpy windowShownSpy(client, &ShellClient::windowShown); QVERIFY(windowShownSpy.isValid()); @@ -122,19 +129,28 @@ void TestShellClient::testMapUnmapMap() QVERIFY(windowShownSpy.wait()); QCOMPARE(windowShownSpy.count(), 1); QCOMPARE(clientAddedSpy.count(), 1); + QCOMPARE(client->readyForPainting(), true); + QCOMPARE(client->isHiddenInternal(), false); QCOMPARE(workspace()->activeClient(), client); + QCOMPARE(effectsWindowShownSpy.count(), 1); + QCOMPARE(effectsWindowShownSpy.first().first().value(), client->effectWindow()); // let's unmap again surface->attachBuffer(Buffer::Ptr()); surface->commit(Surface::CommitFlag::None); QVERIFY(hiddenSpy.wait()); QCOMPARE(hiddenSpy.count(), 2); + QCOMPARE(client->readyForPainting(), true); + QCOMPARE(client->isHiddenInternal(), true); QVERIFY(windowClosedSpy.isEmpty()); + QCOMPARE(effectsWindowHiddenSpy.count(), 2); + QCOMPARE(effectsWindowHiddenSpy.last().first().value(), client->effectWindow()); shellSurface.reset(); surface.reset(); QVERIFY(windowClosedSpy.wait()); QCOMPARE(windowClosedSpy.count(), 1); + QCOMPARE(effectsWindowHiddenSpy.count(), 2); } void TestShellClient::testDesktopPresenceChanged() diff --git a/effects.cpp b/effects.cpp index e2a685df18..cf8b1cd930 100644 --- a/effects.cpp +++ b/effects.cpp @@ -386,6 +386,16 @@ void EffectsHandlerImpl::setupAbstractClientConnections(AbstractClient* c) connect(c, &AbstractClient::modalChanged, this, &EffectsHandlerImpl::slotClientModalityChanged); connect(c, &AbstractClient::geometryShapeChanged, this, &EffectsHandlerImpl::slotGeometryShapeChanged); connect(c, &AbstractClient::damaged, this, &EffectsHandlerImpl::slotWindowDamaged); + connect(c, &AbstractClient::windowShown, this, + [this](Toplevel *c) { + emit windowShown(c->effectWindow()); + } + ); + connect(c, &AbstractClient::windowHidden, this, + [this](Toplevel *c) { + emit windowHidden(c->effectWindow()); + } + ); } void EffectsHandlerImpl::setupClientConnections(Client* c) diff --git a/libkwineffects/kwineffects.h b/libkwineffects/kwineffects.h index d3e361256f..d53493c64c 100644 --- a/libkwineffects/kwineffects.h +++ b/libkwineffects/kwineffects.h @@ -1430,6 +1430,29 @@ Q_SIGNALS: **/ void virtualScreenGeometryChanged(); + /** + * The window @p w gets shown again. The window was previously + * initially shown with @link{windowAdded} and hidden with @link{windowHidden}. + * + * @see windowHidden + * @see windowAdded + * @since 5.8 + **/ + void windowShown(KWin::EffectWindow *w); + + /** + * The window @p w got hidden but not yet closed. + * This can happen when a window is still being used and is supposed to be shown again + * with @link{windowShown}. On X11 an example is autohiding panels. On Wayland every + * window first goes through the window hidden state and might get shown again, or might + * get closed the normal way. + * + * @see windowShown + * @see windowClosed + * @since 5.8 + **/ + void windowHidden(KWin::EffectWindow *w); + protected: QVector< EffectPair > loaded_effects; //QHash< QString, EffectFactory* > effect_factories;