[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
This commit is contained in:
parent
985601e0a4
commit
efc62941ee
3 changed files with 44 additions and 2 deletions
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue