Properly clean up screens during reconnect

Otherwise the old screens are left dangling. Also create a placeholder
screen so the windows get assigned a valid screen upon reconnect.

Change-Id: Iea5d1da6f32be5e87464412447ae1449d91d8e75
Reviewed-by: David Edmundson <davidedmundson@kde.org>
This commit is contained in:
David Redondo 2023-04-27 15:22:26 +02:00
parent f2344f7d71
commit 117f8dedcc
2 changed files with 31 additions and 3 deletions

View File

@ -420,6 +420,12 @@ void QWaylandDisplay::reconnect()
qDeleteAll(mWaitingScreens); qDeleteAll(mWaitingScreens);
mWaitingScreens.clear(); mWaitingScreens.clear();
const auto screens = std::exchange(mScreens, {});
ensureScreen();
for (QWaylandScreen *screen : screens) {
QWindowSystemInterface::handleScreenRemoved(screen);
}
// mCompositor // mCompositor
mShm.reset(); mShm.reset();
mCursorThemes.clear(); mCursorThemes.clear();
@ -449,9 +455,6 @@ void QWaylandDisplay::reconnect()
qDeleteAll(std::exchange(mInputDevices, {})); qDeleteAll(std::exchange(mInputDevices, {}));
mLastInputDevice = nullptr; mLastInputDevice = nullptr;
auto screens = mScreens;
mScreens.clear();
for (const RegistryGlobal &global : mGlobals) { for (const RegistryGlobal &global : mGlobals) {
emit globalRemoved(global); emit globalRemoved(global);
} }

View File

@ -101,6 +101,7 @@ private Q_SLOTS:
//core //core
void cleanup() { QTRY_VERIFY2(m_comp->isClean(), qPrintable(m_comp->dirtyMessage())); } void cleanup() { QTRY_VERIFY2(m_comp->isClean(), qPrintable(m_comp->dirtyMessage())); }
void basicWindow(); void basicWindow();
void screens();
//input //input
void keyFocus(); void keyFocus();
@ -141,6 +142,30 @@ void tst_WaylandReconnect::basicWindow()
QCOMPOSITOR_TRY_VERIFY(m_comp->xdgToplevel()); QCOMPOSITOR_TRY_VERIFY(m_comp->xdgToplevel());
} }
void tst_WaylandReconnect::screens()
{
QRasterWindow window;
window.resize(64, 48);
window.show();
QCOMPOSITOR_TRY_VERIFY(m_comp->xdgToplevel());
auto originalScreens = QGuiApplication::screens();
QSignalSpy screenRemovedSpy(qGuiApp, &QGuiApplication::screenRemoved);
QVERIFY(screenRemovedSpy.isValid());
triggerReconnect();
// All screens plus temporary placeholder screen removed
QCOMPARE(screenRemovedSpy.count(), originalScreens.count() + 1);
for (const auto &screen : std::as_const(screenRemovedSpy)) {
originalScreens.removeOne(screen[0].value<QScreen *>());
}
QVERIFY(originalScreens.isEmpty());
QVERIFY(window.screen());
QVERIFY(QGuiApplication::screens().contains(window.screen()));
}
void tst_WaylandReconnect::keyFocus() void tst_WaylandReconnect::keyFocus()
{ {
TestWindow window; TestWindow window;