From afe0a5c041161d9fa7d08f8b53fe0e83f04c81ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Fl=C3=B6ser?= Date: Thu, 12 Oct 2017 20:33:30 +0200 Subject: [PATCH] Fix placement of KSplash Summary: In a bug report there was a reference that on multi-screen KSplash is not placed correctly. I investigated and noticed that it is an OSD which sets an own position. In KWin the events were processed correctly but the position was off. The problem is that KWin has code to correct the position of an OSD when it's size changes. This happens also on first damage and then the window gets incorrectly placed when the position is set. So honor that the position is set. Test Plan: Restarted the session, ksplash positioned correctly now. Reviewers: #kwin, #plasma Subscribers: plasma-devel, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D8268 --- abstract_client.cpp | 2 +- abstract_client.h | 4 +++ autotests/integration/plasma_surface_test.cpp | 36 +++++++++++++++++++ shell_client.h | 2 +- 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/abstract_client.cpp b/abstract_client.cpp index 7ee63e6a20..0a56538c47 100644 --- a/abstract_client.cpp +++ b/abstract_client.cpp @@ -76,7 +76,7 @@ AbstractClient::AbstractClient() connect(this, &AbstractClient::geometryShapeChanged, this, [this] (Toplevel *c, const QRect &old) { Q_UNUSED(c) - if (isOnScreenDisplay() && !geometry().isEmpty() && old.size() != geometry().size()) { + if (isOnScreenDisplay() && !geometry().isEmpty() && old.size() != geometry().size() && !isInitialPositionSet()) { GeometryUpdatesBlocker blocker(this); QRect area = workspace()->clientArea(PlacementArea, Screens::self()->current(), desktop()); Placement::self()->place(this, area); diff --git a/abstract_client.h b/abstract_client.h index a6f05caab8..4e1ffd7155 100644 --- a/abstract_client.h +++ b/abstract_client.h @@ -678,6 +678,10 @@ public: bool unresponsive() const; + virtual bool isInitialPositionSet() const { + return false; + } + public Q_SLOTS: virtual void closeWindow() = 0; diff --git a/autotests/integration/plasma_surface_test.cpp b/autotests/integration/plasma_surface_test.cpp index 78ee805bba..5cbc32aa98 100644 --- a/autotests/integration/plasma_surface_test.cpp +++ b/autotests/integration/plasma_surface_test.cpp @@ -57,6 +57,8 @@ private Q_SLOTS: void testPanelWindowsCanCover_data(); void testPanelWindowsCanCover(); void testOSDPlacement(); + void testOSDPlacementManualPosition_data(); + void testOSDPlacementManualPosition(); void testPanelTypeHasStrut_data(); void testPanelTypeHasStrut(); void testPanelActivate_data(); @@ -246,6 +248,40 @@ void PlasmaSurfaceTest::testOSDPlacement() QCOMPARE(c->geometry(), QRect(540, 616, 200, 100)); } +void PlasmaSurfaceTest::testOSDPlacementManualPosition_data() +{ + QTest::addColumn("type"); + + QTest::newRow("wl-shell") << Test::ShellSurfaceType::WlShell; + QTest::newRow("xdgv5") << Test::ShellSurfaceType::XdgShellV5; + QTest::newRow("xdgv6") << Test::ShellSurfaceType::XdgShellV6; +} + +void PlasmaSurfaceTest::testOSDPlacementManualPosition() +{ + QScopedPointer surface(Test::createSurface()); + QVERIFY(!surface.isNull()); + QScopedPointer plasmaSurface(m_plasmaShell->createSurface(surface.data())); + QVERIFY(!plasmaSurface.isNull()); + plasmaSurface->setRole(PlasmaShellSurface::Role::OnScreenDisplay); + + plasmaSurface->setPosition(QPoint(50, 70)); + + QFETCH(Test::ShellSurfaceType, type); + QScopedPointer shellSurface(Test::createShellSurface(type, surface.data())); + QVERIFY(!shellSurface.isNull()); + + // now render and map the window + auto c = Test::renderAndWaitForShown(surface.data(), QSize(100, 50), Qt::blue); + + QVERIFY(c); + QVERIFY(c->isInitialPositionSet()); + QCOMPARE(c->windowType(), NET::OnScreenDisplay); + QVERIFY(c->isOnScreenDisplay()); + QCOMPARE(c->geometry(), QRect(50, 70, 100, 50)); +} + + void PlasmaSurfaceTest::testPanelTypeHasStrut_data() { QTest::addColumn("type"); diff --git a/shell_client.h b/shell_client.h index 517dc91d49..0538e3f2f0 100644 --- a/shell_client.h +++ b/shell_client.h @@ -137,7 +137,7 @@ public: void installQtExtendedSurface(KWayland::Server::QtExtendedSurfaceInterface *surface); void installServerSideDecoration(KWayland::Server::ServerSideDecorationInterface *decoration); - bool isInitialPositionSet() const; + bool isInitialPositionSet() const override; bool isTransient() const override; bool hasTransientPlacementHint() const override;