Commit efc62941 authored by David Edmundson's avatar David Edmundson

[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
parent 985601e0
......@@ -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"
......@@ -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
......
......@@ -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);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment