583 lines
23 KiB
C++
583 lines
23 KiB
C++
/*
|
|
SPDX-FileCopyrightText: 2025 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later
|
|
*/
|
|
#include "kwin_wayland_test.h"
|
|
|
|
#include "core/outputconfiguration.h"
|
|
#include "pointer_input.h"
|
|
#include "virtualdesktops.h"
|
|
#include "wayland_server.h"
|
|
#include "window.h"
|
|
#include "workspace.h"
|
|
|
|
#include <KWayland/Client/connection_thread.h>
|
|
#include <KWayland/Client/output.h>
|
|
#include <KWayland/Client/surface.h>
|
|
|
|
using namespace KWin;
|
|
|
|
static const QString s_socketName = QStringLiteral("wayland_test_kwin_xdgsession-0");
|
|
|
|
class TestXdgSession : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
private Q_SLOTS:
|
|
void initTestCase();
|
|
void init();
|
|
void cleanup();
|
|
|
|
void addToplevelSession();
|
|
void addMappedToplevelSession();
|
|
void restoreToplevelSession();
|
|
void restoreMappedToplevelSession();
|
|
void replaceSession();
|
|
void restorePosition();
|
|
void restoreOffscreenPosition();
|
|
void restoreSize();
|
|
void restoreKeepAbove();
|
|
void restoreKeepBelow();
|
|
void restoreSkipSwitcher();
|
|
void restoreSkipPager();
|
|
void restoreSkipTaskbar();
|
|
void restoreMaximized_data();
|
|
void restoreMaximized();
|
|
void restoreFullScreen();
|
|
void restoreMinimized();
|
|
void restoreNoBorder();
|
|
void restoreShortcut();
|
|
void restoreDesktops();
|
|
void restoreUnknownDesktops();
|
|
|
|
private:
|
|
struct RestoreFuncs
|
|
{
|
|
std::function<void(Window *window)> setup;
|
|
std::function<void()> between;
|
|
std::function<void(Window *window)> restore;
|
|
};
|
|
void restoreTemplate(RestoreFuncs funcs);
|
|
};
|
|
|
|
void TestXdgSession::initTestCase()
|
|
{
|
|
qRegisterMetaType<KWin::Window *>();
|
|
qRegisterMetaType<KWayland::Client::Output *>();
|
|
|
|
qputenv("KWIN_WAYLAND_SUPPORT_XX_SESSION_MANAGER", "1");
|
|
|
|
QVERIFY(waylandServer()->init(s_socketName));
|
|
|
|
kwinApp()->start();
|
|
Test::setOutputConfig({
|
|
Rect(0, 0, 1280, 1024),
|
|
Rect(1280, 0, 1280, 1024),
|
|
});
|
|
const auto outputs = workspace()->outputs();
|
|
QCOMPARE(outputs.count(), 2);
|
|
QCOMPARE(outputs[0]->geometry(), Rect(0, 0, 1280, 1024));
|
|
QCOMPARE(outputs[1]->geometry(), Rect(1280, 0, 1280, 1024));
|
|
}
|
|
|
|
void TestXdgSession::init()
|
|
{
|
|
Test::setOutputConfig({
|
|
Rect(0, 0, 1280, 1024),
|
|
Rect(1280, 0, 1280, 1024),
|
|
});
|
|
|
|
QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::XdgSessionV1));
|
|
workspace()->setActiveOutput(QPoint(640, 512));
|
|
input()->pointer()->warp(QPoint(640, 512));
|
|
|
|
VirtualDesktopManager::self()->setCount(2);
|
|
}
|
|
|
|
void TestXdgSession::cleanup()
|
|
{
|
|
Test::destroyWaylandConnection();
|
|
}
|
|
|
|
void TestXdgSession::addToplevelSession()
|
|
{
|
|
std::unique_ptr<Test::XdgSessionV1> session(Test::createXdgSessionV1(Test::XdgSessionManagerV1::reason_launch));
|
|
QSignalSpy sessionCreatedSpy(session.get(), &Test::XdgSessionV1::created);
|
|
QVERIFY(sessionCreatedSpy.wait());
|
|
|
|
// If the toplevel is added to the session for the first time, we should receive a created event, but no restored event.
|
|
{
|
|
std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface());
|
|
std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get(), Test::CreationSetup::CreateOnly));
|
|
std::unique_ptr<Test::XdgToplevelSessionV1> toplevelSession(session->add(shellSurface.get(), QStringLiteral("foo")));
|
|
|
|
QSignalSpy toplevelSessionRestoredSpy(toplevelSession.get(), &Test::XdgToplevelSessionV1::restored);
|
|
QSignalSpy toplevelConfigureRequestedSpy(shellSurface.get(), &Test::XdgToplevel::configureRequested);
|
|
QSignalSpy surfaceConfigureRequestedSpy(shellSurface->xdgSurface(), &Test::XdgSurface::configureRequested);
|
|
surface->commit(KWayland::Client::Surface::CommitFlag::None);
|
|
QVERIFY(surfaceConfigureRequestedSpy.wait());
|
|
QCOMPARE(sessionCreatedSpy.count(), 1);
|
|
QCOMPARE(toplevelSessionRestoredSpy.count(), 0);
|
|
|
|
shellSurface->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy.first()[0].toUInt());
|
|
auto window = Test::renderAndWaitForShown(surface.get(), QSize(100, 50), Qt::blue);
|
|
shellSurface.reset();
|
|
QVERIFY(Test::waitForWindowClosed(window));
|
|
}
|
|
|
|
// If the toplevel is added to the session again, no created and restored events should be sent.
|
|
{
|
|
std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface());
|
|
std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get(), Test::CreationSetup::CreateOnly));
|
|
std::unique_ptr<Test::XdgToplevelSessionV1> toplevelSession(session->add(shellSurface.get(), QStringLiteral("foo")));
|
|
|
|
QSignalSpy toplevelSessionRestoredSpy(toplevelSession.get(), &Test::XdgToplevelSessionV1::restored);
|
|
QSignalSpy toplevelConfigureRequestedSpy(shellSurface.get(), &Test::XdgToplevel::configureRequested);
|
|
QSignalSpy surfaceConfigureRequestedSpy(shellSurface->xdgSurface(), &Test::XdgSurface::configureRequested);
|
|
surface->commit(KWayland::Client::Surface::CommitFlag::None);
|
|
QVERIFY(surfaceConfigureRequestedSpy.wait());
|
|
QCOMPARE(sessionCreatedSpy.count(), 1);
|
|
QCOMPARE(toplevelSessionRestoredSpy.count(), 0);
|
|
|
|
shellSurface->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy.first()[0].toUInt());
|
|
auto window = Test::renderAndWaitForShown(surface.get(), QSize(100, 50), Qt::blue);
|
|
shellSurface.reset();
|
|
QVERIFY(Test::waitForWindowClosed(window));
|
|
}
|
|
}
|
|
|
|
void TestXdgSession::addMappedToplevelSession()
|
|
{
|
|
// This test verifies that no protocol error will be posted if a mapped toplevel is added to the session.
|
|
|
|
std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface());
|
|
std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get()));
|
|
Test::renderAndWaitForShown(surface.get(), QSize(100, 50), Qt::blue);
|
|
|
|
std::unique_ptr<Test::XdgSessionV1> session(Test::createXdgSessionV1(Test::XdgSessionManagerV1::reason_launch));
|
|
std::unique_ptr<Test::XdgToplevelSessionV1> toplevelSession(session->add(shellSurface.get(), QStringLiteral("foo")));
|
|
|
|
QSignalSpy sessionCreatedSpy(session.get(), &Test::XdgSessionV1::created);
|
|
QSignalSpy toplevelSessionRestoredSpy(toplevelSession.get(), &Test::XdgToplevelSessionV1::restored);
|
|
QVERIFY(sessionCreatedSpy.wait());
|
|
QCOMPARE(sessionCreatedSpy.count(), 1);
|
|
QCOMPARE(toplevelSessionRestoredSpy.count(), 0);
|
|
}
|
|
|
|
void TestXdgSession::restoreToplevelSession()
|
|
{
|
|
std::unique_ptr<Test::XdgSessionV1> session(Test::createXdgSessionV1(Test::XdgSessionManagerV1::reason_launch));
|
|
QSignalSpy sessionCreatedSpy(session.get(), &Test::XdgSessionV1::created);
|
|
QVERIFY(sessionCreatedSpy.wait());
|
|
|
|
// Add the toplevel to the session.
|
|
{
|
|
std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface());
|
|
std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get(), Test::CreationSetup::CreateOnly));
|
|
std::unique_ptr<Test::XdgToplevelSessionV1> toplevelSession(session->add(shellSurface.get(), QStringLiteral("foo")));
|
|
|
|
QSignalSpy toplevelSessionRestoredSpy(toplevelSession.get(), &Test::XdgToplevelSessionV1::restored);
|
|
QSignalSpy toplevelConfigureRequestedSpy(shellSurface.get(), &Test::XdgToplevel::configureRequested);
|
|
QSignalSpy surfaceConfigureRequestedSpy(shellSurface->xdgSurface(), &Test::XdgSurface::configureRequested);
|
|
surface->commit(KWayland::Client::Surface::CommitFlag::None);
|
|
QVERIFY(surfaceConfigureRequestedSpy.wait());
|
|
QCOMPARE(toplevelSessionRestoredSpy.count(), 0);
|
|
|
|
shellSurface->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy.first()[0].toUInt());
|
|
auto window = Test::renderAndWaitForShown(surface.get(), QSize(100, 50), Qt::blue);
|
|
shellSurface.reset();
|
|
QVERIFY(Test::waitForWindowClosed(window));
|
|
}
|
|
|
|
// Restore the toplevel session.
|
|
{
|
|
std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface());
|
|
std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get(), Test::CreationSetup::CreateOnly));
|
|
std::unique_ptr<Test::XdgToplevelSessionV1> toplevelSession(session->restore(shellSurface.get(), QStringLiteral("foo")));
|
|
|
|
QSignalSpy toplevelSessionRestoredSpy(toplevelSession.get(), &Test::XdgToplevelSessionV1::restored);
|
|
QSignalSpy toplevelConfigureRequestedSpy(shellSurface.get(), &Test::XdgToplevel::configureRequested);
|
|
QSignalSpy surfaceConfigureRequestedSpy(shellSurface->xdgSurface(), &Test::XdgSurface::configureRequested);
|
|
surface->commit(KWayland::Client::Surface::CommitFlag::None);
|
|
QVERIFY(surfaceConfigureRequestedSpy.wait());
|
|
QCOMPARE(toplevelSessionRestoredSpy.count(), 1);
|
|
|
|
shellSurface->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy.first()[0].toUInt());
|
|
auto window = Test::renderAndWaitForShown(surface.get(), QSize(100, 50), Qt::blue);
|
|
shellSurface.reset();
|
|
QVERIFY(Test::waitForWindowClosed(window));
|
|
}
|
|
|
|
// Restore a toplevel session that does not exist in the session storage.
|
|
{
|
|
std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface());
|
|
std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get(), Test::CreationSetup::CreateOnly));
|
|
std::unique_ptr<Test::XdgToplevelSessionV1> toplevelSession(session->restore(shellSurface.get(), QStringLiteral("bar")));
|
|
|
|
QSignalSpy toplevelSessionRestoredSpy(toplevelSession.get(), &Test::XdgToplevelSessionV1::restored);
|
|
QSignalSpy toplevelConfigureRequestedSpy(shellSurface.get(), &Test::XdgToplevel::configureRequested);
|
|
QSignalSpy surfaceConfigureRequestedSpy(shellSurface->xdgSurface(), &Test::XdgSurface::configureRequested);
|
|
surface->commit(KWayland::Client::Surface::CommitFlag::None);
|
|
QVERIFY(surfaceConfigureRequestedSpy.wait());
|
|
QCOMPARE(toplevelSessionRestoredSpy.count(), 0);
|
|
|
|
shellSurface->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy.first()[0].toUInt());
|
|
auto window = Test::renderAndWaitForShown(surface.get(), QSize(100, 50), Qt::blue);
|
|
shellSurface.reset();
|
|
QVERIFY(Test::waitForWindowClosed(window));
|
|
}
|
|
}
|
|
|
|
void TestXdgSession::restoreMappedToplevelSession()
|
|
{
|
|
// This test verifies that a protocol error will be posted if a client attempts to restore a mapped toplevel.
|
|
|
|
std::unique_ptr<Test::XdgSessionV1> session(Test::createXdgSessionV1(Test::XdgSessionManagerV1::reason_launch));
|
|
QSignalSpy sessionCreatedSpy(session.get(), &Test::XdgSessionV1::created);
|
|
QVERIFY(sessionCreatedSpy.wait());
|
|
|
|
std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface());
|
|
std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get()));
|
|
Test::renderAndWaitForShown(surface.get(), QSize(100, 50), Qt::blue);
|
|
|
|
std::unique_ptr<Test::XdgToplevelSessionV1> toplevelSession(session->restore(shellSurface.get(), QStringLiteral("foo")));
|
|
|
|
QSignalSpy connectionErrorSpy(Test::waylandConnection(), &KWayland::Client::ConnectionThread::errorOccurred);
|
|
QVERIFY(connectionErrorSpy.wait());
|
|
}
|
|
|
|
void TestXdgSession::replaceSession()
|
|
{
|
|
// A naughty client attempts to create a session twice -> a protocol error and lots of spanking.
|
|
{
|
|
auto connection = Test::Connection::setup(Test::AdditionalWaylandInterface::XdgSessionV1);
|
|
|
|
std::unique_ptr<Test::XdgSessionV1> firstSession = Test::createXdgSessionV1(connection->sessionManager.get(), Test::XdgSessionManagerV1::reason_launch);
|
|
QSignalSpy sessionCreatedSpy(firstSession.get(), &Test::XdgSessionV1::created);
|
|
QVERIFY(sessionCreatedSpy.wait());
|
|
|
|
const QString sessionId = sessionCreatedSpy.last().at(0).toString();
|
|
std::unique_ptr<Test::XdgSessionV1> secondSession = Test::createXdgSessionV1(connection->sessionManager.get(), Test::XdgSessionManagerV1::reason_launch, sessionId);
|
|
QSignalSpy connectionErrorSpy(connection->connection, &KWayland::Client::ConnectionThread::errorOccurred);
|
|
QVERIFY(connectionErrorSpy.wait());
|
|
}
|
|
|
|
// A client creates a session that's in use by another client -> send the replaced event to the other client.
|
|
{
|
|
auto firstConnection = Test::Connection::setup(Test::AdditionalWaylandInterface::XdgSessionV1);
|
|
auto secondConnection = Test::Connection::setup(Test::AdditionalWaylandInterface::XdgSessionV1);
|
|
|
|
std::unique_ptr<Test::XdgSessionV1> firstSession = Test::createXdgSessionV1(firstConnection->sessionManager.get(), Test::XdgSessionManagerV1::reason_launch);
|
|
QSignalSpy firstSessionCreatedSpy(firstSession.get(), &Test::XdgSessionV1::created);
|
|
QSignalSpy firstSessionReplacedSpy(firstSession.get(), &Test::XdgSessionV1::replaced);
|
|
QVERIFY(firstSessionCreatedSpy.wait());
|
|
QCOMPARE(firstSessionReplacedSpy.count(), 0);
|
|
QCOMPARE(firstSessionReplacedSpy.count(), 0);
|
|
|
|
const QString sessionId = firstSessionCreatedSpy.last().at(0).toString();
|
|
std::unique_ptr<Test::XdgSessionV1> secondSession = Test::createXdgSessionV1(secondConnection->sessionManager.get(), Test::XdgSessionManagerV1::reason_launch, sessionId);
|
|
QSignalSpy secondSessionCreatedSpy(secondSession.get(), &Test::XdgSessionV1::created);
|
|
QSignalSpy secondSessionReplacedSpy(secondSession.get(), &Test::XdgSessionV1::replaced);
|
|
QVERIFY(secondSessionCreatedSpy.wait());
|
|
QCOMPARE(secondSessionReplacedSpy.count(), 0);
|
|
|
|
// The first and the second connection can process events in different order, the sync is needed
|
|
// to guarantee that the first connection has processed all events before checking the signal spies.
|
|
// Without the sync, the test will be flaky.
|
|
QVERIFY(firstConnection->sync());
|
|
QCOMPARE(firstSessionCreatedSpy.count(), 1);
|
|
QCOMPARE(firstSessionReplacedSpy.count(), 1);
|
|
}
|
|
}
|
|
|
|
void TestXdgSession::restoreTemplate(RestoreFuncs funcs)
|
|
{
|
|
std::unique_ptr<Test::XdgSessionV1> session(Test::createXdgSessionV1(Test::XdgSessionManagerV1::reason_launch));
|
|
QSignalSpy sessionCreatedSpy(session.get(), &Test::XdgSessionV1::created);
|
|
QVERIFY(sessionCreatedSpy.wait());
|
|
|
|
{
|
|
std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface());
|
|
std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get(), Test::CreationSetup::CreateOnly));
|
|
std::unique_ptr<Test::XdgToplevelSessionV1> toplevelSession(session->add(shellSurface.get(), QStringLiteral("foo")));
|
|
|
|
QSignalSpy toplevelSessionRestoredSpy(toplevelSession.get(), &Test::XdgToplevelSessionV1::restored);
|
|
QSignalSpy toplevelConfigureRequestedSpy(shellSurface.get(), &Test::XdgToplevel::configureRequested);
|
|
QSignalSpy surfaceConfigureRequestedSpy(shellSurface->xdgSurface(), &Test::XdgSurface::configureRequested);
|
|
surface->commit(KWayland::Client::Surface::CommitFlag::None);
|
|
QVERIFY(surfaceConfigureRequestedSpy.wait());
|
|
QCOMPARE(toplevelSessionRestoredSpy.count(), 0);
|
|
|
|
const QSize surfaceSize = toplevelConfigureRequestedSpy.last().at(0).toSize();
|
|
shellSurface->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy.first()[0].toUInt());
|
|
auto window = Test::renderAndWaitForShown(surface.get(), surfaceSize.isEmpty() ? QSize(100, 50) : surfaceSize, Qt::blue);
|
|
|
|
funcs.setup(window);
|
|
|
|
shellSurface.reset();
|
|
QVERIFY(Test::waitForWindowClosed(window));
|
|
}
|
|
|
|
if (funcs.between) {
|
|
funcs.between();
|
|
}
|
|
|
|
{
|
|
std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface());
|
|
std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get(), Test::CreationSetup::CreateOnly));
|
|
std::unique_ptr<Test::XdgToplevelSessionV1> toplevelSession(session->restore(shellSurface.get(), QStringLiteral("foo")));
|
|
|
|
QSignalSpy toplevelSessionRestoredSpy(toplevelSession.get(), &Test::XdgToplevelSessionV1::restored);
|
|
QSignalSpy toplevelConfigureRequestedSpy(shellSurface.get(), &Test::XdgToplevel::configureRequested);
|
|
QSignalSpy surfaceConfigureRequestedSpy(shellSurface->xdgSurface(), &Test::XdgSurface::configureRequested);
|
|
surface->commit(KWayland::Client::Surface::CommitFlag::None);
|
|
QVERIFY(surfaceConfigureRequestedSpy.wait());
|
|
QCOMPARE(toplevelSessionRestoredSpy.count(), 1);
|
|
|
|
const QSize surfaceSize = toplevelConfigureRequestedSpy.last().at(0).toSize();
|
|
shellSurface->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy.first()[0].toUInt());
|
|
auto window = Test::renderAndWaitForShown(surface.get(), surfaceSize.isEmpty() ? QSize(100, 50) : surfaceSize, Qt::blue);
|
|
|
|
funcs.restore(window);
|
|
|
|
shellSurface.reset();
|
|
QVERIFY(Test::waitForWindowClosed(window));
|
|
}
|
|
}
|
|
|
|
void TestXdgSession::restorePosition()
|
|
{
|
|
restoreTemplate({
|
|
.setup = [](Window *window) {
|
|
window->move(QPointF(42, 84));
|
|
},
|
|
.restore = [](Window *window) {
|
|
QCOMPARE(window->pos(), QPointF(42, 84));
|
|
},
|
|
});
|
|
}
|
|
|
|
void TestXdgSession::restoreOffscreenPosition()
|
|
{
|
|
const auto outputs = workspace()->outputs();
|
|
|
|
restoreTemplate({
|
|
.setup = [outputs](Window *window) {
|
|
QCOMPARE(outputs[1]->geometry(), Rect(1280, 0, 1280, 1024));
|
|
window->move(QPointF(1280 + 42, 42));
|
|
QCOMPARE(window->output(), outputs[1]);
|
|
},
|
|
.between = [outputs]() {
|
|
OutputConfiguration configuration;
|
|
{
|
|
auto changeSet = configuration.changeSet(outputs[1]->backendOutput());
|
|
changeSet->enabled = false;
|
|
}
|
|
workspace()->applyOutputConfiguration(configuration);
|
|
},
|
|
.restore = [outputs](Window *window) {
|
|
QCOMPARE(window->pos(), QPointF(0, 0));
|
|
QCOMPARE(window->output(), outputs[0]);
|
|
},
|
|
});
|
|
}
|
|
|
|
void TestXdgSession::restoreSize()
|
|
{
|
|
restoreTemplate({
|
|
.setup = [](Window *window) {
|
|
window->resize(QSizeF(300, 250));
|
|
},
|
|
.restore = [](Window *window) {
|
|
QCOMPARE(window->size(), QSizeF(300, 250));
|
|
},
|
|
});
|
|
}
|
|
|
|
void TestXdgSession::restoreKeepAbove()
|
|
{
|
|
restoreTemplate({
|
|
.setup = [](Window *window) {
|
|
window->setKeepAbove(true);
|
|
},
|
|
.restore = [](Window *window) {
|
|
QVERIFY(window->keepAbove());
|
|
},
|
|
});
|
|
}
|
|
|
|
void TestXdgSession::restoreKeepBelow()
|
|
{
|
|
restoreTemplate({
|
|
.setup = [](Window *window) {
|
|
window->setKeepBelow(true);
|
|
},
|
|
.restore = [](Window *window) {
|
|
QVERIFY(window->keepBelow());
|
|
},
|
|
});
|
|
}
|
|
|
|
void TestXdgSession::restoreSkipSwitcher()
|
|
{
|
|
restoreTemplate({
|
|
.setup = [](Window *window) {
|
|
window->setSkipSwitcher(true);
|
|
},
|
|
.restore = [](Window *window) {
|
|
QVERIFY(window->skipSwitcher());
|
|
},
|
|
});
|
|
}
|
|
|
|
void TestXdgSession::restoreSkipPager()
|
|
{
|
|
restoreTemplate({
|
|
.setup = [](Window *window) {
|
|
window->setSkipPager(true);
|
|
},
|
|
.restore = [](Window *window) {
|
|
QVERIFY(window->skipPager());
|
|
},
|
|
});
|
|
}
|
|
|
|
void TestXdgSession::restoreSkipTaskbar()
|
|
{
|
|
restoreTemplate({
|
|
.setup = [](Window *window) {
|
|
window->setSkipTaskbar(true);
|
|
},
|
|
.restore = [](Window *window) {
|
|
QVERIFY(window->skipTaskbar());
|
|
},
|
|
});
|
|
}
|
|
|
|
void TestXdgSession::restoreMaximized_data()
|
|
{
|
|
QTest::addColumn<MaximizeMode>("maximizeMode");
|
|
|
|
QTest::addRow("none") << MaximizeMode::MaximizeRestore;
|
|
QTest::addRow("horizontal") << MaximizeMode::MaximizeHorizontal;
|
|
QTest::addRow("vertical") << MaximizeMode::MaximizeVertical;
|
|
QTest::addRow("full") << MaximizeMode::MaximizeFull;
|
|
}
|
|
|
|
void TestXdgSession::restoreMaximized()
|
|
{
|
|
QFETCH(MaximizeMode, maximizeMode);
|
|
restoreTemplate({
|
|
.setup = [maximizeMode](Window *window) {
|
|
window->maximize(maximizeMode);
|
|
},
|
|
.restore = [maximizeMode](Window *window) {
|
|
QCOMPARE(window->maximizeMode(), maximizeMode);
|
|
QCOMPARE(window->requestedMaximizeMode(), maximizeMode);
|
|
},
|
|
});
|
|
}
|
|
|
|
void TestXdgSession::restoreFullScreen()
|
|
{
|
|
restoreTemplate({
|
|
.setup = [](Window *window) {
|
|
window->setFullScreen(true);
|
|
},
|
|
.restore = [](Window *window) {
|
|
QVERIFY(window->isFullScreen());
|
|
QVERIFY(window->isRequestedFullScreen());
|
|
},
|
|
});
|
|
}
|
|
|
|
void TestXdgSession::restoreMinimized()
|
|
{
|
|
restoreTemplate({
|
|
.setup = [](Window *window) {
|
|
window->setMinimized(true);
|
|
},
|
|
.restore = [](Window *window) {
|
|
QVERIFY(window->isMinimized());
|
|
},
|
|
});
|
|
}
|
|
|
|
void TestXdgSession::restoreNoBorder()
|
|
{
|
|
restoreTemplate({
|
|
.setup = [](Window *window) {
|
|
window->setNoBorder(true);
|
|
},
|
|
.restore = [](Window *window) {
|
|
QVERIFY(window->noBorder());
|
|
},
|
|
});
|
|
}
|
|
|
|
void TestXdgSession::restoreShortcut()
|
|
{
|
|
restoreTemplate({
|
|
.setup = [](Window *window) {
|
|
window->setShortcut(QStringLiteral("Ctrl+Meta+T"));
|
|
},
|
|
.restore = [](Window *window) {
|
|
QCOMPARE(window->shortcut(), QKeySequence(Qt::ControlModifier | Qt::MetaModifier | Qt::Key_T));
|
|
},
|
|
});
|
|
}
|
|
|
|
void TestXdgSession::restoreDesktops()
|
|
{
|
|
const auto desktops = VirtualDesktopManager::self()->desktops();
|
|
restoreTemplate({
|
|
.setup = [desktops](Window *window) {
|
|
QVERIFY(window->isOnDesktop(desktops[0]));
|
|
QVERIFY(!window->isOnDesktop(desktops[1]));
|
|
window->setDesktops({desktops[1]});
|
|
},
|
|
.restore = [desktops](Window *window) {
|
|
QVERIFY(!window->isOnDesktop(desktops[0]));
|
|
QVERIFY(window->isOnDesktop(desktops[1]));
|
|
},
|
|
});
|
|
}
|
|
|
|
void TestXdgSession::restoreUnknownDesktops()
|
|
{
|
|
auto vds = VirtualDesktopManager::self();
|
|
vds->setCount(3);
|
|
|
|
// The window is on desktops 2 and 3. If desktop 3 is removed, the window should be restored only on desktop 2.
|
|
const auto desktops = VirtualDesktopManager::self()->desktops();
|
|
restoreTemplate({
|
|
.setup = [desktops](Window *window) {
|
|
window->setDesktops({desktops[1], desktops[2]});
|
|
},
|
|
.between = [vds, desktops]() {
|
|
vds->removeVirtualDesktop(desktops[2]);
|
|
},
|
|
.restore = [desktops](Window *window) {
|
|
QCOMPARE(window->desktops(), (QList<VirtualDesktop *>{desktops[1]}));
|
|
},
|
|
});
|
|
|
|
// The window is on desktop 2. If desktop 2 is removed, the window should be restored only on desktop 1,
|
|
// it should not be displayed on all desktops.
|
|
restoreTemplate({
|
|
.setup = [desktops](Window *window) {
|
|
window->setDesktops({desktops[1]});
|
|
},
|
|
.between = [vds, desktops]() {
|
|
vds->removeVirtualDesktop(desktops[1]);
|
|
},
|
|
.restore = [desktops](Window *window) {
|
|
QCOMPARE(window->desktops(), (QList<VirtualDesktop *>{desktops[0]}));
|
|
},
|
|
});
|
|
}
|
|
|
|
WAYLANDTEST_MAIN(TestXdgSession)
|
|
#include "xdgsession_test.moc"
|