Changeset View
Changeset View
Standalone View
Standalone View
autotests/integration/maximize_test.cpp
Show All 24 Lines | |||||
25 | #include "wayland_server.h" | 25 | #include "wayland_server.h" | ||
26 | #include "workspace.h" | 26 | #include "workspace.h" | ||
27 | 27 | | |||
28 | #include <KWayland/Client/compositor.h> | 28 | #include <KWayland/Client/compositor.h> | ||
29 | #include <KWayland/Client/shell.h> | 29 | #include <KWayland/Client/shell.h> | ||
30 | #include <KWayland/Client/shm_pool.h> | 30 | #include <KWayland/Client/shm_pool.h> | ||
31 | #include <KWayland/Client/surface.h> | 31 | #include <KWayland/Client/surface.h> | ||
32 | #include <KWayland/Client/server_decoration.h> | 32 | #include <KWayland/Client/server_decoration.h> | ||
33 | #include <KWayland/Client/xdgdecoration.h> | ||||
33 | 34 | | |||
34 | #include <KWayland/Server/shell_interface.h> | 35 | #include <KWayland/Server/shell_interface.h> | ||
36 | #include <KWayland/Server/xdgdecoration_interface.h> | ||||
35 | 37 | | |||
36 | #include <KDecoration2/Decoration> | 38 | #include <KDecoration2/Decoration> | ||
37 | #include <KDecoration2/DecoratedClient> | 39 | #include <KDecoration2/DecoratedClient> | ||
38 | 40 | | |||
39 | using namespace KWin; | 41 | using namespace KWin; | ||
40 | using namespace KWayland::Client; | 42 | using namespace KWayland::Client; | ||
41 | 43 | | |||
42 | static const QString s_socketName = QStringLiteral("wayland_test_kwin_maximized-0"); | 44 | static const QString s_socketName = QStringLiteral("wayland_test_kwin_maximized-0"); | ||
43 | 45 | | |||
44 | class TestMaximized : public QObject | 46 | class TestMaximized : public QObject | ||
45 | { | 47 | { | ||
46 | Q_OBJECT | 48 | Q_OBJECT | ||
47 | private Q_SLOTS: | 49 | private Q_SLOTS: | ||
48 | void initTestCase(); | 50 | void initTestCase(); | ||
49 | void init(); | 51 | void init(); | ||
50 | void cleanup(); | 52 | void cleanup(); | ||
51 | 53 | | |||
52 | void testMaximizedPassedToDeco(); | 54 | void testMaximizedPassedToDeco(); | ||
53 | void testInitiallyMaximized(); | 55 | void testInitiallyMaximized(); | ||
54 | void testBorderlessMaximizedWindow(); | 56 | void testBorderlessMaximizedWindow(); | ||
57 | void testBorderlessMaximizedWindowNoClientSideDecoration(); | ||||
55 | }; | 58 | }; | ||
56 | 59 | | |||
57 | void TestMaximized::initTestCase() | 60 | void TestMaximized::initTestCase() | ||
58 | { | 61 | { | ||
59 | qRegisterMetaType<KWin::ShellClient*>(); | 62 | qRegisterMetaType<KWin::ShellClient*>(); | ||
60 | qRegisterMetaType<KWin::AbstractClient*>(); | 63 | qRegisterMetaType<KWin::AbstractClient*>(); | ||
61 | QSignalSpy workspaceCreatedSpy(kwinApp(), &Application::workspaceCreated); | 64 | QSignalSpy workspaceCreatedSpy(kwinApp(), &Application::workspaceCreated); | ||
62 | QVERIFY(workspaceCreatedSpy.isValid()); | 65 | QVERIFY(workspaceCreatedSpy.isValid()); | ||
63 | kwinApp()->platform()->setInitialWindowSize(QSize(1280, 1024)); | 66 | kwinApp()->platform()->setInitialWindowSize(QSize(1280, 1024)); | ||
64 | QMetaObject::invokeMethod(kwinApp()->platform(), "setVirtualOutputs", Qt::DirectConnection, Q_ARG(int, 2)); | 67 | QMetaObject::invokeMethod(kwinApp()->platform(), "setVirtualOutputs", Qt::DirectConnection, Q_ARG(int, 2)); | ||
65 | QVERIFY(waylandServer()->init(s_socketName.toLocal8Bit())); | 68 | QVERIFY(waylandServer()->init(s_socketName.toLocal8Bit())); | ||
66 | 69 | | |||
67 | kwinApp()->setConfig(KSharedConfig::openConfig(QString(), KConfig::SimpleConfig)); | 70 | kwinApp()->setConfig(KSharedConfig::openConfig(QString(), KConfig::SimpleConfig)); | ||
68 | 71 | | |||
69 | kwinApp()->start(); | 72 | kwinApp()->start(); | ||
70 | QVERIFY(workspaceCreatedSpy.wait()); | 73 | QVERIFY(workspaceCreatedSpy.wait()); | ||
71 | QCOMPARE(screens()->count(), 2); | 74 | QCOMPARE(screens()->count(), 2); | ||
72 | QCOMPARE(screens()->geometry(0), QRect(0, 0, 1280, 1024)); | 75 | QCOMPARE(screens()->geometry(0), QRect(0, 0, 1280, 1024)); | ||
73 | QCOMPARE(screens()->geometry(1), QRect(1280, 0, 1280, 1024)); | 76 | QCOMPARE(screens()->geometry(1), QRect(1280, 0, 1280, 1024)); | ||
74 | waylandServer()->initWorkspace(); | 77 | waylandServer()->initWorkspace(); | ||
75 | } | 78 | } | ||
76 | 79 | | |||
77 | void TestMaximized::init() | 80 | void TestMaximized::init() | ||
78 | { | 81 | { | ||
79 | QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Decoration)); | 82 | QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Decoration | | ||
83 | Test::AdditionalWaylandInterface::XdgDecoration)); | ||||
80 | 84 | | |||
81 | screens()->setCurrent(0); | 85 | screens()->setCurrent(0); | ||
82 | KWin::Cursor::setPos(QPoint(1280, 512)); | 86 | KWin::Cursor::setPos(QPoint(1280, 512)); | ||
83 | } | 87 | } | ||
84 | 88 | | |||
85 | void TestMaximized::cleanup() | 89 | void TestMaximized::cleanup() | ||
86 | { | 90 | { | ||
87 | Test::destroyWaylandConnection(); | 91 | Test::destroyWaylandConnection(); | ||
▲ Show 20 Lines • Show All 130 Lines • ▼ Show 20 Line(s) | 184 | { | |||
218 | Test::render(surface.data(), QSize(100, 50), Qt::red); | 222 | Test::render(surface.data(), QSize(100, 50), Qt::red); | ||
219 | QVERIFY(geometryChangedSpy.wait()); | 223 | QVERIFY(geometryChangedSpy.wait()); | ||
220 | QCOMPARE(client->maximizeMode(), MaximizeMode::MaximizeRestore); | 224 | QCOMPARE(client->maximizeMode(), MaximizeMode::MaximizeRestore); | ||
221 | QCOMPARE(client->geometry(), origGeo); | 225 | QCOMPARE(client->geometry(), origGeo); | ||
222 | QCOMPARE(client->geometryRestore(), origGeo); | 226 | QCOMPARE(client->geometryRestore(), origGeo); | ||
223 | QCOMPARE(client->isDecorated(), true); | 227 | QCOMPARE(client->isDecorated(), true); | ||
224 | } | 228 | } | ||
225 | 229 | | |||
230 | void TestMaximized::testBorderlessMaximizedWindowNoClientSideDecoration() | ||||
231 | { | ||||
232 | // test case verifies that borderless maximized windows doesn't cause | ||||
233 | // clients to render client-side decorations instead (BUG 405385) | ||||
234 | | ||||
235 | // adjust config | ||||
236 | auto group = kwinApp()->config()->group("Windows"); | ||||
237 | group.writeEntry("BorderlessMaximizedWindows", true); | ||||
238 | group.sync(); | ||||
239 | Workspace::self()->slotReconfigure(); | ||||
240 | QCOMPARE(options->borderlessMaximizedWindows(), true); | ||||
241 | | ||||
242 | QScopedPointer<Surface> surface(Test::createSurface()); | ||||
243 | QScopedPointer<XdgShellSurface> xdgShellSurface(Test::createXdgShellStableSurface(surface.data())); | ||||
244 | QScopedPointer<XdgDecoration> deco(Test::xdgDecorationManager()->getToplevelDecoration(xdgShellSurface.data())); | ||||
245 | | ||||
246 | QSignalSpy decorationConfiguredSpy(deco.data(), &XdgDecoration::modeChanged); | ||||
247 | QVERIFY(decorationConfiguredSpy.isValid()); | ||||
248 | | ||||
249 | auto client = Test::renderAndWaitForShown(surface.data(), QSize(100, 50), Qt::blue); | ||||
250 | | ||||
251 | QSignalSpy geometryChangedSpy(client, &ShellClient::geometryChanged); | ||||
252 | QVERIFY(geometryChangedSpy.isValid()); | ||||
253 | QSignalSpy sizeChangeRequestedSpy(xdgShellSurface.data(), &XdgShellSurface::sizeChanged); | ||||
254 | QVERIFY(sizeChangeRequestedSpy.isValid()); | ||||
255 | QSignalSpy configureRequestedSpy(xdgShellSurface.data(), &XdgShellSurface::configureRequested); | ||||
256 | QVERIFY(configureRequestedSpy.isValid()); | ||||
257 | | ||||
258 | QVERIFY(client->isDecorated()); | ||||
259 | QVERIFY(!client->noBorder()); | ||||
260 | configureRequestedSpy.wait(); | ||||
261 | QCOMPARE(decorationConfiguredSpy.count(), 1); | ||||
262 | QCOMPARE(deco->mode(), XdgDecoration::Mode::ServerSide); | ||||
263 | | ||||
264 | // go to maximized | ||||
265 | xdgShellSurface->setMaximized(true); | ||||
266 | QVERIFY(sizeChangeRequestedSpy.wait()); | ||||
267 | QCOMPARE(sizeChangeRequestedSpy.count(), 1); | ||||
zzag: maybe you could check decorationConfiguredSpy.count() here as well. though in general it's a… | |||||
We should only send one, but whether we or not is somewhat unrelated to this patch. Try checking it's one, but if it fails leave it. davidedmundson: We should only send one, but whether we or not is somewhat unrelated to this patch.
Try… | |||||
268 | | ||||
269 | for (const auto &it: configureRequestedSpy) { | ||||
270 | xdgShellSurface->ackConfigure(it[2].toInt()); | ||||
271 | } | ||||
zzag: just ack the last one | |||||
272 | Test::render(surface.data(), sizeChangeRequestedSpy.last().first().toSize(), Qt::red); | ||||
273 | QVERIFY(geometryChangedSpy.wait()); | ||||
274 | | ||||
275 | // no deco | ||||
276 | QVERIFY(!client->isDecorated()); | ||||
277 | QVERIFY(client->noBorder()); | ||||
278 | // but still server-side | ||||
279 | QCOMPARE(deco->mode(), XdgDecoration::Mode::ServerSide); | ||||
280 | | ||||
281 | // go back to normal | ||||
282 | xdgShellSurface->setMaximized(false); | ||||
283 | QVERIFY(sizeChangeRequestedSpy.wait()); | ||||
284 | QCOMPARE(sizeChangeRequestedSpy.count(), 2); | ||||
285 | | ||||
286 | for (const auto &it: configureRequestedSpy) { | ||||
287 | xdgShellSurface->ackConfigure(it[2].toInt()); | ||||
288 | } | ||||
289 | Test::render(surface.data(), sizeChangeRequestedSpy.last().first().toSize(), Qt::red); | ||||
290 | QVERIFY(geometryChangedSpy.wait()); | ||||
291 | | ||||
292 | QVERIFY(client->isDecorated()); | ||||
293 | QVERIFY(!client->noBorder()); | ||||
294 | QCOMPARE(deco->mode(), XdgDecoration::Mode::ServerSide); | ||||
295 | } | ||||
296 | | ||||
226 | WAYLANDTEST_MAIN(TestMaximized) | 297 | WAYLANDTEST_MAIN(TestMaximized) | ||
227 | #include "maximize_test.moc" | 298 | #include "maximize_test.moc" |
maybe you could check decorationConfiguredSpy.count() here as well. though in general it's a bit messy because kwin sends several configure events in this case.....