Changeset View
Changeset View
Standalone View
Standalone View
autotests/integration/stacking_order_test.cpp
Show First 20 Lines • Show All 102 Lines • ▼ Show 20 Line(s) | 102 | KWayland::Client::XdgShellSurface *parentShellSurface = | |||
---|---|---|---|---|---|
103 | Test::createXdgShellStableSurface(parentSurface, parentSurface); | 103 | Test::createXdgShellStableSurface(parentSurface, parentSurface); | ||
104 | QVERIFY(parentShellSurface); | 104 | QVERIFY(parentShellSurface); | ||
105 | XdgShellClient *parent = Test::renderAndWaitForShown(parentSurface, QSize(256, 256), Qt::blue); | 105 | XdgShellClient *parent = Test::renderAndWaitForShown(parentSurface, QSize(256, 256), Qt::blue); | ||
106 | QVERIFY(parent); | 106 | QVERIFY(parent); | ||
107 | QVERIFY(parent->isActive()); | 107 | QVERIFY(parent->isActive()); | ||
108 | QVERIFY(!parent->isTransient()); | 108 | QVERIFY(!parent->isTransient()); | ||
109 | 109 | | |||
110 | // Initially, the stacking order should contain only the parent window. | 110 | // Initially, the stacking order should contain only the parent window. | ||
111 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{parent})); | 111 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{parent})); | ||
112 | 112 | | |||
113 | // Create the transient. | 113 | // Create the transient. | ||
114 | KWayland::Client::Surface *transientSurface = | 114 | KWayland::Client::Surface *transientSurface = | ||
115 | Test::createSurface(Test::waylandCompositor()); | 115 | Test::createSurface(Test::waylandCompositor()); | ||
116 | QVERIFY(transientSurface); | 116 | QVERIFY(transientSurface); | ||
117 | KWayland::Client::XdgShellSurface *transientShellSurface = | 117 | KWayland::Client::XdgShellSurface *transientShellSurface = | ||
118 | Test::createXdgShellStableSurface(transientSurface, transientSurface); | 118 | Test::createXdgShellStableSurface(transientSurface, transientSurface); | ||
119 | QVERIFY(transientShellSurface); | 119 | QVERIFY(transientShellSurface); | ||
120 | transientShellSurface->setTransientFor(parentShellSurface); | 120 | transientShellSurface->setTransientFor(parentShellSurface); | ||
121 | XdgShellClient *transient = Test::renderAndWaitForShown( | 121 | XdgShellClient *transient = Test::renderAndWaitForShown( | ||
122 | transientSurface, QSize(128, 128), Qt::red); | 122 | transientSurface, QSize(128, 128), Qt::red); | ||
123 | QVERIFY(transient); | 123 | QVERIFY(transient); | ||
124 | QVERIFY(transient->isActive()); | 124 | QVERIFY(transient->isActive()); | ||
125 | QVERIFY(transient->isTransient()); | 125 | QVERIFY(transient->isTransient()); | ||
126 | 126 | | |||
127 | // The transient should be above the parent. | 127 | // The transient should be above the parent. | ||
128 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{parent, transient})); | 128 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{parent, transient})); | ||
129 | 129 | | |||
130 | // The transient still stays above the parent if we activate the latter. | 130 | // The transient still stays above the parent if we activate the latter. | ||
131 | workspace()->activateClient(parent); | 131 | workspace()->activateClient(parent); | ||
132 | QTRY_VERIFY(parent->isActive()); | 132 | QTRY_VERIFY(parent->isActive()); | ||
133 | QTRY_VERIFY(!transient->isActive()); | 133 | QTRY_VERIFY(!transient->isActive()); | ||
134 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{parent, transient})); | 134 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{parent, transient})); | ||
135 | } | 135 | } | ||
136 | 136 | | |||
137 | void StackingOrderTest::testRaiseTransient() | 137 | void StackingOrderTest::testRaiseTransient() | ||
138 | { | 138 | { | ||
139 | // This test verifies that both the parent and the transient will be | 139 | // This test verifies that both the parent and the transient will be | ||
140 | // raised if either one of them is activated. | 140 | // raised if either one of them is activated. | ||
141 | 141 | | |||
142 | // Create the parent. | 142 | // Create the parent. | ||
143 | KWayland::Client::Surface *parentSurface = | 143 | KWayland::Client::Surface *parentSurface = | ||
144 | Test::createSurface(Test::waylandCompositor()); | 144 | Test::createSurface(Test::waylandCompositor()); | ||
145 | QVERIFY(parentSurface); | 145 | QVERIFY(parentSurface); | ||
146 | KWayland::Client::XdgShellSurface *parentShellSurface = | 146 | KWayland::Client::XdgShellSurface *parentShellSurface = | ||
147 | Test::createXdgShellStableSurface(parentSurface, parentSurface); | 147 | Test::createXdgShellStableSurface(parentSurface, parentSurface); | ||
148 | QVERIFY(parentShellSurface); | 148 | QVERIFY(parentShellSurface); | ||
149 | XdgShellClient *parent = Test::renderAndWaitForShown(parentSurface, QSize(256, 256), Qt::blue); | 149 | XdgShellClient *parent = Test::renderAndWaitForShown(parentSurface, QSize(256, 256), Qt::blue); | ||
150 | QVERIFY(parent); | 150 | QVERIFY(parent); | ||
151 | QVERIFY(parent->isActive()); | 151 | QVERIFY(parent->isActive()); | ||
152 | QVERIFY(!parent->isTransient()); | 152 | QVERIFY(!parent->isTransient()); | ||
153 | 153 | | |||
154 | // Initially, the stacking order should contain only the parent window. | 154 | // Initially, the stacking order should contain only the parent window. | ||
155 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{parent})); | 155 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{parent})); | ||
156 | 156 | | |||
157 | // Create the transient. | 157 | // Create the transient. | ||
158 | KWayland::Client::Surface *transientSurface = | 158 | KWayland::Client::Surface *transientSurface = | ||
159 | Test::createSurface(Test::waylandCompositor()); | 159 | Test::createSurface(Test::waylandCompositor()); | ||
160 | QVERIFY(transientSurface); | 160 | QVERIFY(transientSurface); | ||
161 | KWayland::Client::XdgShellSurface *transientShellSurface = | 161 | KWayland::Client::XdgShellSurface *transientShellSurface = | ||
162 | Test::createXdgShellStableSurface(transientSurface, transientSurface); | 162 | Test::createXdgShellStableSurface(transientSurface, transientSurface); | ||
163 | QVERIFY(transientShellSurface); | 163 | QVERIFY(transientShellSurface); | ||
164 | transientShellSurface->setTransientFor(parentShellSurface); | 164 | transientShellSurface->setTransientFor(parentShellSurface); | ||
165 | XdgShellClient *transient = Test::renderAndWaitForShown( | 165 | XdgShellClient *transient = Test::renderAndWaitForShown( | ||
166 | transientSurface, QSize(128, 128), Qt::red); | 166 | transientSurface, QSize(128, 128), Qt::red); | ||
167 | QVERIFY(transient); | 167 | QVERIFY(transient); | ||
168 | QTRY_VERIFY(transient->isActive()); | 168 | QTRY_VERIFY(transient->isActive()); | ||
169 | QVERIFY(transient->isTransient()); | 169 | QVERIFY(transient->isTransient()); | ||
170 | 170 | | |||
171 | // The transient should be above the parent. | 171 | // The transient should be above the parent. | ||
172 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{parent, transient})); | 172 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{parent, transient})); | ||
173 | 173 | | |||
174 | // Create a window that doesn't have any relationship to the parent or the transient. | 174 | // Create a window that doesn't have any relationship to the parent or the transient. | ||
175 | KWayland::Client::Surface *anotherSurface = | 175 | KWayland::Client::Surface *anotherSurface = | ||
176 | Test::createSurface(Test::waylandCompositor()); | 176 | Test::createSurface(Test::waylandCompositor()); | ||
177 | QVERIFY(anotherSurface); | 177 | QVERIFY(anotherSurface); | ||
178 | KWayland::Client::XdgShellSurface *anotherShellSurface = | 178 | KWayland::Client::XdgShellSurface *anotherShellSurface = | ||
179 | Test::createXdgShellStableSurface(anotherSurface, anotherSurface); | 179 | Test::createXdgShellStableSurface(anotherSurface, anotherSurface); | ||
180 | QVERIFY(anotherShellSurface); | 180 | QVERIFY(anotherShellSurface); | ||
181 | XdgShellClient *anotherClient = Test::renderAndWaitForShown(anotherSurface, QSize(128, 128), Qt::green); | 181 | XdgShellClient *anotherClient = Test::renderAndWaitForShown(anotherSurface, QSize(128, 128), Qt::green); | ||
182 | QVERIFY(anotherClient); | 182 | QVERIFY(anotherClient); | ||
183 | QVERIFY(anotherClient->isActive()); | 183 | QVERIFY(anotherClient->isActive()); | ||
184 | QVERIFY(!anotherClient->isTransient()); | 184 | QVERIFY(!anotherClient->isTransient()); | ||
185 | 185 | | |||
186 | // The newly created surface has to be above both the parent and the transient. | 186 | // The newly created surface has to be above both the parent and the transient. | ||
187 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{parent, transient, anotherClient})); | 187 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{parent, transient, anotherClient})); | ||
188 | 188 | | |||
189 | // If we activate the parent, the transient should be raised too. | 189 | // If we activate the parent, the transient should be raised too. | ||
190 | workspace()->activateClient(parent); | 190 | workspace()->activateClient(parent); | ||
191 | QTRY_VERIFY(parent->isActive()); | 191 | QTRY_VERIFY(parent->isActive()); | ||
192 | QTRY_VERIFY(!transient->isActive()); | 192 | QTRY_VERIFY(!transient->isActive()); | ||
193 | QTRY_VERIFY(!anotherClient->isActive()); | 193 | QTRY_VERIFY(!anotherClient->isActive()); | ||
194 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{anotherClient, parent, transient})); | 194 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{anotherClient, parent, transient})); | ||
195 | 195 | | |||
196 | // Go back to the initial setup. | 196 | // Go back to the initial setup. | ||
197 | workspace()->activateClient(anotherClient); | 197 | workspace()->activateClient(anotherClient); | ||
198 | QTRY_VERIFY(!parent->isActive()); | 198 | QTRY_VERIFY(!parent->isActive()); | ||
199 | QTRY_VERIFY(!transient->isActive()); | 199 | QTRY_VERIFY(!transient->isActive()); | ||
200 | QTRY_VERIFY(anotherClient->isActive()); | 200 | QTRY_VERIFY(anotherClient->isActive()); | ||
201 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{parent, transient, anotherClient})); | 201 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{parent, transient, anotherClient})); | ||
202 | 202 | | |||
203 | // If we activate the transient, the parent should be raised too. | 203 | // If we activate the transient, the parent should be raised too. | ||
204 | workspace()->activateClient(transient); | 204 | workspace()->activateClient(transient); | ||
205 | QTRY_VERIFY(!parent->isActive()); | 205 | QTRY_VERIFY(!parent->isActive()); | ||
206 | QTRY_VERIFY(transient->isActive()); | 206 | QTRY_VERIFY(transient->isActive()); | ||
207 | QTRY_VERIFY(!anotherClient->isActive()); | 207 | QTRY_VERIFY(!anotherClient->isActive()); | ||
208 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{anotherClient, parent, transient})); | 208 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{anotherClient, parent, transient})); | ||
209 | } | 209 | } | ||
210 | 210 | | |||
211 | struct WindowUnrefDeleter | 211 | struct WindowUnrefDeleter | ||
212 | { | 212 | { | ||
213 | static inline void cleanup(Deleted *d) { | 213 | static inline void cleanup(Deleted *d) { | ||
214 | if (d != nullptr) { | 214 | if (d != nullptr) { | ||
215 | d->unrefWindow(); | 215 | d->unrefWindow(); | ||
216 | } | 216 | } | ||
Show All 12 Lines | 221 | { | |||
229 | KWayland::Client::XdgShellSurface *parentShellSurface = | 229 | KWayland::Client::XdgShellSurface *parentShellSurface = | ||
230 | Test::createXdgShellStableSurface(parentSurface, parentSurface); | 230 | Test::createXdgShellStableSurface(parentSurface, parentSurface); | ||
231 | QVERIFY(parentShellSurface); | 231 | QVERIFY(parentShellSurface); | ||
232 | XdgShellClient *parent = Test::renderAndWaitForShown(parentSurface, QSize(256, 256), Qt::blue); | 232 | XdgShellClient *parent = Test::renderAndWaitForShown(parentSurface, QSize(256, 256), Qt::blue); | ||
233 | QVERIFY(parent); | 233 | QVERIFY(parent); | ||
234 | QVERIFY(parent->isActive()); | 234 | QVERIFY(parent->isActive()); | ||
235 | QVERIFY(!parent->isTransient()); | 235 | QVERIFY(!parent->isTransient()); | ||
236 | 236 | | |||
237 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{parent})); | 237 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{parent})); | ||
238 | 238 | | |||
239 | // Create the first transient. | 239 | // Create the first transient. | ||
240 | KWayland::Client::Surface *transient1Surface = | 240 | KWayland::Client::Surface *transient1Surface = | ||
241 | Test::createSurface(Test::waylandCompositor()); | 241 | Test::createSurface(Test::waylandCompositor()); | ||
242 | QVERIFY(transient1Surface); | 242 | QVERIFY(transient1Surface); | ||
243 | KWayland::Client::XdgShellSurface *transient1ShellSurface = | 243 | KWayland::Client::XdgShellSurface *transient1ShellSurface = | ||
244 | Test::createXdgShellStableSurface(transient1Surface, transient1Surface); | 244 | Test::createXdgShellStableSurface(transient1Surface, transient1Surface); | ||
245 | QVERIFY(transient1ShellSurface); | 245 | QVERIFY(transient1ShellSurface); | ||
246 | transient1ShellSurface->setTransientFor(parentShellSurface); | 246 | transient1ShellSurface->setTransientFor(parentShellSurface); | ||
247 | XdgShellClient *transient1 = Test::renderAndWaitForShown( | 247 | XdgShellClient *transient1 = Test::renderAndWaitForShown( | ||
248 | transient1Surface, QSize(128, 128), Qt::red); | 248 | transient1Surface, QSize(128, 128), Qt::red); | ||
249 | QVERIFY(transient1); | 249 | QVERIFY(transient1); | ||
250 | QTRY_VERIFY(transient1->isActive()); | 250 | QTRY_VERIFY(transient1->isActive()); | ||
251 | QVERIFY(transient1->isTransient()); | 251 | QVERIFY(transient1->isTransient()); | ||
252 | QCOMPARE(transient1->transientFor(), parent); | 252 | QCOMPARE(transient1->transientFor(), parent); | ||
253 | 253 | | |||
254 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{parent, transient1})); | 254 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{parent, transient1})); | ||
255 | 255 | | |||
256 | // Create the second transient. | 256 | // Create the second transient. | ||
257 | KWayland::Client::Surface *transient2Surface = | 257 | KWayland::Client::Surface *transient2Surface = | ||
258 | Test::createSurface(Test::waylandCompositor()); | 258 | Test::createSurface(Test::waylandCompositor()); | ||
259 | QVERIFY(transient2Surface); | 259 | QVERIFY(transient2Surface); | ||
260 | KWayland::Client::XdgShellSurface *transient2ShellSurface = | 260 | KWayland::Client::XdgShellSurface *transient2ShellSurface = | ||
261 | Test::createXdgShellStableSurface(transient2Surface, transient2Surface); | 261 | Test::createXdgShellStableSurface(transient2Surface, transient2Surface); | ||
262 | QVERIFY(transient2ShellSurface); | 262 | QVERIFY(transient2ShellSurface); | ||
263 | transient2ShellSurface->setTransientFor(transient1ShellSurface); | 263 | transient2ShellSurface->setTransientFor(transient1ShellSurface); | ||
264 | XdgShellClient *transient2 = Test::renderAndWaitForShown( | 264 | XdgShellClient *transient2 = Test::renderAndWaitForShown( | ||
265 | transient2Surface, QSize(128, 128), Qt::red); | 265 | transient2Surface, QSize(128, 128), Qt::red); | ||
266 | QVERIFY(transient2); | 266 | QVERIFY(transient2); | ||
267 | QTRY_VERIFY(transient2->isActive()); | 267 | QTRY_VERIFY(transient2->isActive()); | ||
268 | QVERIFY(transient2->isTransient()); | 268 | QVERIFY(transient2->isTransient()); | ||
269 | QCOMPARE(transient2->transientFor(), transient1); | 269 | QCOMPARE(transient2->transientFor(), transient1); | ||
270 | 270 | | |||
271 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{parent, transient1, transient2})); | 271 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{parent, transient1, transient2})); | ||
272 | 272 | | |||
273 | // Activate the parent, both transients have to be above it. | 273 | // Activate the parent, both transients have to be above it. | ||
274 | workspace()->activateClient(parent); | 274 | workspace()->activateClient(parent); | ||
275 | QTRY_VERIFY(parent->isActive()); | 275 | QTRY_VERIFY(parent->isActive()); | ||
276 | QTRY_VERIFY(!transient1->isActive()); | 276 | QTRY_VERIFY(!transient1->isActive()); | ||
277 | QTRY_VERIFY(!transient2->isActive()); | 277 | QTRY_VERIFY(!transient2->isActive()); | ||
278 | 278 | | |||
279 | // Close the top-most transient. | 279 | // Close the top-most transient. | ||
Show All 12 Lines | |||||
292 | 292 | | |||
293 | QScopedPointer<Deleted, WindowUnrefDeleter> deletedTransient( | 293 | QScopedPointer<Deleted, WindowUnrefDeleter> deletedTransient( | ||
294 | windowClosedSpy.first().at(1).value<Deleted *>()); | 294 | windowClosedSpy.first().at(1).value<Deleted *>()); | ||
295 | QVERIFY(deletedTransient.data()); | 295 | QVERIFY(deletedTransient.data()); | ||
296 | 296 | | |||
297 | // The deleted transient still has to be above its old parent (transient1). | 297 | // The deleted transient still has to be above its old parent (transient1). | ||
298 | QTRY_VERIFY(parent->isActive()); | 298 | QTRY_VERIFY(parent->isActive()); | ||
299 | QTRY_VERIFY(!transient1->isActive()); | 299 | QTRY_VERIFY(!transient1->isActive()); | ||
300 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{parent, transient1, deletedTransient.data()})); | 300 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{parent, transient1, deletedTransient.data()})); | ||
301 | } | 301 | } | ||
302 | 302 | | |||
303 | static xcb_window_t createGroupWindow(xcb_connection_t *conn, | 303 | static xcb_window_t createGroupWindow(xcb_connection_t *conn, | ||
304 | const QRect &geometry, | 304 | const QRect &geometry, | ||
305 | xcb_window_t leaderWid = XCB_WINDOW_NONE) | 305 | xcb_window_t leaderWid = XCB_WINDOW_NONE) | ||
306 | { | 306 | { | ||
307 | xcb_window_t wid = xcb_generate_id(conn); | 307 | xcb_window_t wid = xcb_generate_id(conn); | ||
308 | xcb_create_window( | 308 | xcb_create_window( | ||
▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Line(s) | 355 | { | |||
371 | 371 | | |||
372 | QVERIFY(windowCreatedSpy.wait()); | 372 | QVERIFY(windowCreatedSpy.wait()); | ||
373 | X11Client *leader = windowCreatedSpy.first().first().value<X11Client *>(); | 373 | X11Client *leader = windowCreatedSpy.first().first().value<X11Client *>(); | ||
374 | QVERIFY(leader); | 374 | QVERIFY(leader); | ||
375 | QVERIFY(leader->isActive()); | 375 | QVERIFY(leader->isActive()); | ||
376 | QCOMPARE(leader->windowId(), leaderWid); | 376 | QCOMPARE(leader->windowId(), leaderWid); | ||
377 | QVERIFY(!leader->isTransient()); | 377 | QVERIFY(!leader->isTransient()); | ||
378 | 378 | | |||
379 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{leader})); | 379 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader})); | ||
380 | 380 | | |||
381 | // Create another group member. | 381 | // Create another group member. | ||
382 | windowCreatedSpy.clear(); | 382 | windowCreatedSpy.clear(); | ||
383 | xcb_window_t member1Wid = createGroupWindow(conn.data(), geometry, leaderWid); | 383 | xcb_window_t member1Wid = createGroupWindow(conn.data(), geometry, leaderWid); | ||
384 | xcb_map_window(conn.data(), member1Wid); | 384 | xcb_map_window(conn.data(), member1Wid); | ||
385 | xcb_flush(conn.data()); | 385 | xcb_flush(conn.data()); | ||
386 | 386 | | |||
387 | QVERIFY(windowCreatedSpy.wait()); | 387 | QVERIFY(windowCreatedSpy.wait()); | ||
388 | X11Client *member1 = windowCreatedSpy.first().first().value<X11Client *>(); | 388 | X11Client *member1 = windowCreatedSpy.first().first().value<X11Client *>(); | ||
389 | QVERIFY(member1); | 389 | QVERIFY(member1); | ||
390 | QVERIFY(member1->isActive()); | 390 | QVERIFY(member1->isActive()); | ||
391 | QCOMPARE(member1->windowId(), member1Wid); | 391 | QCOMPARE(member1->windowId(), member1Wid); | ||
392 | QCOMPARE(member1->group(), leader->group()); | 392 | QCOMPARE(member1->group(), leader->group()); | ||
393 | QVERIFY(!member1->isTransient()); | 393 | QVERIFY(!member1->isTransient()); | ||
394 | 394 | | |||
395 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{leader, member1})); | 395 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1})); | ||
396 | 396 | | |||
397 | // Create yet another group member. | 397 | // Create yet another group member. | ||
398 | windowCreatedSpy.clear(); | 398 | windowCreatedSpy.clear(); | ||
399 | xcb_window_t member2Wid = createGroupWindow(conn.data(), geometry, leaderWid); | 399 | xcb_window_t member2Wid = createGroupWindow(conn.data(), geometry, leaderWid); | ||
400 | xcb_map_window(conn.data(), member2Wid); | 400 | xcb_map_window(conn.data(), member2Wid); | ||
401 | xcb_flush(conn.data()); | 401 | xcb_flush(conn.data()); | ||
402 | 402 | | |||
403 | QVERIFY(windowCreatedSpy.wait()); | 403 | QVERIFY(windowCreatedSpy.wait()); | ||
404 | X11Client *member2 = windowCreatedSpy.first().first().value<X11Client *>(); | 404 | X11Client *member2 = windowCreatedSpy.first().first().value<X11Client *>(); | ||
405 | QVERIFY(member2); | 405 | QVERIFY(member2); | ||
406 | QVERIFY(member2->isActive()); | 406 | QVERIFY(member2->isActive()); | ||
407 | QCOMPARE(member2->windowId(), member2Wid); | 407 | QCOMPARE(member2->windowId(), member2Wid); | ||
408 | QCOMPARE(member2->group(), leader->group()); | 408 | QCOMPARE(member2->group(), leader->group()); | ||
409 | QVERIFY(!member2->isTransient()); | 409 | QVERIFY(!member2->isTransient()); | ||
410 | 410 | | |||
411 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{leader, member1, member2})); | 411 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1, member2})); | ||
412 | 412 | | |||
413 | // Create a group transient. | 413 | // Create a group transient. | ||
414 | windowCreatedSpy.clear(); | 414 | windowCreatedSpy.clear(); | ||
415 | xcb_window_t transientWid = createGroupWindow(conn.data(), geometry, leaderWid); | 415 | xcb_window_t transientWid = createGroupWindow(conn.data(), geometry, leaderWid); | ||
416 | xcb_icccm_set_wm_transient_for(conn.data(), transientWid, rootWindow()); | 416 | xcb_icccm_set_wm_transient_for(conn.data(), transientWid, rootWindow()); | ||
417 | 417 | | |||
418 | // Currently, we have some weird bug workaround: if a group transient | 418 | // Currently, we have some weird bug workaround: if a group transient | ||
419 | // is a non-modal dialog, then it won't be kept above its window group. | 419 | // is a non-modal dialog, then it won't be kept above its window group. | ||
Show All 23 Lines | |||||
443 | QVERIFY(transient); | 443 | QVERIFY(transient); | ||
444 | QVERIFY(transient->isActive()); | 444 | QVERIFY(transient->isActive()); | ||
445 | QCOMPARE(transient->windowId(), transientWid); | 445 | QCOMPARE(transient->windowId(), transientWid); | ||
446 | QCOMPARE(transient->group(), leader->group()); | 446 | QCOMPARE(transient->group(), leader->group()); | ||
447 | QVERIFY(transient->isTransient()); | 447 | QVERIFY(transient->isTransient()); | ||
448 | QVERIFY(transient->groupTransient()); | 448 | QVERIFY(transient->groupTransient()); | ||
449 | QVERIFY(!transient->isDialog()); // See above why | 449 | QVERIFY(!transient->isDialog()); // See above why | ||
450 | 450 | | |||
451 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{leader, member1, member2, transient})); | 451 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1, member2, transient})); | ||
452 | 452 | | |||
453 | // If we activate any member of the window group, the transient will be above it. | 453 | // If we activate any member of the window group, the transient will be above it. | ||
454 | workspace()->activateClient(leader); | 454 | workspace()->activateClient(leader); | ||
455 | QTRY_VERIFY(leader->isActive()); | 455 | QTRY_VERIFY(leader->isActive()); | ||
456 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{member1, member2, leader, transient})); | 456 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{member1, member2, leader, transient})); | ||
457 | 457 | | |||
458 | workspace()->activateClient(member1); | 458 | workspace()->activateClient(member1); | ||
459 | QTRY_VERIFY(member1->isActive()); | 459 | QTRY_VERIFY(member1->isActive()); | ||
460 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{member2, leader, member1, transient})); | 460 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{member2, leader, member1, transient})); | ||
461 | 461 | | |||
462 | workspace()->activateClient(member2); | 462 | workspace()->activateClient(member2); | ||
463 | QTRY_VERIFY(member2->isActive()); | 463 | QTRY_VERIFY(member2->isActive()); | ||
464 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{leader, member1, member2, transient})); | 464 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1, member2, transient})); | ||
465 | 465 | | |||
466 | workspace()->activateClient(transient); | 466 | workspace()->activateClient(transient); | ||
467 | QTRY_VERIFY(transient->isActive()); | 467 | QTRY_VERIFY(transient->isActive()); | ||
468 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{leader, member1, member2, transient})); | 468 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1, member2, transient})); | ||
469 | } | 469 | } | ||
470 | 470 | | |||
471 | void StackingOrderTest::testRaiseGroupTransient() | 471 | void StackingOrderTest::testRaiseGroupTransient() | ||
472 | { | 472 | { | ||
473 | const QRect geometry = QRect(0, 0, 128, 128); | 473 | const QRect geometry = QRect(0, 0, 128, 128); | ||
474 | 474 | | |||
475 | QScopedPointer<xcb_connection_t, XcbConnectionDeleter> conn( | 475 | QScopedPointer<xcb_connection_t, XcbConnectionDeleter> conn( | ||
476 | xcb_connect(nullptr, nullptr)); | 476 | xcb_connect(nullptr, nullptr)); | ||
477 | 477 | | |||
478 | QSignalSpy windowCreatedSpy(workspace(), &Workspace::clientAdded); | 478 | QSignalSpy windowCreatedSpy(workspace(), &Workspace::clientAdded); | ||
479 | QVERIFY(windowCreatedSpy.isValid()); | 479 | QVERIFY(windowCreatedSpy.isValid()); | ||
480 | 480 | | |||
481 | // Create the group leader. | 481 | // Create the group leader. | ||
482 | xcb_window_t leaderWid = createGroupWindow(conn.data(), geometry); | 482 | xcb_window_t leaderWid = createGroupWindow(conn.data(), geometry); | ||
483 | xcb_map_window(conn.data(), leaderWid); | 483 | xcb_map_window(conn.data(), leaderWid); | ||
484 | xcb_flush(conn.data()); | 484 | xcb_flush(conn.data()); | ||
485 | 485 | | |||
486 | QVERIFY(windowCreatedSpy.wait()); | 486 | QVERIFY(windowCreatedSpy.wait()); | ||
487 | X11Client *leader = windowCreatedSpy.first().first().value<X11Client *>(); | 487 | X11Client *leader = windowCreatedSpy.first().first().value<X11Client *>(); | ||
488 | QVERIFY(leader); | 488 | QVERIFY(leader); | ||
489 | QVERIFY(leader->isActive()); | 489 | QVERIFY(leader->isActive()); | ||
490 | QCOMPARE(leader->windowId(), leaderWid); | 490 | QCOMPARE(leader->windowId(), leaderWid); | ||
491 | QVERIFY(!leader->isTransient()); | 491 | QVERIFY(!leader->isTransient()); | ||
492 | 492 | | |||
493 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{leader})); | 493 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader})); | ||
494 | 494 | | |||
495 | // Create another group member. | 495 | // Create another group member. | ||
496 | windowCreatedSpy.clear(); | 496 | windowCreatedSpy.clear(); | ||
497 | xcb_window_t member1Wid = createGroupWindow(conn.data(), geometry, leaderWid); | 497 | xcb_window_t member1Wid = createGroupWindow(conn.data(), geometry, leaderWid); | ||
498 | xcb_map_window(conn.data(), member1Wid); | 498 | xcb_map_window(conn.data(), member1Wid); | ||
499 | xcb_flush(conn.data()); | 499 | xcb_flush(conn.data()); | ||
500 | 500 | | |||
501 | QVERIFY(windowCreatedSpy.wait()); | 501 | QVERIFY(windowCreatedSpy.wait()); | ||
502 | X11Client *member1 = windowCreatedSpy.first().first().value<X11Client *>(); | 502 | X11Client *member1 = windowCreatedSpy.first().first().value<X11Client *>(); | ||
503 | QVERIFY(member1); | 503 | QVERIFY(member1); | ||
504 | QVERIFY(member1->isActive()); | 504 | QVERIFY(member1->isActive()); | ||
505 | QCOMPARE(member1->windowId(), member1Wid); | 505 | QCOMPARE(member1->windowId(), member1Wid); | ||
506 | QCOMPARE(member1->group(), leader->group()); | 506 | QCOMPARE(member1->group(), leader->group()); | ||
507 | QVERIFY(!member1->isTransient()); | 507 | QVERIFY(!member1->isTransient()); | ||
508 | 508 | | |||
509 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{leader, member1})); | 509 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1})); | ||
510 | 510 | | |||
511 | // Create yet another group member. | 511 | // Create yet another group member. | ||
512 | windowCreatedSpy.clear(); | 512 | windowCreatedSpy.clear(); | ||
513 | xcb_window_t member2Wid = createGroupWindow(conn.data(), geometry, leaderWid); | 513 | xcb_window_t member2Wid = createGroupWindow(conn.data(), geometry, leaderWid); | ||
514 | xcb_map_window(conn.data(), member2Wid); | 514 | xcb_map_window(conn.data(), member2Wid); | ||
515 | xcb_flush(conn.data()); | 515 | xcb_flush(conn.data()); | ||
516 | 516 | | |||
517 | QVERIFY(windowCreatedSpy.wait()); | 517 | QVERIFY(windowCreatedSpy.wait()); | ||
518 | X11Client *member2 = windowCreatedSpy.first().first().value<X11Client *>(); | 518 | X11Client *member2 = windowCreatedSpy.first().first().value<X11Client *>(); | ||
519 | QVERIFY(member2); | 519 | QVERIFY(member2); | ||
520 | QVERIFY(member2->isActive()); | 520 | QVERIFY(member2->isActive()); | ||
521 | QCOMPARE(member2->windowId(), member2Wid); | 521 | QCOMPARE(member2->windowId(), member2Wid); | ||
522 | QCOMPARE(member2->group(), leader->group()); | 522 | QCOMPARE(member2->group(), leader->group()); | ||
523 | QVERIFY(!member2->isTransient()); | 523 | QVERIFY(!member2->isTransient()); | ||
524 | 524 | | |||
525 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{leader, member1, member2})); | 525 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1, member2})); | ||
526 | 526 | | |||
527 | // Create a group transient. | 527 | // Create a group transient. | ||
528 | windowCreatedSpy.clear(); | 528 | windowCreatedSpy.clear(); | ||
529 | xcb_window_t transientWid = createGroupWindow(conn.data(), geometry, leaderWid); | 529 | xcb_window_t transientWid = createGroupWindow(conn.data(), geometry, leaderWid); | ||
530 | xcb_icccm_set_wm_transient_for(conn.data(), transientWid, rootWindow()); | 530 | xcb_icccm_set_wm_transient_for(conn.data(), transientWid, rootWindow()); | ||
531 | 531 | | |||
532 | // Currently, we have some weird bug workaround: if a group transient | 532 | // Currently, we have some weird bug workaround: if a group transient | ||
533 | // is a non-modal dialog, then it won't be kept above its window group. | 533 | // is a non-modal dialog, then it won't be kept above its window group. | ||
Show All 23 Lines | |||||
557 | QVERIFY(transient); | 557 | QVERIFY(transient); | ||
558 | QVERIFY(transient->isActive()); | 558 | QVERIFY(transient->isActive()); | ||
559 | QCOMPARE(transient->windowId(), transientWid); | 559 | QCOMPARE(transient->windowId(), transientWid); | ||
560 | QCOMPARE(transient->group(), leader->group()); | 560 | QCOMPARE(transient->group(), leader->group()); | ||
561 | QVERIFY(transient->isTransient()); | 561 | QVERIFY(transient->isTransient()); | ||
562 | QVERIFY(transient->groupTransient()); | 562 | QVERIFY(transient->groupTransient()); | ||
563 | QVERIFY(!transient->isDialog()); // See above why | 563 | QVERIFY(!transient->isDialog()); // See above why | ||
564 | 564 | | |||
565 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{leader, member1, member2, transient})); | 565 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1, member2, transient})); | ||
566 | 566 | | |||
567 | // Create a Wayland client that is not a member of the window group. | 567 | // Create a Wayland client that is not a member of the window group. | ||
568 | KWayland::Client::Surface *anotherSurface = | 568 | KWayland::Client::Surface *anotherSurface = | ||
569 | Test::createSurface(Test::waylandCompositor()); | 569 | Test::createSurface(Test::waylandCompositor()); | ||
570 | QVERIFY(anotherSurface); | 570 | QVERIFY(anotherSurface); | ||
571 | KWayland::Client::XdgShellSurface *anotherShellSurface = | 571 | KWayland::Client::XdgShellSurface *anotherShellSurface = | ||
572 | Test::createXdgShellStableSurface(anotherSurface, anotherSurface); | 572 | Test::createXdgShellStableSurface(anotherSurface, anotherSurface); | ||
573 | QVERIFY(anotherShellSurface); | 573 | QVERIFY(anotherShellSurface); | ||
574 | XdgShellClient *anotherClient = Test::renderAndWaitForShown(anotherSurface, QSize(128, 128), Qt::green); | 574 | XdgShellClient *anotherClient = Test::renderAndWaitForShown(anotherSurface, QSize(128, 128), Qt::green); | ||
575 | QVERIFY(anotherClient); | 575 | QVERIFY(anotherClient); | ||
576 | QVERIFY(anotherClient->isActive()); | 576 | QVERIFY(anotherClient->isActive()); | ||
577 | QVERIFY(!anotherClient->isTransient()); | 577 | QVERIFY(!anotherClient->isTransient()); | ||
578 | 578 | | |||
579 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{leader, member1, member2, transient, anotherClient})); | 579 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1, member2, transient, anotherClient})); | ||
580 | 580 | | |||
581 | // If we activate the leader, then only it and the transient have to be raised. | 581 | // If we activate the leader, then only it and the transient have to be raised. | ||
582 | workspace()->activateClient(leader); | 582 | workspace()->activateClient(leader); | ||
583 | QTRY_VERIFY(leader->isActive()); | 583 | QTRY_VERIFY(leader->isActive()); | ||
584 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{member1, member2, anotherClient, leader, transient})); | 584 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{member1, member2, anotherClient, leader, transient})); | ||
585 | 585 | | |||
586 | // If another member of the window group is activated, then the transient will | 586 | // If another member of the window group is activated, then the transient will | ||
587 | // be above that member and the leader. | 587 | // be above that member and the leader. | ||
588 | workspace()->activateClient(member2); | 588 | workspace()->activateClient(member2); | ||
589 | QTRY_VERIFY(member2->isActive()); | 589 | QTRY_VERIFY(member2->isActive()); | ||
590 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{member1, anotherClient, leader, member2, transient})); | 590 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{member1, anotherClient, leader, member2, transient})); | ||
591 | 591 | | |||
592 | // FIXME: If we activate the transient, only it will be raised. | 592 | // FIXME: If we activate the transient, only it will be raised. | ||
593 | workspace()->activateClient(anotherClient); | 593 | workspace()->activateClient(anotherClient); | ||
594 | QTRY_VERIFY(anotherClient->isActive()); | 594 | QTRY_VERIFY(anotherClient->isActive()); | ||
595 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{member1, leader, member2, transient, anotherClient})); | 595 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{member1, leader, member2, transient, anotherClient})); | ||
596 | 596 | | |||
597 | workspace()->activateClient(transient); | 597 | workspace()->activateClient(transient); | ||
598 | QTRY_VERIFY(transient->isActive()); | 598 | QTRY_VERIFY(transient->isActive()); | ||
599 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{member1, leader, member2, anotherClient, transient})); | 599 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{member1, leader, member2, anotherClient, transient})); | ||
600 | } | 600 | } | ||
601 | 601 | | |||
602 | void StackingOrderTest::testDeletedGroupTransient() | 602 | void StackingOrderTest::testDeletedGroupTransient() | ||
603 | { | 603 | { | ||
604 | // This test verifies that deleted group transients are kept above their | 604 | // This test verifies that deleted group transients are kept above their | ||
605 | // old window groups. | 605 | // old window groups. | ||
606 | 606 | | |||
607 | const QRect geometry = QRect(0, 0, 128, 128); | 607 | const QRect geometry = QRect(0, 0, 128, 128); | ||
Show All 11 Lines | |||||
619 | 619 | | |||
620 | QVERIFY(windowCreatedSpy.wait()); | 620 | QVERIFY(windowCreatedSpy.wait()); | ||
621 | X11Client *leader = windowCreatedSpy.first().first().value<X11Client *>(); | 621 | X11Client *leader = windowCreatedSpy.first().first().value<X11Client *>(); | ||
622 | QVERIFY(leader); | 622 | QVERIFY(leader); | ||
623 | QVERIFY(leader->isActive()); | 623 | QVERIFY(leader->isActive()); | ||
624 | QCOMPARE(leader->windowId(), leaderWid); | 624 | QCOMPARE(leader->windowId(), leaderWid); | ||
625 | QVERIFY(!leader->isTransient()); | 625 | QVERIFY(!leader->isTransient()); | ||
626 | 626 | | |||
627 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{leader})); | 627 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader})); | ||
628 | 628 | | |||
629 | // Create another group member. | 629 | // Create another group member. | ||
630 | windowCreatedSpy.clear(); | 630 | windowCreatedSpy.clear(); | ||
631 | xcb_window_t member1Wid = createGroupWindow(conn.data(), geometry, leaderWid); | 631 | xcb_window_t member1Wid = createGroupWindow(conn.data(), geometry, leaderWid); | ||
632 | xcb_map_window(conn.data(), member1Wid); | 632 | xcb_map_window(conn.data(), member1Wid); | ||
633 | xcb_flush(conn.data()); | 633 | xcb_flush(conn.data()); | ||
634 | 634 | | |||
635 | QVERIFY(windowCreatedSpy.wait()); | 635 | QVERIFY(windowCreatedSpy.wait()); | ||
636 | X11Client *member1 = windowCreatedSpy.first().first().value<X11Client *>(); | 636 | X11Client *member1 = windowCreatedSpy.first().first().value<X11Client *>(); | ||
637 | QVERIFY(member1); | 637 | QVERIFY(member1); | ||
638 | QVERIFY(member1->isActive()); | 638 | QVERIFY(member1->isActive()); | ||
639 | QCOMPARE(member1->windowId(), member1Wid); | 639 | QCOMPARE(member1->windowId(), member1Wid); | ||
640 | QCOMPARE(member1->group(), leader->group()); | 640 | QCOMPARE(member1->group(), leader->group()); | ||
641 | QVERIFY(!member1->isTransient()); | 641 | QVERIFY(!member1->isTransient()); | ||
642 | 642 | | |||
643 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{leader, member1})); | 643 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1})); | ||
644 | 644 | | |||
645 | // Create yet another group member. | 645 | // Create yet another group member. | ||
646 | windowCreatedSpy.clear(); | 646 | windowCreatedSpy.clear(); | ||
647 | xcb_window_t member2Wid = createGroupWindow(conn.data(), geometry, leaderWid); | 647 | xcb_window_t member2Wid = createGroupWindow(conn.data(), geometry, leaderWid); | ||
648 | xcb_map_window(conn.data(), member2Wid); | 648 | xcb_map_window(conn.data(), member2Wid); | ||
649 | xcb_flush(conn.data()); | 649 | xcb_flush(conn.data()); | ||
650 | 650 | | |||
651 | QVERIFY(windowCreatedSpy.wait()); | 651 | QVERIFY(windowCreatedSpy.wait()); | ||
652 | X11Client *member2 = windowCreatedSpy.first().first().value<X11Client *>(); | 652 | X11Client *member2 = windowCreatedSpy.first().first().value<X11Client *>(); | ||
653 | QVERIFY(member2); | 653 | QVERIFY(member2); | ||
654 | QVERIFY(member2->isActive()); | 654 | QVERIFY(member2->isActive()); | ||
655 | QCOMPARE(member2->windowId(), member2Wid); | 655 | QCOMPARE(member2->windowId(), member2Wid); | ||
656 | QCOMPARE(member2->group(), leader->group()); | 656 | QCOMPARE(member2->group(), leader->group()); | ||
657 | QVERIFY(!member2->isTransient()); | 657 | QVERIFY(!member2->isTransient()); | ||
658 | 658 | | |||
659 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{leader, member1, member2})); | 659 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1, member2})); | ||
660 | 660 | | |||
661 | // Create a group transient. | 661 | // Create a group transient. | ||
662 | windowCreatedSpy.clear(); | 662 | windowCreatedSpy.clear(); | ||
663 | xcb_window_t transientWid = createGroupWindow(conn.data(), geometry, leaderWid); | 663 | xcb_window_t transientWid = createGroupWindow(conn.data(), geometry, leaderWid); | ||
664 | xcb_icccm_set_wm_transient_for(conn.data(), transientWid, rootWindow()); | 664 | xcb_icccm_set_wm_transient_for(conn.data(), transientWid, rootWindow()); | ||
665 | 665 | | |||
666 | // Currently, we have some weird bug workaround: if a group transient | 666 | // Currently, we have some weird bug workaround: if a group transient | ||
667 | // is a non-modal dialog, then it won't be kept above its window group. | 667 | // is a non-modal dialog, then it won't be kept above its window group. | ||
Show All 23 Lines | |||||
691 | QVERIFY(transient); | 691 | QVERIFY(transient); | ||
692 | QVERIFY(transient->isActive()); | 692 | QVERIFY(transient->isActive()); | ||
693 | QCOMPARE(transient->windowId(), transientWid); | 693 | QCOMPARE(transient->windowId(), transientWid); | ||
694 | QCOMPARE(transient->group(), leader->group()); | 694 | QCOMPARE(transient->group(), leader->group()); | ||
695 | QVERIFY(transient->isTransient()); | 695 | QVERIFY(transient->isTransient()); | ||
696 | QVERIFY(transient->groupTransient()); | 696 | QVERIFY(transient->groupTransient()); | ||
697 | QVERIFY(!transient->isDialog()); // See above why | 697 | QVERIFY(!transient->isDialog()); // See above why | ||
698 | 698 | | |||
699 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{leader, member1, member2, transient})); | 699 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1, member2, transient})); | ||
700 | 700 | | |||
701 | // Unmap the transient. | 701 | // Unmap the transient. | ||
702 | connect(transient, &X11Client::windowClosed, this, | 702 | connect(transient, &X11Client::windowClosed, this, | ||
703 | [](Toplevel *toplevel, Deleted *deleted) { | 703 | [](Toplevel *toplevel, Deleted *deleted) { | ||
704 | Q_UNUSED(toplevel) | 704 | Q_UNUSED(toplevel) | ||
705 | deleted->refWindow(); | 705 | deleted->refWindow(); | ||
706 | } | 706 | } | ||
707 | ); | 707 | ); | ||
708 | 708 | | |||
709 | QSignalSpy windowClosedSpy(transient, &X11Client::windowClosed); | 709 | QSignalSpy windowClosedSpy(transient, &X11Client::windowClosed); | ||
710 | QVERIFY(windowClosedSpy.isValid()); | 710 | QVERIFY(windowClosedSpy.isValid()); | ||
711 | xcb_unmap_window(conn.data(), transientWid); | 711 | xcb_unmap_window(conn.data(), transientWid); | ||
712 | xcb_flush(conn.data()); | 712 | xcb_flush(conn.data()); | ||
713 | QVERIFY(windowClosedSpy.wait()); | 713 | QVERIFY(windowClosedSpy.wait()); | ||
714 | 714 | | |||
715 | QScopedPointer<Deleted, WindowUnrefDeleter> deletedTransient( | 715 | QScopedPointer<Deleted, WindowUnrefDeleter> deletedTransient( | ||
716 | windowClosedSpy.first().at(1).value<Deleted *>()); | 716 | windowClosedSpy.first().at(1).value<Deleted *>()); | ||
717 | QVERIFY(deletedTransient.data()); | 717 | QVERIFY(deletedTransient.data()); | ||
718 | 718 | | |||
719 | // The transient has to be above each member of the window group. | 719 | // The transient has to be above each member of the window group. | ||
720 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{leader, member1, member2, deletedTransient.data()})); | 720 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1, member2, deletedTransient.data()})); | ||
721 | } | 721 | } | ||
722 | 722 | | |||
723 | void StackingOrderTest::testDontKeepAboveNonModalDialogGroupTransients() | 723 | void StackingOrderTest::testDontKeepAboveNonModalDialogGroupTransients() | ||
724 | { | 724 | { | ||
725 | // Bug 76026 | 725 | // Bug 76026 | ||
726 | 726 | | |||
727 | const QRect geometry = QRect(0, 0, 128, 128); | 727 | const QRect geometry = QRect(0, 0, 128, 128); | ||
728 | 728 | | |||
Show All 10 Lines | |||||
739 | 739 | | |||
740 | QVERIFY(windowCreatedSpy.wait()); | 740 | QVERIFY(windowCreatedSpy.wait()); | ||
741 | X11Client *leader = windowCreatedSpy.first().first().value<X11Client *>(); | 741 | X11Client *leader = windowCreatedSpy.first().first().value<X11Client *>(); | ||
742 | QVERIFY(leader); | 742 | QVERIFY(leader); | ||
743 | QVERIFY(leader->isActive()); | 743 | QVERIFY(leader->isActive()); | ||
744 | QCOMPARE(leader->windowId(), leaderWid); | 744 | QCOMPARE(leader->windowId(), leaderWid); | ||
745 | QVERIFY(!leader->isTransient()); | 745 | QVERIFY(!leader->isTransient()); | ||
746 | 746 | | |||
747 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{leader})); | 747 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader})); | ||
748 | 748 | | |||
749 | // Create another group member. | 749 | // Create another group member. | ||
750 | windowCreatedSpy.clear(); | 750 | windowCreatedSpy.clear(); | ||
751 | xcb_window_t member1Wid = createGroupWindow(conn.data(), geometry, leaderWid); | 751 | xcb_window_t member1Wid = createGroupWindow(conn.data(), geometry, leaderWid); | ||
752 | xcb_map_window(conn.data(), member1Wid); | 752 | xcb_map_window(conn.data(), member1Wid); | ||
753 | xcb_flush(conn.data()); | 753 | xcb_flush(conn.data()); | ||
754 | 754 | | |||
755 | QVERIFY(windowCreatedSpy.wait()); | 755 | QVERIFY(windowCreatedSpy.wait()); | ||
756 | X11Client *member1 = windowCreatedSpy.first().first().value<X11Client *>(); | 756 | X11Client *member1 = windowCreatedSpy.first().first().value<X11Client *>(); | ||
757 | QVERIFY(member1); | 757 | QVERIFY(member1); | ||
758 | QVERIFY(member1->isActive()); | 758 | QVERIFY(member1->isActive()); | ||
759 | QCOMPARE(member1->windowId(), member1Wid); | 759 | QCOMPARE(member1->windowId(), member1Wid); | ||
760 | QCOMPARE(member1->group(), leader->group()); | 760 | QCOMPARE(member1->group(), leader->group()); | ||
761 | QVERIFY(!member1->isTransient()); | 761 | QVERIFY(!member1->isTransient()); | ||
762 | 762 | | |||
763 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{leader, member1})); | 763 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1})); | ||
764 | 764 | | |||
765 | // Create yet another group member. | 765 | // Create yet another group member. | ||
766 | windowCreatedSpy.clear(); | 766 | windowCreatedSpy.clear(); | ||
767 | xcb_window_t member2Wid = createGroupWindow(conn.data(), geometry, leaderWid); | 767 | xcb_window_t member2Wid = createGroupWindow(conn.data(), geometry, leaderWid); | ||
768 | xcb_map_window(conn.data(), member2Wid); | 768 | xcb_map_window(conn.data(), member2Wid); | ||
769 | xcb_flush(conn.data()); | 769 | xcb_flush(conn.data()); | ||
770 | 770 | | |||
771 | QVERIFY(windowCreatedSpy.wait()); | 771 | QVERIFY(windowCreatedSpy.wait()); | ||
772 | X11Client *member2 = windowCreatedSpy.first().first().value<X11Client *>(); | 772 | X11Client *member2 = windowCreatedSpy.first().first().value<X11Client *>(); | ||
773 | QVERIFY(member2); | 773 | QVERIFY(member2); | ||
774 | QVERIFY(member2->isActive()); | 774 | QVERIFY(member2->isActive()); | ||
775 | QCOMPARE(member2->windowId(), member2Wid); | 775 | QCOMPARE(member2->windowId(), member2Wid); | ||
776 | QCOMPARE(member2->group(), leader->group()); | 776 | QCOMPARE(member2->group(), leader->group()); | ||
777 | QVERIFY(!member2->isTransient()); | 777 | QVERIFY(!member2->isTransient()); | ||
778 | 778 | | |||
779 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{leader, member1, member2})); | 779 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1, member2})); | ||
780 | 780 | | |||
781 | // Create a group transient. | 781 | // Create a group transient. | ||
782 | windowCreatedSpy.clear(); | 782 | windowCreatedSpy.clear(); | ||
783 | xcb_window_t transientWid = createGroupWindow(conn.data(), geometry, leaderWid); | 783 | xcb_window_t transientWid = createGroupWindow(conn.data(), geometry, leaderWid); | ||
784 | xcb_icccm_set_wm_transient_for(conn.data(), transientWid, rootWindow()); | 784 | xcb_icccm_set_wm_transient_for(conn.data(), transientWid, rootWindow()); | ||
785 | xcb_map_window(conn.data(), transientWid); | 785 | xcb_map_window(conn.data(), transientWid); | ||
786 | xcb_flush(conn.data()); | 786 | xcb_flush(conn.data()); | ||
787 | 787 | | |||
788 | QVERIFY(windowCreatedSpy.wait()); | 788 | QVERIFY(windowCreatedSpy.wait()); | ||
789 | X11Client *transient = windowCreatedSpy.first().first().value<X11Client *>(); | 789 | X11Client *transient = windowCreatedSpy.first().first().value<X11Client *>(); | ||
790 | QVERIFY(transient); | 790 | QVERIFY(transient); | ||
791 | QVERIFY(transient->isActive()); | 791 | QVERIFY(transient->isActive()); | ||
792 | QCOMPARE(transient->windowId(), transientWid); | 792 | QCOMPARE(transient->windowId(), transientWid); | ||
793 | QCOMPARE(transient->group(), leader->group()); | 793 | QCOMPARE(transient->group(), leader->group()); | ||
794 | QVERIFY(transient->isTransient()); | 794 | QVERIFY(transient->isTransient()); | ||
795 | QVERIFY(transient->groupTransient()); | 795 | QVERIFY(transient->groupTransient()); | ||
796 | QVERIFY(transient->isDialog()); | 796 | QVERIFY(transient->isDialog()); | ||
797 | QVERIFY(!transient->isModal()); | 797 | QVERIFY(!transient->isModal()); | ||
798 | 798 | | |||
799 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{leader, member1, member2, transient})); | 799 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1, member2, transient})); | ||
800 | 800 | | |||
801 | workspace()->activateClient(leader); | 801 | workspace()->activateClient(leader); | ||
802 | QTRY_VERIFY(leader->isActive()); | 802 | QTRY_VERIFY(leader->isActive()); | ||
803 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{member1, member2, transient, leader})); | 803 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{member1, member2, transient, leader})); | ||
804 | 804 | | |||
805 | workspace()->activateClient(member1); | 805 | workspace()->activateClient(member1); | ||
806 | QTRY_VERIFY(member1->isActive()); | 806 | QTRY_VERIFY(member1->isActive()); | ||
807 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{member2, transient, leader, member1})); | 807 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{member2, transient, leader, member1})); | ||
808 | 808 | | |||
809 | workspace()->activateClient(member2); | 809 | workspace()->activateClient(member2); | ||
810 | QTRY_VERIFY(member2->isActive()); | 810 | QTRY_VERIFY(member2->isActive()); | ||
811 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{transient, leader, member1, member2})); | 811 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{transient, leader, member1, member2})); | ||
812 | 812 | | |||
813 | workspace()->activateClient(transient); | 813 | workspace()->activateClient(transient); | ||
814 | QTRY_VERIFY(transient->isActive()); | 814 | QTRY_VERIFY(transient->isActive()); | ||
815 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{leader, member1, member2, transient})); | 815 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1, member2, transient})); | ||
816 | } | 816 | } | ||
817 | 817 | | |||
818 | void StackingOrderTest::testKeepAbove() | 818 | void StackingOrderTest::testKeepAbove() | ||
819 | { | 819 | { | ||
820 | // This test verifies that "keep-above" windows are kept above other windows. | 820 | // This test verifies that "keep-above" windows are kept above other windows. | ||
821 | 821 | | |||
822 | // Create the first client. | 822 | // Create the first client. | ||
823 | KWayland::Client::Surface *clientASurface = | 823 | KWayland::Client::Surface *clientASurface = | ||
824 | Test::createSurface(Test::waylandCompositor()); | 824 | Test::createSurface(Test::waylandCompositor()); | ||
825 | QVERIFY(clientASurface); | 825 | QVERIFY(clientASurface); | ||
826 | KWayland::Client::XdgShellSurface *clientAShellSurface = | 826 | KWayland::Client::XdgShellSurface *clientAShellSurface = | ||
827 | Test::createXdgShellStableSurface(clientASurface, clientASurface); | 827 | Test::createXdgShellStableSurface(clientASurface, clientASurface); | ||
828 | QVERIFY(clientAShellSurface); | 828 | QVERIFY(clientAShellSurface); | ||
829 | XdgShellClient *clientA = Test::renderAndWaitForShown(clientASurface, QSize(128, 128), Qt::green); | 829 | XdgShellClient *clientA = Test::renderAndWaitForShown(clientASurface, QSize(128, 128), Qt::green); | ||
830 | QVERIFY(clientA); | 830 | QVERIFY(clientA); | ||
831 | QVERIFY(clientA->isActive()); | 831 | QVERIFY(clientA->isActive()); | ||
832 | QVERIFY(!clientA->keepAbove()); | 832 | QVERIFY(!clientA->keepAbove()); | ||
833 | 833 | | |||
834 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{clientA})); | 834 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{clientA})); | ||
835 | 835 | | |||
836 | // Create the second client. | 836 | // Create the second client. | ||
837 | KWayland::Client::Surface *clientBSurface = | 837 | KWayland::Client::Surface *clientBSurface = | ||
838 | Test::createSurface(Test::waylandCompositor()); | 838 | Test::createSurface(Test::waylandCompositor()); | ||
839 | QVERIFY(clientBSurface); | 839 | QVERIFY(clientBSurface); | ||
840 | KWayland::Client::XdgShellSurface *clientBShellSurface = | 840 | KWayland::Client::XdgShellSurface *clientBShellSurface = | ||
841 | Test::createXdgShellStableSurface(clientBSurface, clientBSurface); | 841 | Test::createXdgShellStableSurface(clientBSurface, clientBSurface); | ||
842 | QVERIFY(clientBShellSurface); | 842 | QVERIFY(clientBShellSurface); | ||
843 | XdgShellClient *clientB = Test::renderAndWaitForShown(clientBSurface, QSize(128, 128), Qt::green); | 843 | XdgShellClient *clientB = Test::renderAndWaitForShown(clientBSurface, QSize(128, 128), Qt::green); | ||
844 | QVERIFY(clientB); | 844 | QVERIFY(clientB); | ||
845 | QVERIFY(clientB->isActive()); | 845 | QVERIFY(clientB->isActive()); | ||
846 | QVERIFY(!clientB->keepAbove()); | 846 | QVERIFY(!clientB->keepAbove()); | ||
847 | 847 | | |||
848 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{clientA, clientB})); | 848 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{clientA, clientB})); | ||
849 | 849 | | |||
850 | // Go to the initial test position. | 850 | // Go to the initial test position. | ||
851 | workspace()->activateClient(clientA); | 851 | workspace()->activateClient(clientA); | ||
852 | QTRY_VERIFY(clientA->isActive()); | 852 | QTRY_VERIFY(clientA->isActive()); | ||
853 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{clientB, clientA})); | 853 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{clientB, clientA})); | ||
854 | 854 | | |||
855 | // Set the "keep-above" flag on the client B, it should go above other clients. | 855 | // Set the "keep-above" flag on the client B, it should go above other clients. | ||
856 | { | 856 | { | ||
857 | StackingUpdatesBlocker blocker(workspace()); | 857 | StackingUpdatesBlocker blocker(workspace()); | ||
858 | clientB->setKeepAbove(true); | 858 | clientB->setKeepAbove(true); | ||
859 | } | 859 | } | ||
860 | 860 | | |||
861 | QVERIFY(clientB->keepAbove()); | 861 | QVERIFY(clientB->keepAbove()); | ||
862 | QVERIFY(!clientB->isActive()); | 862 | QVERIFY(!clientB->isActive()); | ||
863 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{clientA, clientB})); | 863 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{clientA, clientB})); | ||
864 | } | 864 | } | ||
865 | 865 | | |||
866 | void StackingOrderTest::testKeepBelow() | 866 | void StackingOrderTest::testKeepBelow() | ||
867 | { | 867 | { | ||
868 | // This test verifies that "keep-below" windows are kept below other windows. | 868 | // This test verifies that "keep-below" windows are kept below other windows. | ||
869 | 869 | | |||
870 | // Create the first client. | 870 | // Create the first client. | ||
871 | KWayland::Client::Surface *clientASurface = | 871 | KWayland::Client::Surface *clientASurface = | ||
872 | Test::createSurface(Test::waylandCompositor()); | 872 | Test::createSurface(Test::waylandCompositor()); | ||
873 | QVERIFY(clientASurface); | 873 | QVERIFY(clientASurface); | ||
874 | KWayland::Client::XdgShellSurface *clientAShellSurface = | 874 | KWayland::Client::XdgShellSurface *clientAShellSurface = | ||
875 | Test::createXdgShellStableSurface(clientASurface, clientASurface); | 875 | Test::createXdgShellStableSurface(clientASurface, clientASurface); | ||
876 | QVERIFY(clientAShellSurface); | 876 | QVERIFY(clientAShellSurface); | ||
877 | XdgShellClient *clientA = Test::renderAndWaitForShown(clientASurface, QSize(128, 128), Qt::green); | 877 | XdgShellClient *clientA = Test::renderAndWaitForShown(clientASurface, QSize(128, 128), Qt::green); | ||
878 | QVERIFY(clientA); | 878 | QVERIFY(clientA); | ||
879 | QVERIFY(clientA->isActive()); | 879 | QVERIFY(clientA->isActive()); | ||
880 | QVERIFY(!clientA->keepBelow()); | 880 | QVERIFY(!clientA->keepBelow()); | ||
881 | 881 | | |||
882 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{clientA})); | 882 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{clientA})); | ||
883 | 883 | | |||
884 | // Create the second client. | 884 | // Create the second client. | ||
885 | KWayland::Client::Surface *clientBSurface = | 885 | KWayland::Client::Surface *clientBSurface = | ||
886 | Test::createSurface(Test::waylandCompositor()); | 886 | Test::createSurface(Test::waylandCompositor()); | ||
887 | QVERIFY(clientBSurface); | 887 | QVERIFY(clientBSurface); | ||
888 | KWayland::Client::XdgShellSurface *clientBShellSurface = | 888 | KWayland::Client::XdgShellSurface *clientBShellSurface = | ||
889 | Test::createXdgShellStableSurface(clientBSurface, clientBSurface); | 889 | Test::createXdgShellStableSurface(clientBSurface, clientBSurface); | ||
890 | QVERIFY(clientBShellSurface); | 890 | QVERIFY(clientBShellSurface); | ||
891 | XdgShellClient *clientB = Test::renderAndWaitForShown(clientBSurface, QSize(128, 128), Qt::green); | 891 | XdgShellClient *clientB = Test::renderAndWaitForShown(clientBSurface, QSize(128, 128), Qt::green); | ||
892 | QVERIFY(clientB); | 892 | QVERIFY(clientB); | ||
893 | QVERIFY(clientB->isActive()); | 893 | QVERIFY(clientB->isActive()); | ||
894 | QVERIFY(!clientB->keepBelow()); | 894 | QVERIFY(!clientB->keepBelow()); | ||
895 | 895 | | |||
896 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{clientA, clientB})); | 896 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{clientA, clientB})); | ||
897 | 897 | | |||
898 | // Set the "keep-below" flag on the client B, it should go below other clients. | 898 | // Set the "keep-below" flag on the client B, it should go below other clients. | ||
899 | { | 899 | { | ||
900 | StackingUpdatesBlocker blocker(workspace()); | 900 | StackingUpdatesBlocker blocker(workspace()); | ||
901 | clientB->setKeepBelow(true); | 901 | clientB->setKeepBelow(true); | ||
902 | } | 902 | } | ||
903 | 903 | | |||
904 | QVERIFY(clientB->isActive()); | 904 | QVERIFY(clientB->isActive()); | ||
905 | QVERIFY(clientB->keepBelow()); | 905 | QVERIFY(clientB->keepBelow()); | ||
906 | QCOMPARE(workspace()->stackingOrder(), (ToplevelList{clientB, clientA})); | 906 | QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{clientB, clientA})); | ||
907 | } | 907 | } | ||
908 | 908 | | |||
909 | WAYLANDTEST_MAIN(StackingOrderTest) | 909 | WAYLANDTEST_MAIN(StackingOrderTest) | ||
910 | #include "stacking_order_test.moc" | 910 | #include "stacking_order_test.moc" |