diff --git a/autotests/integration/maximize_test.cpp b/autotests/integration/maximize_test.cpp --- a/autotests/integration/maximize_test.cpp +++ b/autotests/integration/maximize_test.cpp @@ -30,8 +30,10 @@ #include #include #include +#include #include +#include #include #include @@ -52,6 +54,7 @@ void testMaximizedPassedToDeco(); void testInitiallyMaximized(); void testBorderlessMaximizedWindow(); + void testBorderlessMaximizedWindowNoClientSideDecoration(); }; void TestMaximized::initTestCase() @@ -76,7 +79,8 @@ void TestMaximized::init() { - QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Decoration)); + QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Decoration | + Test::AdditionalWaylandInterface::XdgDecoration)); screens()->setCurrent(0); KWin::Cursor::setPos(QPoint(1280, 512)); @@ -224,5 +228,72 @@ QCOMPARE(client->isDecorated(), true); } +void TestMaximized::testBorderlessMaximizedWindowNoClientSideDecoration() +{ + // test case verifies that borderless maximized windows doesn't cause + // clients to render client-side decorations instead (BUG 405385) + + // adjust config + auto group = kwinApp()->config()->group("Windows"); + group.writeEntry("BorderlessMaximizedWindows", true); + group.sync(); + Workspace::self()->slotReconfigure(); + QCOMPARE(options->borderlessMaximizedWindows(), true); + + QScopedPointer surface(Test::createSurface()); + QScopedPointer xdgShellSurface(Test::createXdgShellStableSurface(surface.data())); + QScopedPointer deco(Test::xdgDecorationManager()->getToplevelDecoration(xdgShellSurface.data())); + + QSignalSpy decorationConfiguredSpy(deco.data(), &XdgDecoration::modeChanged); + QVERIFY(decorationConfiguredSpy.isValid()); + + auto client = Test::renderAndWaitForShown(surface.data(), QSize(100, 50), Qt::blue); + + QSignalSpy geometryChangedSpy(client, &ShellClient::geometryChanged); + QVERIFY(geometryChangedSpy.isValid()); + QSignalSpy sizeChangeRequestedSpy(xdgShellSurface.data(), &XdgShellSurface::sizeChanged); + QVERIFY(sizeChangeRequestedSpy.isValid()); + QSignalSpy configureRequestedSpy(xdgShellSurface.data(), &XdgShellSurface::configureRequested); + QVERIFY(configureRequestedSpy.isValid()); + + QVERIFY(client->isDecorated()); + QVERIFY(!client->noBorder()); + configureRequestedSpy.wait(); + QCOMPARE(decorationConfiguredSpy.count(), 1); + QCOMPARE(deco->mode(), XdgDecoration::Mode::ServerSide); + + // go to maximized + xdgShellSurface->setMaximized(true); + QVERIFY(sizeChangeRequestedSpy.wait()); + QCOMPARE(sizeChangeRequestedSpy.count(), 1); + + for (const auto &it: configureRequestedSpy) { + xdgShellSurface->ackConfigure(it[2].toInt()); + } + Test::render(surface.data(), sizeChangeRequestedSpy.last().first().toSize(), Qt::red); + QVERIFY(geometryChangedSpy.wait()); + + // no deco + QVERIFY(!client->isDecorated()); + QVERIFY(client->noBorder()); + // but still server-side + QCOMPARE(deco->mode(), XdgDecoration::Mode::ServerSide); + + // go back to normal + xdgShellSurface->setMaximized(false); + QVERIFY(sizeChangeRequestedSpy.wait()); + QCOMPARE(sizeChangeRequestedSpy.count(), 2); + + for (const auto &it: configureRequestedSpy) { + xdgShellSurface->ackConfigure(it[2].toInt()); + } + Test::render(surface.data(), sizeChangeRequestedSpy.last().first().toSize(), Qt::red); + QVERIFY(geometryChangedSpy.wait()); + + QVERIFY(client->isDecorated()); + QVERIFY(!client->noBorder()); + QCOMPARE(deco->mode(), XdgDecoration::Mode::ServerSide); +} + WAYLANDTEST_MAIN(TestMaximized) #include "maximize_test.moc" diff --git a/shell_client.cpp b/shell_client.cpp --- a/shell_client.cpp +++ b/shell_client.cpp @@ -579,7 +579,7 @@ m_serverDecoration->setMode(KWayland::Server::ServerSideDecorationManagerInterface::Mode::Server); } if (m_xdgDecoration) { - auto mode = isDecorated() ? XdgDecorationInterface::Mode::ServerSide: XdgDecorationInterface::Mode::ClientSide; + auto mode = isDecorated() || m_userNoBorder ? XdgDecorationInterface::Mode::ServerSide: XdgDecorationInterface::Mode::ClientSide; m_xdgDecoration->configure(mode); m_xdgShellSurface->configure(xdgSurfaceStates(), m_requestedClientSize); }