diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index a109126d4f7..954d6df315b 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -1306,6 +1306,8 @@ void QWaylandWindow::handleScreensChanged() if (newScreen == mLastReportedScreen) return; + if (!newScreen->isPlaceholder() && !newScreen->QPlatformScreen::screen()) + mDisplay->forceRoundTrip(); QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen()); mLastReportedScreen = newScreen; diff --git a/tests/auto/wayland/shared/coreprotocol.cpp b/tests/auto/wayland/shared/coreprotocol.cpp index 4f3d21d8eb9..8e64adadae3 100644 --- a/tests/auto/wayland/shared/coreprotocol.cpp +++ b/tests/auto/wayland/shared/coreprotocol.cpp @@ -226,6 +226,8 @@ void Output::output_bind_resource(QtWaylandServer::wl_output::Resource *resource if (m_version >= WL_OUTPUT_DONE_SINCE_VERSION) wl_output::send_done(resource->handle); + + Q_EMIT outputBound(resource); } // Seat stuff diff --git a/tests/auto/wayland/shared/coreprotocol.h b/tests/auto/wayland/shared/coreprotocol.h index 74f07afbf44..8703fe1d308 100644 --- a/tests/auto/wayland/shared/coreprotocol.h +++ b/tests/auto/wayland/shared/coreprotocol.h @@ -288,6 +288,9 @@ public: OutputData m_data; int m_version = 1; // TODO: remove on libwayland upgrade +Q_SIGNALS: + void outputBound(Resource *resource); + protected: void output_bind_resource(Resource *resource) override; }; diff --git a/tests/auto/wayland/xdgoutput/tst_xdgoutput.cpp b/tests/auto/wayland/xdgoutput/tst_xdgoutput.cpp index b1dcde43e61..ea8719f13d3 100644 --- a/tests/auto/wayland/xdgoutput/tst_xdgoutput.cpp +++ b/tests/auto/wayland/xdgoutput/tst_xdgoutput.cpp @@ -30,6 +30,7 @@ private slots: void primaryScreen(); void overrideGeometry(); void changeGeometry(); + void outputCreateEnterRace(); }; void tst_xdgoutput::cleanup() @@ -109,5 +110,39 @@ void tst_xdgoutput::changeGeometry() exec([=] { remove(output(1)); }); } +void tst_xdgoutput::outputCreateEnterRace() +{ + m_config.autoConfigure = true; + m_config.autoEnter = false; + QRasterWindow window; + QSignalSpy screenChanged(&window, &QWindow::screenChanged); + window.resize(400, 320); + window.show(); + QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial); + exec([=] { xdgToplevel()->surface()->sendEnter(output(0));}); + + QTRY_COMPARE(QGuiApplication::screens().size(), 1); + QScreen *primaryScreen = QGuiApplication::screens().first(); + QCOMPARE(window.screen(), primaryScreen); + + auto *out = exec([=] { + return add(); + }); + + // In Compositor Thread + connect(out, &Output::outputBound, this, [this](QtWaylandServer::wl_output::Resource *resource){ + auto surface = xdgToplevel()->surface(); + surface->sendLeave(output(0)); + surface->QtWaylandServer::wl_surface::send_enter(surface->resource()->handle, resource->handle); + }, Qt::DirectConnection); + + QTRY_COMPARE(QGuiApplication::screens().size(), 2); + QTRY_COMPARE(window.screen(), QGuiApplication::screens()[1]); + + exec([=] { remove(out); }); + m_config.autoConfigure = false; + m_config.autoEnter = true; +} + QCOMPOSITOR_TEST_MAIN(tst_xdgoutput) #include "tst_xdgoutput.moc"