[wayland] Place all toplevels before the first configure

Summary:
Currently popups get positioned once at the initial configure, to set
the correct size and again when they are mapped.

Toplevels are currently only positioned when they are mapped. This works
for all cases where the the toplevel defines its own size, but not if
the window should have an initial size set by the placement strategy or
window rules. Most notably the maximised placement strategy used on
plasma mobile.

Being out of sync and resizing later currently causes a positioning bug
when plasma mobile is used with XdgShell.

This patch repositions all top levels that don't have a position set
through the plasma interface.

Test Plan: Relevant unit test

Reviewers: #kwin, bshah

Reviewed By: bshah

Subscribers: zzag, bshah, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D20241
icc-effect-5.17.5
David Edmundson 2019-04-09 11:15:02 +01:00
parent 985601e0a4
commit efc62941ee
3 changed files with 44 additions and 2 deletions

View File

@ -31,6 +31,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <KWayland/Client/surface.h>
#include <KWayland/Client/server_decoration.h>
#include <KWayland/Client/xdgdecoration.h>
#include <KWayland/Client/xdgshell.h>
#include <KWayland/Client/plasmashell.h>
#include <KWayland/Server/shell_interface.h>
#include <KWayland/Server/xdgdecoration_interface.h>
@ -55,6 +57,7 @@ private Q_SLOTS:
void testInitiallyMaximized();
void testBorderlessMaximizedWindow();
void testBorderlessMaximizedWindowNoClientSideDecoration();
void testMaximizePlacementStrategy();
};
void TestMaximized::initTestCase()
@ -80,7 +83,8 @@ void TestMaximized::initTestCase()
void TestMaximized::init()
{
QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Decoration |
Test::AdditionalWaylandInterface::XdgDecoration));
Test::AdditionalWaylandInterface::XdgDecoration |
Test::AdditionalWaylandInterface::PlasmaShell));
screens()->setCurrent(0);
KWin::Cursor::setPos(QPoint(1280, 512));
@ -294,5 +298,39 @@ void TestMaximized::testBorderlessMaximizedWindowNoClientSideDecoration()
QCOMPARE(deco->mode(), XdgDecoration::Mode::ServerSide);
}
void TestMaximized::testMaximizePlacementStrategy()
{
// adjust config
auto group = kwinApp()->config()->group("Windows");
group.writeEntry("Placement", "Maximizing");
group.sync();
Workspace::self()->slotReconfigure();
// add a top panel
QScopedPointer<Surface> panelSurface(Test::createSurface());
QScopedPointer<QObject> panelShellSurface(Test::createXdgShellStableSurface(panelSurface.data()));
QScopedPointer<PlasmaShellSurface> 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);
// create a new window - it should be maximised on the first configure and positioned beneath the strut
QScopedPointer<Surface> surface(Test::createSurface());
auto shellSurface = Test::createXdgShellStableSurface(surface.data(), surface.data(), Test::CreationSetup::CreateOnly);
QSignalSpy configSpy(shellSurface, &XdgShellSurface::configureRequested);
surface->commit(Surface::CommitFlag::None);
QVERIFY(configSpy.wait());
const auto size = configSpy[0][0].toSize();
const auto states = configSpy[0][1].value<KWayland::Client::XdgShellSurface::States>();
QVERIFY(states & XdgShellSurface::State::Maximized);
shellSurface->ackConfigure(configSpy[0][2].toUInt());
QCOMPARE(size, QSize(1280, 1024 - 20));
auto c = Test::renderAndWaitForShown(surface.data(), size, Qt::red);
QVERIFY(c);
QCOMPARE(c->geometry(), QRect(0, 20, 1280, 1024 - 20));
}
WAYLANDTEST_MAIN(TestMaximized)
#include "maximize_test.moc"

View File

@ -376,6 +376,10 @@ QPoint Workspace::cascadeOffset(const AbstractClient *c) const
**/
void Placement::placeCascaded(AbstractClient* c, QRect& area, Policy nextPlacement)
{
if (!c->size().isValid()) {
return;
}
/* cascadePlacement by Cristian Tibirna (tibirna@kde.org) (30Jan98)
*/
// work coords

View File

@ -372,7 +372,7 @@ void ShellClient::finishInit() {
SurfaceInterface *s = surface();
disconnect(s, &SurfaceInterface::committed, this, &ShellClient::finishInit);
if (m_xdgShellPopup) {
if (!isInitialPositionSet()) {
QRect area = workspace()->clientArea(PlacementArea, Screens::self()->current(), desktop());
placeIn(area);
}