diff --git a/autotests/wayland/quick_tiling_test.cpp b/autotests/wayland/quick_tiling_test.cpp
index fde6d90172..1e3677a6d2 100644
--- a/autotests/wayland/quick_tiling_test.cpp
+++ b/autotests/wayland/quick_tiling_test.cpp
@@ -34,6 +34,7 @@ along with this program. If not, see .
#include
Q_DECLARE_METATYPE(KWin::AbstractClient::QuickTileMode)
+Q_DECLARE_METATYPE(KWin::MaximizeMode)
namespace KWin
{
@@ -49,6 +50,8 @@ private Q_SLOTS:
void cleanup();
void testQuickTiling_data();
void testQuickTiling();
+ void testQuickMaximizing_data();
+ void testQuickMaximizing();
private:
KWayland::Client::ConnectionThread *m_connection = nullptr;
@@ -62,6 +65,8 @@ private:
void QuickTilingTest::initTestCase()
{
qRegisterMetaType();
+ qRegisterMetaType();
+ qRegisterMetaType("MaximizeMode");
QSignalSpy workspaceCreatedSpy(kwinApp(), &Application::workspaceCreated);
QVERIFY(workspaceCreatedSpy.isValid());
waylandServer()->backend()->setInitialWindowSize(QSize(1280, 1024));
@@ -153,6 +158,8 @@ void QuickTilingTest::testQuickTiling_data()
QTest::newRow("bottom left") << (FLAG(Left) | FLAG(Bottom)) << QRect(0, 512, 640, 512);
QTest::newRow("bottom right") << (FLAG(Right) | FLAG(Bottom)) << QRect(640, 512, 640, 512);
+ QTest::newRow("maximize") << FLAG(Maximize) << QRect(0, 0, 1280, 1024);
+
#undef FLAG
}
@@ -216,6 +223,125 @@ void QuickTilingTest::testQuickTiling()
QCOMPARE(c->geometry(), expectedGeometry);
}
+void QuickTilingTest::testQuickMaximizing_data()
+{
+ QTest::addColumn("mode");
+
+#define FLAG(name) AbstractClient::QuickTileMode(AbstractClient::QuickTile##name)
+
+ QTest::newRow("maximize") << FLAG(Maximize);
+ QTest::newRow("none") << FLAG(None);
+
+#undef FLAG
+}
+
+void QuickTilingTest::testQuickMaximizing()
+{
+ using namespace KWayland::Client;
+
+ QSignalSpy clientAddedSpy(waylandServer(), &WaylandServer::shellClientAdded);
+ QVERIFY(clientAddedSpy.isValid());
+
+ QScopedPointer surface(m_compositor->createSurface());
+ QVERIFY(!surface.isNull());
+
+ QScopedPointer shellSurface(m_shell->createSurface(surface.data()));
+ QVERIFY(!shellSurface.isNull());
+ QSignalSpy sizeChangeSpy(shellSurface.data(), &ShellSurface::sizeChanged);
+ QVERIFY(sizeChangeSpy.isValid());
+ // let's render
+ QImage img(QSize(100, 50), QImage::Format_ARGB32);
+ img.fill(Qt::blue);
+ surface->attachBuffer(m_shm->createBuffer(img));
+ surface->damage(QRect(0, 0, 100, 50));
+ surface->commit(Surface::CommitFlag::None);
+
+ m_connection->flush();
+ QVERIFY(clientAddedSpy.wait());
+ AbstractClient *c = workspace()->activeClient();
+ QVERIFY(c);
+ QCOMPARE(clientAddedSpy.first().first().value(), c);
+ QCOMPARE(c->geometry(), QRect(0, 0, 100, 50));
+ QCOMPARE(c->quickTileMode(), AbstractClient::QuickTileNone);
+ QCOMPARE(c->maximizeMode(), MaximizeRestore);
+ QSignalSpy quickTileChangedSpy(c, &AbstractClient::quickTileModeChanged);
+ QVERIFY(quickTileChangedSpy.isValid());
+ QSignalSpy geometryChangedSpy(c, &AbstractClient::geometryChanged);
+ QVERIFY(geometryChangedSpy.isValid());
+ QSignalSpy maximizeChangedSpy1(c, SIGNAL(clientMaximizedStateChanged(KWin::AbstractClient*,MaximizeMode)));
+ QVERIFY(maximizeChangedSpy1.isValid());
+ QSignalSpy maximizeChangedSpy2(c, SIGNAL(clientMaximizedStateChanged(KWin::AbstractClient*,bool,bool)));
+ QVERIFY(maximizeChangedSpy2.isValid());
+
+ c->setQuickTileMode(AbstractClient::QuickTileMaximize, true);
+ QCOMPARE(quickTileChangedSpy.count(), 1);
+ QCOMPARE(maximizeChangedSpy1.count(), 1);
+ QCOMPARE(maximizeChangedSpy1.first().first().value(), c);
+ QCOMPARE(maximizeChangedSpy1.first().last().value(), MaximizeFull);
+ QCOMPARE(maximizeChangedSpy2.count(), 1);
+ QCOMPARE(maximizeChangedSpy2.first().first().value(), c);
+ QCOMPARE(maximizeChangedSpy2.first().at(1).toBool(), true);
+ QCOMPARE(maximizeChangedSpy2.first().at(2).toBool(), true);
+ // at this point the geometry did not yet change
+ QCOMPARE(c->geometry(), QRect(0, 0, 100, 50));
+ // but quick tile mode already changed
+ QCOMPARE(c->quickTileMode(), AbstractClient::QuickTileMaximize);
+ QCOMPARE(c->maximizeMode(), MaximizeFull);
+ QCOMPARE(c->geometryRestore(), QRect(0, 0, 100, 50));
+
+ // but we got requested a new geometry
+ QVERIFY(sizeChangeSpy.wait());
+ QCOMPARE(sizeChangeSpy.count(), 1);
+ QCOMPARE(sizeChangeSpy.first().first().toSize(), QSize(1280, 1024));
+
+ // attach a new image
+ img = QImage(QSize(1280, 1024), QImage::Format_ARGB32);
+ img.fill(Qt::red);
+ surface->attachBuffer(m_shm->createBuffer(img));
+ surface->damage(QRect(0, 0, 1280, 1024));
+ surface->commit(Surface::CommitFlag::None);
+ m_connection->flush();
+
+ QVERIFY(geometryChangedSpy.wait());
+ QCOMPARE(geometryChangedSpy.count(), 1);
+ QCOMPARE(c->geometry(), QRect(0, 0, 1280, 1024));
+ QCOMPARE(c->geometryRestore(), QRect(0, 0, 100, 50));
+
+ // go back to quick tile none
+ QFETCH(AbstractClient::QuickTileMode, mode);
+ c->setQuickTileMode(mode, true);
+ QCOMPARE(quickTileChangedSpy.count(), 2);
+ QCOMPARE(maximizeChangedSpy1.count(), 2);
+ QCOMPARE(maximizeChangedSpy1.last().first().value(), c);
+ QCOMPARE(maximizeChangedSpy1.last().last().value(), MaximizeRestore);
+ QCOMPARE(maximizeChangedSpy2.count(), 2);
+ QCOMPARE(maximizeChangedSpy2.last().first().value(), c);
+ QCOMPARE(maximizeChangedSpy2.last().at(1).toBool(), false);
+ QCOMPARE(maximizeChangedSpy2.last().at(2).toBool(), false);
+ QCOMPARE(c->quickTileMode(), AbstractClient::QuickTileNone);
+ QCOMPARE(c->maximizeMode(), MaximizeRestore);
+ // geometry not yet changed
+ QCOMPARE(c->geometry(), QRect(0, 0, 1280, 1024));
+ QCOMPARE(c->geometryRestore(), QRect(0, 0, 100, 50));
+ // we got requested a new geometry
+ QVERIFY(sizeChangeSpy.wait());
+ QCOMPARE(sizeChangeSpy.count(), 2);
+ QCOMPARE(sizeChangeSpy.last().first().toSize(), QSize(100, 50));
+
+ // render again
+ img = QImage(QSize(100, 50), QImage::Format_ARGB32);
+ img.fill(Qt::yellow);
+ surface->attachBuffer(m_shm->createBuffer(img));
+ surface->damage(QRect(0, 0, 100, 50));
+ surface->commit(Surface::CommitFlag::None);
+ m_connection->flush();
+
+ QVERIFY(geometryChangedSpy.wait());
+ QCOMPARE(geometryChangedSpy.count(), 2);
+ QCOMPARE(c->geometry(), QRect(0, 0, 100, 50));
+ QCOMPARE(c->geometryRestore(), QRect(0, 0, 100, 50));
+}
+
}
WAYLANTEST_MAIN(KWin::QuickTilingTest)
diff --git a/shell_client.cpp b/shell_client.cpp
index 24f2ce98a5..242885b4c6 100644
--- a/shell_client.cpp
+++ b/shell_client.cpp
@@ -267,6 +267,13 @@ void ShellClient::doSetGeometry(const QRect &rect)
}
const QRect old = geom;
geom = rect;
+
+ if (m_unmapped && m_geomMaximizeRestore.isEmpty() && !geom.isEmpty()) {
+ // use first valid geometry as restore geometry
+ // TODO: needs to interact with placing. The first valid geometry should be the placed one
+ m_geomMaximizeRestore = geom;
+ }
+
if (!m_unmapped) {
addWorkspaceRepaint(visibleRect());
}