[client] Ensure PlasmaWindowManagement updates active window if it goes away
Summary: So far when the active PlasmaWindow got unmapped or destroyed, the PlasmaWindowManagement didn't update the activeWindow. This means it could expose a deleted object through it's API which could result in a crash. This change addresses the problem by updating the active window when a window gets unmapped or destroyed. Test Plan: Tests added which exposed the problem Reviewers: #plasma, hein Subscribers: plasma-devel Tags: #plasma Differential Revision: https://phabricator.kde.org/D1621
This commit is contained in:
parent
372955bf05
commit
2c5bc69d1d
1 changed files with 51 additions and 0 deletions
|
@ -46,6 +46,8 @@ private Q_SLOTS:
|
||||||
void testMinimizedGeometry();
|
void testMinimizedGeometry();
|
||||||
void testUseAfterUnmap();
|
void testUseAfterUnmap();
|
||||||
void testServerDelete();
|
void testServerDelete();
|
||||||
|
void testActiveWindowOnUnmapped();
|
||||||
|
void testDeleteActiveWindow();
|
||||||
|
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
|
@ -258,5 +260,54 @@ void TestWindowManagement::testServerDelete()
|
||||||
m_window = nullptr;
|
m_window = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestWindowManagement::testActiveWindowOnUnmapped()
|
||||||
|
{
|
||||||
|
// This test verifies that unmapping the active window changes the active window.
|
||||||
|
// first make the window active
|
||||||
|
QVERIFY(!m_windowManagement->activeWindow());
|
||||||
|
QVERIFY(!m_window->isActive());
|
||||||
|
QSignalSpy activeWindowChangedSpy(m_windowManagement, &KWayland::Client::PlasmaWindowManagement::activeWindowChanged);
|
||||||
|
QVERIFY(activeWindowChangedSpy.isValid());
|
||||||
|
m_windowInterface->setActive(true);
|
||||||
|
QVERIFY(activeWindowChangedSpy.wait());
|
||||||
|
QCOMPARE(m_windowManagement->activeWindow(), m_window);
|
||||||
|
QVERIFY(m_window->isActive());
|
||||||
|
|
||||||
|
// now unmap should change the active window
|
||||||
|
QSignalSpy destroyedSpy(m_window, &QObject::destroyed);
|
||||||
|
QVERIFY(destroyedSpy.isValid());
|
||||||
|
QSignalSpy serverDestroyedSpy(m_windowInterface, &QObject::destroyed);
|
||||||
|
QVERIFY(serverDestroyedSpy.isValid());
|
||||||
|
m_windowManagementInterface->unmapWindow(m_windowInterface);
|
||||||
|
QVERIFY(activeWindowChangedSpy.wait());
|
||||||
|
QVERIFY(!m_windowManagement->activeWindow());
|
||||||
|
QVERIFY(destroyedSpy.wait());
|
||||||
|
QCOMPARE(destroyedSpy.count(), 1);
|
||||||
|
m_window = nullptr;
|
||||||
|
QVERIFY(serverDestroyedSpy.wait());
|
||||||
|
m_windowInterface = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestWindowManagement::testDeleteActiveWindow()
|
||||||
|
{
|
||||||
|
// This test verifies that deleting the active window on client side changes the active window
|
||||||
|
// first make the window active
|
||||||
|
QVERIFY(!m_windowManagement->activeWindow());
|
||||||
|
QVERIFY(!m_window->isActive());
|
||||||
|
QSignalSpy activeWindowChangedSpy(m_windowManagement, &KWayland::Client::PlasmaWindowManagement::activeWindowChanged);
|
||||||
|
QVERIFY(activeWindowChangedSpy.isValid());
|
||||||
|
m_windowInterface->setActive(true);
|
||||||
|
QVERIFY(activeWindowChangedSpy.wait());
|
||||||
|
QCOMPARE(activeWindowChangedSpy.count(), 1);
|
||||||
|
QCOMPARE(m_windowManagement->activeWindow(), m_window);
|
||||||
|
QVERIFY(m_window->isActive());
|
||||||
|
|
||||||
|
// delete the client side window - that's semantically kind of wrong, but shouldn't make our code crash
|
||||||
|
delete m_window;
|
||||||
|
m_window = nullptr;
|
||||||
|
QCOMPARE(activeWindowChangedSpy.count(), 2);
|
||||||
|
QVERIFY(!m_windowManagement->activeWindow());
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(TestWindowManagement)
|
QTEST_GUILESS_MAIN(TestWindowManagement)
|
||||||
#include "test_wayland_windowmanagement.moc"
|
#include "test_wayland_windowmanagement.moc"
|
||||||
|
|
Loading…
Reference in a new issue