From 10ace126be219c0665e404e8dcf83a04c41035a3 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Fri, 11 Oct 2019 10:46:08 +0200 Subject: [PATCH] [wayland] Make sure fullscreen windows aren't repositioned Summary: on X11, setFullScreen is always called after Placement::place() so they always have the correct geometry. on wayland, the window if is shown directly as fullscren, is set fullscreen in init() then place() is evecuted, potentially moving it to a wrong position and potentially even size (which happens with maximiziong placement strategy) so instead of place() the client needs to be explicitly set at fullscreen geometry Test Plan: fullscreen windows always appear with the proper geometry autotests still pass Reviewers: #kwin, #plasma, davidedmundson Reviewed By: #kwin, #plasma, davidedmundson Subscribers: zzag, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D24542 --- autotests/integration/placement_test.cpp | 36 +++++++++++++++++++ autotests/integration/xdgshellclient_test.cpp | 27 ++++++++++++++ xdgshellclient.cpp | 4 +++ 3 files changed, 67 insertions(+) diff --git a/autotests/integration/placement_test.cpp b/autotests/integration/placement_test.cpp index 227d3fc747..0d66113467 100644 --- a/autotests/integration/placement_test.cpp +++ b/autotests/integration/placement_test.cpp @@ -58,6 +58,7 @@ private Q_SLOTS: void testPlaceSmart(); void testPlaceZeroCornered(); void testPlaceMaximized(); + void testPlaceMaximizedLeavesFullscreen(); void testPlaceCentered(); void testPlaceUnderMouse(); void testPlaceCascaded(); @@ -204,6 +205,41 @@ void TestPlacement::testPlaceMaximized() } } +void TestPlacement::testPlaceMaximizedLeavesFullscreen() +{ + setPlacementPolicy(Placement::Maximizing); + + // add a top panel + QScopedPointer panelSurface(Test::createSurface()); + QScopedPointer panelShellSurface(Test::createXdgShellStableSurface(panelSurface.data())); + QScopedPointer plasmaSurface(Test::waylandPlasmaShell()->createSurface(panelSurface.data())); + plasmaSurface->setRole(PlasmaShellSurface::Role::Panel); + plasmaSurface->setPosition(QPoint(0, 0)); + Test::renderAndWaitForShown(panelSurface.data(), QSize(1280, 20), Qt::blue); + + QScopedPointer testParent(new QObject); + + // all windows should be initially fullscreen with an initial configure size sent, despite the policy + for (int i = 0; i < 4; i++) { + auto surface = Test::createSurface(testParent.data()); + auto shellSurface = Test::createXdgShellStableSurface(surface, surface, Test::CreationSetup::CreateOnly); + shellSurface->setFullscreen(true); + QSignalSpy configSpy(shellSurface, &XdgShellSurface::configureRequested); + surface->commit(Surface::CommitFlag::None); + configSpy.wait(); + + auto initiallyConfiguredSize = configSpy[0][0].toSize(); + auto initiallyConfiguredStates = configSpy[0][1].value(); + shellSurface->ackConfigure(configSpy[0][2].toUInt()); + + auto c = Test::renderAndWaitForShown(surface, initiallyConfiguredSize, Qt::red); + + QVERIFY(initiallyConfiguredStates & XdgShellSurface::State::Fullscreen); + QCOMPARE(initiallyConfiguredSize, QSize(1280, 1024 )); + QCOMPARE(c->frameGeometry(), QRect(0, 0, 1280, 1024)); + } +} + void TestPlacement::testPlaceCentered() { // This test verifies that Centered placement policy works. diff --git a/autotests/integration/xdgshellclient_test.cpp b/autotests/integration/xdgshellclient_test.cpp index 82c9e344f1..f9b6d9489d 100644 --- a/autotests/integration/xdgshellclient_test.cpp +++ b/autotests/integration/xdgshellclient_test.cpp @@ -112,6 +112,7 @@ private Q_SLOTS: void testXdgNeverCommitted(); void testXdgInitialState(); void testXdgInitiallyMaximised(); + void testXdgInitiallyFullscreen(); void testXdgInitiallyMinimized(); void testXdgWindowGeometry(); }; @@ -1243,6 +1244,32 @@ void TestXdgShellClient::testXdgInitiallyMaximised() QCOMPARE(c->size(), QSize(1280, 1024)); } +void TestXdgShellClient::testXdgInitiallyFullscreen() +{ + QScopedPointer surface(Test::createSurface()); + QScopedPointer shellSurface(Test::createXdgShellStableSurface(surface.data(), nullptr, Test::CreationSetup::CreateOnly)); + QSignalSpy configureRequestedSpy(shellSurface.data(), &XdgShellSurface::configureRequested); + + shellSurface->setFullscreen(true); + surface->commit(Surface::CommitFlag::None); + + configureRequestedSpy.wait(); + + QCOMPARE(configureRequestedSpy.count(), 1); + + const auto size = configureRequestedSpy.first()[0].value(); + const auto state = configureRequestedSpy.first()[1].value(); + + QCOMPARE(size, QSize(1280, 1024)); + QVERIFY(state & KWayland::Client::XdgShellSurface::State::Fullscreen); + + shellSurface->ackConfigure(configureRequestedSpy.first()[2].toUInt()); + + auto c = Test::renderAndWaitForShown(surface.data(), size, Qt::blue); + QCOMPARE(c->isFullScreen(), true); + QCOMPARE(c->size(), QSize(1280, 1024)); +} + void TestXdgShellClient::testXdgInitiallyMinimized() { QScopedPointer surface(Test::createSurface()); diff --git a/xdgshellclient.cpp b/xdgshellclient.cpp index eaf5e4a091..44538b15eb 100644 --- a/xdgshellclient.cpp +++ b/xdgshellclient.cpp @@ -222,6 +222,10 @@ void XdgShellClient::finishInit() updateWindowRules(Rules::All); } + if (isFullScreen()) { + needsPlacement = false; + } + if (needsPlacement) { const QRect area = workspace()->clientArea(PlacementArea, Screens::self()->current(), desktop()); placeIn(area);