File: 0066-client-Force-a-roundtrip-when-an-XdgOutput-is-not-re.patch

package info (click to toggle)
qtwayland-opensource-src 5.15.17-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 11,108 kB
  • sloc: cpp: 53,691; xml: 9,462; ansic: 187; makefile: 29; sh: 5
file content (105 lines) | stat: -rw-r--r-- 3,915 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
From 6897f62f603df049135347cf402a7a4037092263 Mon Sep 17 00:00:00 2001
From: Marco Martin <notmart@gmail.com>
Date: Fri, 24 Feb 2023 17:40:48 +0100
Subject: [PATCH] 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 <davidedmundson@kde.org>
---
 src/client/qwaylandwindow.cpp                 |  2 ++
 tests/auto/client/shared/coreprotocol.cpp     |  2 ++
 tests/auto/client/shared/coreprotocol.h       |  3 ++
 tests/auto/client/xdgoutput/tst_xdgoutput.cpp | 35 +++++++++++++++++++
 4 files changed, 42 insertions(+)

--- a/src/client/qwaylandwindow.cpp
+++ b/src/client/qwaylandwindow.cpp
@@ -1042,6 +1042,8 @@ void QWaylandWindow::handleScreensChanged()
     if (newScreen == mLastReportedScreen)
         return;
 
+    if (!newScreen->isPlaceholder() && !newScreen->QPlatformScreen::screen())
+        mDisplay->forceRoundTrip();
     QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen());
     mLastReportedScreen = newScreen;
     if (fixedToplevelPositions && !QPlatformWindow::parent() && window()->type() != Qt::Popup
--- a/tests/auto/client/shared/coreprotocol.cpp
+++ b/tests/auto/client/shared/coreprotocol.cpp
@@ -185,6 +185,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
--- a/tests/auto/client/shared/coreprotocol.h
+++ b/tests/auto/client/shared/coreprotocol.h
@@ -273,6 +273,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;
 };
--- a/tests/auto/client/xdgoutput/tst_xdgoutput.cpp
+++ b/tests/auto/client/xdgoutput/tst_xdgoutput.cpp
@@ -55,6 +55,7 @@ private slots:
     void primaryScreen();
     void overrideGeometry();
     void changeGeometry();
+    void outputCreateEnterRace();
 };
 
 void tst_xdgoutput::cleanup()
@@ -134,5 +135,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<Output>();
+     });
+
+     // 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"