From a195223a8d581e0d6d36374771c939414c7c036d Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Wed, 14 Oct 2020 21:53:07 +0300 Subject: [PATCH] wayland: Fix Qt clients not being maximized initially Currently, Qt clients send two maximize requests separated by the initial commit. From spec's perspective, this is totally fine, the client should receive two configure events with "maximized" state. But because changeMaximize() in XdgToplevelClient and setMaximized() operate on two different maximize modes, the second maximize request will trick kwin into thinking that the client should be restored. --- abstract_client.cpp | 2 +- autotests/integration/xdgshellclient_test.cpp | 34 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/abstract_client.cpp b/abstract_client.cpp index 96122f0f24..a768042eef 100644 --- a/abstract_client.cpp +++ b/abstract_client.cpp @@ -878,7 +878,7 @@ void AbstractClient::maximize(MaximizeMode m) void AbstractClient::setMaximize(bool vertically, bool horizontally) { // changeMaximize() flips the state, so change from set->flip - const MaximizeMode oldMode = maximizeMode(); + const MaximizeMode oldMode = requestedMaximizeMode(); changeMaximize( oldMode & MaximizeHorizontal ? !horizontally : horizontally, oldMode & MaximizeVertical ? !vertically : vertically, diff --git a/autotests/integration/xdgshellclient_test.cpp b/autotests/integration/xdgshellclient_test.cpp index 89470083be..499c89be07 100644 --- a/autotests/integration/xdgshellclient_test.cpp +++ b/autotests/integration/xdgshellclient_test.cpp @@ -100,6 +100,7 @@ private Q_SLOTS: void testXdgWindowGeometryMaximize(); void testPointerInputTransform(); void testReentrantSetFrameGeometry(); + void testDoubleMaximize(); }; void TestXdgShellClient::initTestCase() @@ -1558,5 +1559,38 @@ void TestXdgShellClient::testReentrantSetFrameGeometry() QVERIFY(Test::waitForWindowDestroyed(client)); } +void TestXdgShellClient::testDoubleMaximize() +{ + // This test verifies that the case where a client issues two set_maximized() requests + // separated by the initial commit is handled properly. + + // Create the test surface. + QScopedPointer surface(Test::createSurface()); + QScopedPointer shellSurface(Test::createXdgShellStableSurface(surface.data(), nullptr, Test::CreationSetup::CreateOnly)); + shellSurface->setMaximized(true); + surface->commit(Surface::CommitFlag::None); + + // Wait for the compositor to respond with a configure event. + QSignalSpy configureRequestedSpy(shellSurface.data(), &XdgShellSurface::configureRequested); + QVERIFY(configureRequestedSpy.wait()); + QCOMPARE(configureRequestedSpy.count(), 1); + QSize size = configureRequestedSpy.last().at(0).value(); + QCOMPARE(size, QSize(1280, 1024)); + XdgShellSurface::States states = configureRequestedSpy.last().at(1).value(); + QVERIFY(states.testFlag(XdgShellSurface::State::Maximized)); + + // Send another set_maximized() request, but do not attach any buffer yet. + shellSurface->setMaximized(true); + surface->commit(Surface::CommitFlag::None); + + // The compositor must respond with another configure event even if the state hasn't changed. + QVERIFY(configureRequestedSpy.wait()); + QCOMPARE(configureRequestedSpy.count(), 2); + size = configureRequestedSpy.last().at(0).value(); + QCOMPARE(size, QSize(1280, 1024)); + states = configureRequestedSpy.last().at(1).value(); + QVERIFY(states.testFlag(XdgShellSurface::State::Maximized)); +} + WAYLANDTEST_MAIN(TestXdgShellClient) #include "xdgshellclient_test.moc"