From 9858708993906f7a449c127b6c1f24ccae7ed453 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Fri, 24 Feb 2023 17:40:48 +0100 Subject: client: Force a roundtrip when an XdgOutput is not ready yet Is possible that the server sends a surface_enter before all the information of the XdgOutput have been processed by the client. in this case the associated QScreen doesn't exist yet, causing a QWindow::SetScreen(nullptr), which will fall back to QGuiApplication::primaryScreen(), having the QWindow being assigned the wrong screen Change-Id: I923d5d3a35484deafa6f0572f79c16c27b1f87f0 Reviewed-by: David Edmundson --- tests/auto/client/shared/coreprotocol.cpp | 2 ++ tests/auto/client/shared/coreprotocol.h | 3 +++ tests/auto/client/xdgoutput/tst_xdgoutput.cpp | 35 +++++++++++++++++++++++++++ 3 files changed, 40 insertions(+) (limited to 'tests/auto') diff --git a/tests/auto/client/shared/coreprotocol.cpp b/tests/auto/client/shared/coreprotocol.cpp index 4f3d21d8e..8e64adada 100644 --- a/tests/auto/client/shared/coreprotocol.cpp +++ b/tests/auto/client/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/client/shared/coreprotocol.h b/tests/auto/client/shared/coreprotocol.h index 74f07afbf..8703fe1d3 100644 --- a/tests/auto/client/shared/coreprotocol.h +++ b/tests/auto/client/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/client/xdgoutput/tst_xdgoutput.cpp b/tests/auto/client/xdgoutput/tst_xdgoutput.cpp index b1dcde43e..ea8719f13 100644 --- a/tests/auto/client/xdgoutput/tst_xdgoutput.cpp +++ b/tests/auto/client/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" -- cgit v1.2.3