From c3cd8df7954f4b136deb67a763103ce333bc0468 Mon Sep 17 00:00:00 2001 From: Anthony Fieroni Date: Wed, 1 Jun 2016 20:46:35 +0300 Subject: [PATCH 1/5] Be sure isCurrentTab returns true REVIEW: 127985 Signed-off-by: Anthony Fieroni --- deleted.cpp | 2 ++ deleted.h | 6 ++++++ libkwineffects/kwineffects.cpp | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/deleted.cpp b/deleted.cpp index 5e0225f593..61b8dbd82e 100644 --- a/deleted.cpp +++ b/deleted.cpp @@ -41,6 +41,7 @@ Deleted::Deleted() , m_minimized(false) , m_modal(false) , m_wasClient(false) + , m_wasCurrentTab(true) , m_decorationRenderer(nullptr) , m_fullscreen(false) { @@ -110,6 +111,7 @@ void Deleted::copyToDeleted(Toplevel* c) connect(c, &AbstractClient::windowClosed, this, &Deleted::mainClientClosed); } m_fullscreen = client->isFullScreen(); + m_wasCurrentTab = client->isCurrentTab(); } } diff --git a/deleted.h b/deleted.h index b89c961ef1..70af56f80a 100644 --- a/deleted.h +++ b/deleted.h @@ -40,6 +40,7 @@ class KWIN_EXPORT Deleted Q_PROPERTY(bool minimized READ isMinimized) Q_PROPERTY(bool modal READ isModal) Q_PROPERTY(bool fullScreen READ isFullScreen CONSTANT) + Q_PROPERTY(bool isCurrentTab READ isCurrentTab) public: static Deleted* create(Toplevel* c); // used by effects to keep the window around for e.g. fadeout effects when it's destroyed @@ -87,6 +88,10 @@ public: bool isFullScreen() const { return m_fullscreen; } + + bool isCurrentTab() const { + return m_wasCurrentTab; + } protected: virtual void debug(QDebug& stream) const; virtual bool shouldUnredirect() const; @@ -115,6 +120,7 @@ private: bool m_modal; QList m_mainClients; bool m_wasClient; + bool m_wasCurrentTab; Decoration::Renderer *m_decorationRenderer; double m_opacity; NET::WindowType m_type = NET::Unknown; diff --git a/libkwineffects/kwineffects.cpp b/libkwineffects/kwineffects.cpp index 206afa314f..b1d8f5dc88 100644 --- a/libkwineffects/kwineffects.cpp +++ b/libkwineffects/kwineffects.cpp @@ -837,7 +837,7 @@ WINDOW_HELPER_DEFAULT(bool, isSpecialWindow, "specialWindow", true) WINDOW_HELPER_DEFAULT(bool, acceptsFocus, "wantsInput", true) // We don't actually know... WINDOW_HELPER_DEFAULT(QIcon, icon, "icon", QIcon()) WINDOW_HELPER_DEFAULT(bool, isSkipSwitcher, "skipSwitcher", false) -WINDOW_HELPER_DEFAULT(bool, isCurrentTab, "isCurrentTab", false) +WINDOW_HELPER_DEFAULT(bool, isCurrentTab, "isCurrentTab", true) WINDOW_HELPER_DEFAULT(bool, decorationHasAlpha, "decorationHasAlpha", false) WINDOW_HELPER_DEFAULT(bool, isFullScreen, "fullScreen", false) From dc8c33e856be8bcdec4e9423c60a85931ec100d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Mon, 23 May 2016 08:54:28 +0200 Subject: [PATCH 2/5] Destroy ShellClient when the SurfaceInterface gets destroyed KWayland was changed: the ShellSurfaceInterface does no longer get destroyed when the parent SurfaceInterface gets destroyed. For the wl_shell_surface there is no dtor request in the interface so the resource sticks around and also the ShellClient is kept. This change ensures that the ShellClient also gets destroyed when the Surface is destroyed. This should fix some broken tests. Cherry-picked from master to fix failing tests on build.kde.org. --- shell_client.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/shell_client.cpp b/shell_client.cpp index fed1d88c23..95be7711d8 100644 --- a/shell_client.cpp +++ b/shell_client.cpp @@ -89,6 +89,7 @@ ShellClient::ShellClient(ShellSurfaceInterface *surface) ); connect(surface, &ShellSurfaceInterface::destroyed, this, &ShellClient::destroyClient); connect(surface->surface(), &SurfaceInterface::unmapped, this, &ShellClient::unmap); + connect(surface->surface(), &SurfaceInterface::destroyed, this, &ShellClient::destroyClient); connect(surface, &ShellSurfaceInterface::titleChanged, this, &ShellClient::captionChanged); connect(surface, &ShellSurfaceInterface::fullscreenChanged, this, &ShellClient::clientFullScreenChanged); From 65d707d24cf8da094096808402f600cc0d372379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Mon, 23 May 2016 09:28:27 +0200 Subject: [PATCH 3/5] [decorations] Don't recreate Renderer once the Compositor is destroyed If we get a compositingToggled because the Compositor is going down we don't need to recreate the Renderer as KWin as a whole is going down. Thus we disconnect the compositingToggled connection when the Compositor is about to be destroyed. --- decorations/decoratedclient.cpp | 8 +++++++- decorations/decoratedclient.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/decorations/decoratedclient.cpp b/decorations/decoratedclient.cpp index 242cec1b80..79ebc1b429 100644 --- a/decorations/decoratedclient.cpp +++ b/decorations/decoratedclient.cpp @@ -75,7 +75,7 @@ DecoratedClientImpl::DecoratedClientImpl(AbstractClient *client, KDecoration2::D &Decoration::DecoratedClientImpl::signalShadeChange); connect(client, &AbstractClient::keepAboveChanged, decoratedClient, &KDecoration2::DecoratedClient::keepAboveChanged); connect(client, &AbstractClient::keepBelowChanged, decoratedClient, &KDecoration2::DecoratedClient::keepBelowChanged); - connect(Compositor::self(), &Compositor::compositingToggled, this, + m_compositorToggledConnection = connect(Compositor::self(), &Compositor::compositingToggled, this, [this, decoration]() { delete m_renderer; m_renderer = nullptr; @@ -83,6 +83,12 @@ DecoratedClientImpl::DecoratedClientImpl(AbstractClient *client, KDecoration2::D decoration->update(); } ); + connect(Compositor::self(), &Compositor::aboutToDestroy, this, + [this] { + disconnect(m_compositorToggledConnection); + m_compositorToggledConnection = QMetaObject::Connection(); + } + ); connect(client, &AbstractClient::quickTileModeChanged, decoratedClient, [this, decoratedClient]() { emit decoratedClient->adjacentScreenEdgesChanged(adjacentScreenEdges()); diff --git a/decorations/decoratedclient.h b/decorations/decoratedclient.h index 2247076375..c51a27fff7 100644 --- a/decorations/decoratedclient.h +++ b/decorations/decoratedclient.h @@ -99,6 +99,7 @@ private: void createRenderer(); AbstractClient *m_client; Renderer *m_renderer; + QMetaObject::Connection m_compositorToggledConnection; }; } From 54d770d5ca22f4ed75084d2bfb63395b6d83cd63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Mon, 23 May 2016 10:01:31 +0200 Subject: [PATCH 4/5] Destroy decoration when DecorationBridge is destroyed When KWin goes down the DecorationBridge might be destroyed before the last AbstractClient is destroyed. Thus we should destroy the Decoration when the DecorationBridge gets destroyed. --- abstract_client.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/abstract_client.cpp b/abstract_client.cpp index b3230300cf..ab40c7b509 100644 --- a/abstract_client.cpp +++ b/abstract_client.cpp @@ -20,6 +20,7 @@ along with this program. If not, see . #include "abstract_client.h" #include "decorations/decoratedclient.h" #include "decorations/decorationpalette.h" +#include "decorations/decorationbridge.h" #include "cursor.h" #include "effects.h" #include "focuschain.h" @@ -64,6 +65,8 @@ AbstractClient::AbstractClient() connect(this, &AbstractClient::clientFinishUserMovedResized, this, &AbstractClient::setupCheckScreenConnection); connect(this, &AbstractClient::paletteChanged, this, &AbstractClient::triggerDecorationRepaint); + + connect(Decoration::DecorationBridge::self(), &QObject::destroyed, this, &AbstractClient::destroyDecoration); } AbstractClient::~AbstractClient() From ee785db147f7763b36c99bb79487f3672aea382b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Mon, 23 May 2016 11:19:29 +0200 Subject: [PATCH 5/5] [autotests/wayland] Try to make PointerInputTest::testMouseActionActiveWindow more robust It's currently failing on build.kde.org. I'm not able to reproduce the failure localy so I can only interpret the failure. The failure looks like a window is still present in the next executed test case thus breaking the positioning. This change ensures that the window is properly gone before going into the next test case. --- autotests/wayland/pointer_input.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/autotests/wayland/pointer_input.cpp b/autotests/wayland/pointer_input.cpp index 075fa477fa..95c41e0632 100644 --- a/autotests/wayland/pointer_input.cpp +++ b/autotests/wayland/pointer_input.cpp @@ -740,6 +740,8 @@ void PointerInputTest::testMouseActionActiveWindow() QVERIFY(clientAddedSpy.wait()); AbstractClient *window1 = workspace()->activeClient(); QVERIFY(window1); + QSignalSpy window1DestroyedSpy(window1, &QObject::destroyed); + QVERIFY(window1DestroyedSpy.isValid()); Surface *surface2 = m_compositor->createSurface(m_compositor); QVERIFY(surface2); ShellSurface *shellSurface2 = m_shell->createSurface(surface2, surface2); @@ -749,6 +751,8 @@ void PointerInputTest::testMouseActionActiveWindow() AbstractClient *window2 = workspace()->activeClient(); QVERIFY(window2); QVERIFY(window1 != window2); + QSignalSpy window2DestroyedSpy(window2, &QObject::destroyed); + QVERIFY(window2DestroyedSpy.isValid()); QCOMPARE(workspace()->topClientOnDesktop(1, -1), window2); // geometry of the two windows should be overlapping QVERIFY(window1->geometry().intersects(window2->geometry())); @@ -781,6 +785,11 @@ void PointerInputTest::testMouseActionActiveWindow() // release again waylandServer()->backend()->pointerButtonReleased(button, timestamp++); + + delete surface1; + QVERIFY(window1DestroyedSpy.wait()); + delete surface2; + QVERIFY(window2DestroyedSpy.wait()); } void PointerInputTest::testCursorImage()