2020-08-07 19:01:42 +00:00
|
|
|
/*
|
|
|
|
SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
|
|
|
|
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "kwin_wayland_test.h"
|
2022-03-23 10:13:38 +00:00
|
|
|
|
2020-08-07 19:01:42 +00:00
|
|
|
#include "main.h"
|
2022-04-14 12:33:28 +00:00
|
|
|
#include "output.h"
|
2020-08-07 19:01:42 +00:00
|
|
|
#include "platform.h"
|
|
|
|
#include "wayland_server.h"
|
2022-04-22 17:39:12 +00:00
|
|
|
#include "window.h"
|
2020-08-07 19:01:42 +00:00
|
|
|
#include "workspace.h"
|
|
|
|
|
|
|
|
#include <KWayland/Client/output.h>
|
|
|
|
#include <KWayland/Client/surface.h>
|
|
|
|
|
|
|
|
Q_DECLARE_METATYPE(QMargins)
|
|
|
|
Q_DECLARE_METATYPE(KWin::Layer)
|
|
|
|
|
|
|
|
namespace KWin
|
|
|
|
{
|
|
|
|
|
2022-04-22 17:46:41 +00:00
|
|
|
static const QString s_socketName = QStringLiteral("wayland_test_kwin_layershellv1window-0");
|
2020-08-07 19:01:42 +00:00
|
|
|
|
2022-04-22 17:46:41 +00:00
|
|
|
class LayerShellV1WindowTest : public QObject
|
2020-08-07 19:01:42 +00:00
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
private Q_SLOTS:
|
|
|
|
void initTestCase();
|
|
|
|
void init();
|
|
|
|
void cleanup();
|
|
|
|
void testOutput_data();
|
|
|
|
void testOutput();
|
|
|
|
void testAnchor_data();
|
|
|
|
void testAnchor();
|
|
|
|
void testMargins_data();
|
|
|
|
void testMargins();
|
|
|
|
void testLayer_data();
|
|
|
|
void testLayer();
|
|
|
|
void testPlacementArea_data();
|
|
|
|
void testPlacementArea();
|
|
|
|
void testFill_data();
|
|
|
|
void testFill();
|
|
|
|
void testStack();
|
|
|
|
void testFocus();
|
|
|
|
void testActivate_data();
|
|
|
|
void testActivate();
|
|
|
|
void testUnmap();
|
|
|
|
};
|
|
|
|
|
2022-04-22 17:46:41 +00:00
|
|
|
void LayerShellV1WindowTest::initTestCase()
|
2020-08-07 19:01:42 +00:00
|
|
|
{
|
|
|
|
QSignalSpy applicationStartedSpy(kwinApp(), &Application::started);
|
|
|
|
QVERIFY(applicationStartedSpy.isValid());
|
|
|
|
kwinApp()->platform()->setInitialWindowSize(QSize(1280, 1024));
|
2020-12-09 13:06:15 +00:00
|
|
|
QVERIFY(waylandServer()->init(s_socketName));
|
2020-08-07 19:01:42 +00:00
|
|
|
QMetaObject::invokeMethod(kwinApp()->platform(), "setVirtualOutputs", Qt::DirectConnection, Q_ARG(int, 2));
|
|
|
|
|
|
|
|
kwinApp()->start();
|
|
|
|
QVERIFY(applicationStartedSpy.wait());
|
2021-08-31 07:03:05 +00:00
|
|
|
const auto outputs = kwinApp()->platform()->enabledOutputs();
|
|
|
|
QCOMPARE(outputs.count(), 2);
|
|
|
|
QCOMPARE(outputs[0]->geometry(), QRect(0, 0, 1280, 1024));
|
|
|
|
QCOMPARE(outputs[1]->geometry(), QRect(1280, 0, 1280, 1024));
|
2021-05-08 00:08:22 +00:00
|
|
|
Test::initWaylandWorkspace();
|
2020-08-07 19:01:42 +00:00
|
|
|
}
|
|
|
|
|
2022-04-22 17:46:41 +00:00
|
|
|
void LayerShellV1WindowTest::init()
|
2020-08-07 19:01:42 +00:00
|
|
|
{
|
|
|
|
QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::LayerShellV1));
|
|
|
|
|
2021-08-28 18:58:29 +00:00
|
|
|
workspace()->setActiveOutput(QPoint(640, 512));
|
2020-08-07 19:01:42 +00:00
|
|
|
Cursors::self()->mouse()->setPos(QPoint(640, 512));
|
|
|
|
}
|
|
|
|
|
2022-04-22 17:46:41 +00:00
|
|
|
void LayerShellV1WindowTest::cleanup()
|
2020-08-07 19:01:42 +00:00
|
|
|
{
|
|
|
|
Test::destroyWaylandConnection();
|
|
|
|
}
|
|
|
|
|
2022-04-22 17:46:41 +00:00
|
|
|
void LayerShellV1WindowTest::testOutput_data()
|
2020-08-07 19:01:42 +00:00
|
|
|
{
|
|
|
|
QTest::addColumn<int>("screenId");
|
|
|
|
|
2022-03-23 10:13:38 +00:00
|
|
|
QTest::addRow("first output") << 0;
|
2020-08-07 19:01:42 +00:00
|
|
|
QTest::addRow("second output") << 1;
|
|
|
|
}
|
|
|
|
|
2022-04-22 17:46:41 +00:00
|
|
|
void LayerShellV1WindowTest::testOutput()
|
2020-08-07 19:01:42 +00:00
|
|
|
{
|
|
|
|
// Fetch the wl_output object.
|
|
|
|
QFETCH(int, screenId);
|
|
|
|
KWayland::Client::Output *output = Test::waylandOutputs().value(screenId);
|
|
|
|
QVERIFY(output);
|
|
|
|
|
|
|
|
// Create a layer shell surface.
|
|
|
|
QScopedPointer<KWayland::Client::Surface> surface(Test::createSurface());
|
|
|
|
QScopedPointer<Test::LayerSurfaceV1> shellSurface(Test::createLayerSurfaceV1(surface.data(), QStringLiteral("test"), output));
|
|
|
|
|
|
|
|
// Set the initial state of the layer surface.
|
|
|
|
shellSurface->set_size(280, 124);
|
|
|
|
surface->commit(KWayland::Client::Surface::CommitFlag::None);
|
|
|
|
|
|
|
|
// Wait for the compositor to position the surface.
|
|
|
|
QSignalSpy configureRequestedSpy(shellSurface.data(), &Test::LayerSurfaceV1::configureRequested);
|
|
|
|
QVERIFY(configureRequestedSpy.isValid());
|
|
|
|
QVERIFY(configureRequestedSpy.wait());
|
|
|
|
const QSize requestedSize = configureRequestedSpy.last().at(1).toSize();
|
|
|
|
|
|
|
|
// Map the layer surface.
|
|
|
|
shellSurface->ack_configure(configureRequestedSpy.last().at(0).toUInt());
|
2022-04-22 17:39:12 +00:00
|
|
|
Window *client = Test::renderAndWaitForShown(surface.data(), requestedSize, Qt::red);
|
2020-08-07 19:01:42 +00:00
|
|
|
QVERIFY(client);
|
|
|
|
|
|
|
|
// Verify that the client is on the requested screen.
|
|
|
|
QVERIFY(output->geometry().contains(client->frameGeometry()));
|
|
|
|
|
|
|
|
// Destroy the client.
|
|
|
|
shellSurface.reset();
|
|
|
|
QVERIFY(Test::waitForWindowDestroyed(client));
|
|
|
|
}
|
|
|
|
|
2022-04-22 17:46:41 +00:00
|
|
|
void LayerShellV1WindowTest::testAnchor_data()
|
2020-08-07 19:01:42 +00:00
|
|
|
{
|
|
|
|
QTest::addColumn<int>("anchor");
|
|
|
|
QTest::addColumn<QRect>("expectedGeometry");
|
|
|
|
|
2022-03-23 10:13:38 +00:00
|
|
|
QTest::addRow("left") << int(Test::LayerSurfaceV1::anchor_left)
|
|
|
|
<< QRect(0, 450, 280, 124);
|
2020-08-07 19:01:42 +00:00
|
|
|
|
2022-03-23 10:13:38 +00:00
|
|
|
QTest::addRow("top left") << (Test::LayerSurfaceV1::anchor_top | Test::LayerSurfaceV1::anchor_left)
|
|
|
|
<< QRect(0, 0, 280, 124);
|
2020-08-07 19:01:42 +00:00
|
|
|
|
2022-03-23 10:13:38 +00:00
|
|
|
QTest::addRow("top") << int(Test::LayerSurfaceV1::anchor_top)
|
|
|
|
<< QRect(500, 0, 280, 124);
|
2020-08-07 19:01:42 +00:00
|
|
|
|
2022-03-23 10:13:38 +00:00
|
|
|
QTest::addRow("top right") << (Test::LayerSurfaceV1::anchor_top | Test::LayerSurfaceV1::anchor_right)
|
|
|
|
<< QRect(1000, 0, 280, 124);
|
2020-08-07 19:01:42 +00:00
|
|
|
|
2022-03-23 10:13:38 +00:00
|
|
|
QTest::addRow("right") << int(Test::LayerSurfaceV1::anchor_right)
|
|
|
|
<< QRect(1000, 450, 280, 124);
|
2020-08-07 19:01:42 +00:00
|
|
|
|
2022-03-23 10:13:38 +00:00
|
|
|
QTest::addRow("bottom right") << (Test::LayerSurfaceV1::anchor_bottom | Test::LayerSurfaceV1::anchor_right)
|
2020-08-07 19:01:42 +00:00
|
|
|
<< QRect(1000, 900, 280, 124);
|
|
|
|
|
2022-03-23 10:13:38 +00:00
|
|
|
QTest::addRow("bottom") << int(Test::LayerSurfaceV1::anchor_bottom)
|
|
|
|
<< QRect(500, 900, 280, 124);
|
2020-08-07 19:01:42 +00:00
|
|
|
|
2022-03-23 10:13:38 +00:00
|
|
|
QTest::addRow("bottom left") << (Test::LayerSurfaceV1::anchor_bottom | Test::LayerSurfaceV1::anchor_left)
|
|
|
|
<< QRect(0, 900, 280, 124);
|
2020-08-07 19:01:42 +00:00
|
|
|
}
|
|
|
|
|
2022-04-22 17:46:41 +00:00
|
|
|
void LayerShellV1WindowTest::testAnchor()
|
2020-08-07 19:01:42 +00:00
|
|
|
{
|
|
|
|
// Create a layer shell surface.
|
|
|
|
QScopedPointer<KWayland::Client::Surface> surface(Test::createSurface());
|
|
|
|
QScopedPointer<Test::LayerSurfaceV1> shellSurface(Test::createLayerSurfaceV1(surface.data(), QStringLiteral("test")));
|
|
|
|
|
|
|
|
// Set the initial state of the layer surface.
|
|
|
|
QFETCH(int, anchor);
|
|
|
|
shellSurface->set_anchor(anchor);
|
|
|
|
shellSurface->set_size(280, 124);
|
|
|
|
surface->commit(KWayland::Client::Surface::CommitFlag::None);
|
|
|
|
|
|
|
|
// Wait for the compositor to position the surface.
|
|
|
|
QSignalSpy configureRequestedSpy(shellSurface.data(), &Test::LayerSurfaceV1::configureRequested);
|
|
|
|
QVERIFY(configureRequestedSpy.isValid());
|
|
|
|
QVERIFY(configureRequestedSpy.wait());
|
|
|
|
const QSize requestedSize = configureRequestedSpy.last().at(1).toSize();
|
|
|
|
QCOMPARE(requestedSize, QSize(280, 124));
|
|
|
|
|
|
|
|
// Map the layer surface.
|
|
|
|
shellSurface->ack_configure(configureRequestedSpy.last().at(0).toUInt());
|
2022-04-22 17:39:12 +00:00
|
|
|
Window *client = Test::renderAndWaitForShown(surface.data(), QSize(280, 124), Qt::red);
|
2020-08-07 19:01:42 +00:00
|
|
|
QVERIFY(client);
|
|
|
|
|
|
|
|
// Verify that the client is placed at expected location.
|
|
|
|
QTEST(client->frameGeometry(), "expectedGeometry");
|
|
|
|
|
|
|
|
// Destroy the client.
|
|
|
|
shellSurface.reset();
|
|
|
|
QVERIFY(Test::waitForWindowDestroyed(client));
|
|
|
|
}
|
|
|
|
|
2022-04-22 17:46:41 +00:00
|
|
|
void LayerShellV1WindowTest::testMargins_data()
|
2020-08-07 19:01:42 +00:00
|
|
|
{
|
|
|
|
QTest::addColumn<int>("anchor");
|
|
|
|
QTest::addColumn<QMargins>("margins");
|
|
|
|
QTest::addColumn<QRect>("expectedGeometry");
|
|
|
|
|
2022-03-23 10:13:38 +00:00
|
|
|
QTest::addRow("left") << int(Test::LayerSurfaceV1::anchor_left)
|
|
|
|
<< QMargins(100, 0, 0, 0)
|
|
|
|
<< QRect(100, 450, 280, 124);
|
2020-08-07 19:01:42 +00:00
|
|
|
|
2022-03-23 10:13:38 +00:00
|
|
|
QTest::addRow("top left") << (Test::LayerSurfaceV1::anchor_top | Test::LayerSurfaceV1::anchor_left)
|
|
|
|
<< QMargins(100, 200, 0, 0)
|
|
|
|
<< QRect(100, 200, 280, 124);
|
2020-08-07 19:01:42 +00:00
|
|
|
|
2022-03-23 10:13:38 +00:00
|
|
|
QTest::addRow("top") << int(Test::LayerSurfaceV1::anchor_top)
|
|
|
|
<< QMargins(0, 200, 0, 0)
|
|
|
|
<< QRect(500, 200, 280, 124);
|
2020-08-07 19:01:42 +00:00
|
|
|
|
2022-03-23 10:13:38 +00:00
|
|
|
QTest::addRow("top right") << (Test::LayerSurfaceV1::anchor_top | Test::LayerSurfaceV1::anchor_right)
|
|
|
|
<< QMargins(0, 200, 300, 0)
|
|
|
|
<< QRect(700, 200, 280, 124);
|
2020-08-07 19:01:42 +00:00
|
|
|
|
2022-03-23 10:13:38 +00:00
|
|
|
QTest::addRow("right") << int(Test::LayerSurfaceV1::anchor_right)
|
|
|
|
<< QMargins(0, 0, 300, 0)
|
|
|
|
<< QRect(700, 450, 280, 124);
|
2020-08-07 19:01:42 +00:00
|
|
|
|
2022-03-23 10:13:38 +00:00
|
|
|
QTest::addRow("bottom right") << (Test::LayerSurfaceV1::anchor_bottom | Test::LayerSurfaceV1::anchor_right)
|
2020-08-07 19:01:42 +00:00
|
|
|
<< QMargins(0, 0, 300, 400)
|
|
|
|
<< QRect(700, 500, 280, 124);
|
|
|
|
|
2022-03-23 10:13:38 +00:00
|
|
|
QTest::addRow("bottom") << int(Test::LayerSurfaceV1::anchor_bottom)
|
|
|
|
<< QMargins(0, 0, 0, 400)
|
|
|
|
<< QRect(500, 500, 280, 124);
|
2020-08-07 19:01:42 +00:00
|
|
|
|
2022-03-23 10:13:38 +00:00
|
|
|
QTest::addRow("bottom left") << (Test::LayerSurfaceV1::anchor_bottom | Test::LayerSurfaceV1::anchor_left)
|
|
|
|
<< QMargins(100, 0, 0, 400)
|
|
|
|
<< QRect(100, 500, 280, 124);
|
2020-08-07 19:01:42 +00:00
|
|
|
}
|
|
|
|
|
2022-04-22 17:46:41 +00:00
|
|
|
void LayerShellV1WindowTest::testMargins()
|
2020-08-07 19:01:42 +00:00
|
|
|
{
|
|
|
|
// Create a layer shell surface.
|
|
|
|
QScopedPointer<KWayland::Client::Surface> surface(Test::createSurface());
|
|
|
|
QScopedPointer<Test::LayerSurfaceV1> shellSurface(Test::createLayerSurfaceV1(surface.data(), QStringLiteral("test")));
|
|
|
|
|
|
|
|
// Set the initial state of the layer surface.
|
|
|
|
QFETCH(QMargins, margins);
|
|
|
|
QFETCH(int, anchor);
|
|
|
|
shellSurface->set_anchor(anchor);
|
|
|
|
shellSurface->set_margin(margins.top(), margins.right(), margins.bottom(), margins.left());
|
|
|
|
shellSurface->set_size(280, 124);
|
|
|
|
surface->commit(KWayland::Client::Surface::CommitFlag::None);
|
|
|
|
|
|
|
|
// Wait for the compositor to position the surface.
|
|
|
|
QSignalSpy configureRequestedSpy(shellSurface.data(), &Test::LayerSurfaceV1::configureRequested);
|
|
|
|
QVERIFY(configureRequestedSpy.isValid());
|
|
|
|
QVERIFY(configureRequestedSpy.wait());
|
|
|
|
const QSize requestedSize = configureRequestedSpy.last().at(1).toSize();
|
|
|
|
|
|
|
|
// Map the layer surface.
|
|
|
|
shellSurface->ack_configure(configureRequestedSpy.last().at(0).toUInt());
|
2022-04-22 17:39:12 +00:00
|
|
|
Window *client = Test::renderAndWaitForShown(surface.data(), requestedSize, Qt::red);
|
2020-08-07 19:01:42 +00:00
|
|
|
QVERIFY(client);
|
|
|
|
|
|
|
|
// Verify that the client is placed at expected location.
|
|
|
|
QTEST(client->frameGeometry(), "expectedGeometry");
|
|
|
|
|
|
|
|
// Destroy the client.
|
|
|
|
shellSurface.reset();
|
|
|
|
QVERIFY(Test::waitForWindowDestroyed(client));
|
|
|
|
}
|
|
|
|
|
2022-04-22 17:46:41 +00:00
|
|
|
void LayerShellV1WindowTest::testLayer_data()
|
2020-08-07 19:01:42 +00:00
|
|
|
{
|
|
|
|
QTest::addColumn<int>("protocolLayer");
|
|
|
|
QTest::addColumn<Layer>("compositorLayer");
|
|
|
|
|
2022-03-23 10:13:38 +00:00
|
|
|
QTest::addRow("overlay") << int(Test::LayerShellV1::layer_overlay) << UnmanagedLayer;
|
|
|
|
QTest::addRow("top") << int(Test::LayerShellV1::layer_top) << AboveLayer;
|
|
|
|
QTest::addRow("bottom") << int(Test::LayerShellV1::layer_bottom) << BelowLayer;
|
2020-08-07 19:01:42 +00:00
|
|
|
QTest::addRow("background") << int(Test::LayerShellV1::layer_background) << DesktopLayer;
|
|
|
|
}
|
|
|
|
|
2022-04-22 17:46:41 +00:00
|
|
|
void LayerShellV1WindowTest::testLayer()
|
2020-08-07 19:01:42 +00:00
|
|
|
{
|
|
|
|
// Create a layer shell surface.
|
|
|
|
QScopedPointer<KWayland::Client::Surface> surface(Test::createSurface());
|
|
|
|
QScopedPointer<Test::LayerSurfaceV1> shellSurface(Test::createLayerSurfaceV1(surface.data(), QStringLiteral("test")));
|
|
|
|
|
|
|
|
// Set the initial state of the layer surface.
|
|
|
|
QFETCH(int, protocolLayer);
|
|
|
|
shellSurface->set_layer(protocolLayer);
|
|
|
|
shellSurface->set_size(280, 124);
|
|
|
|
surface->commit(KWayland::Client::Surface::CommitFlag::None);
|
|
|
|
|
|
|
|
// Wait for the compositor to position the surface.
|
|
|
|
QSignalSpy configureRequestedSpy(shellSurface.data(), &Test::LayerSurfaceV1::configureRequested);
|
|
|
|
QVERIFY(configureRequestedSpy.isValid());
|
|
|
|
QVERIFY(configureRequestedSpy.wait());
|
|
|
|
const QSize requestedSize = configureRequestedSpy.last().at(1).toSize();
|
|
|
|
|
|
|
|
// Map the layer surface.
|
|
|
|
shellSurface->ack_configure(configureRequestedSpy.last().at(0).toUInt());
|
2022-04-22 17:39:12 +00:00
|
|
|
Window *client = Test::renderAndWaitForShown(surface.data(), requestedSize, Qt::red);
|
2020-08-07 19:01:42 +00:00
|
|
|
QVERIFY(client);
|
|
|
|
|
|
|
|
// Verify that the client is placed at expected location.
|
|
|
|
QTEST(client->layer(), "compositorLayer");
|
|
|
|
|
|
|
|
// Destroy the client.
|
|
|
|
shellSurface.reset();
|
|
|
|
QVERIFY(Test::waitForWindowDestroyed(client));
|
|
|
|
}
|
|
|
|
|
2022-04-22 17:46:41 +00:00
|
|
|
void LayerShellV1WindowTest::testPlacementArea_data()
|
2020-08-07 19:01:42 +00:00
|
|
|
{
|
|
|
|
QTest::addColumn<int>("anchor");
|
|
|
|
QTest::addColumn<int>("exclusiveZone");
|
|
|
|
QTest::addColumn<QRect>("placementArea");
|
|
|
|
|
2022-03-23 10:13:38 +00:00
|
|
|
QTest::addRow("left") << int(Test::LayerSurfaceV1::anchor_left) << 300 << QRect(300, 0, 980, 1024);
|
|
|
|
QTest::addRow("top") << int(Test::LayerSurfaceV1::anchor_top) << 300 << QRect(0, 300, 1280, 724);
|
|
|
|
QTest::addRow("right") << int(Test::LayerSurfaceV1::anchor_right) << 300 << QRect(0, 0, 980, 1024);
|
2020-08-07 19:01:42 +00:00
|
|
|
QTest::addRow("bottom") << int(Test::LayerSurfaceV1::anchor_bottom) << 300 << QRect(0, 0, 1280, 724);
|
|
|
|
}
|
|
|
|
|
2022-04-22 17:46:41 +00:00
|
|
|
void LayerShellV1WindowTest::testPlacementArea()
|
2020-08-07 19:01:42 +00:00
|
|
|
{
|
|
|
|
// Create a layer shell surface.
|
|
|
|
QScopedPointer<KWayland::Client::Surface> surface(Test::createSurface());
|
|
|
|
QScopedPointer<Test::LayerSurfaceV1> shellSurface(Test::createLayerSurfaceV1(surface.data(), QStringLiteral("test")));
|
|
|
|
|
|
|
|
// Set the initial state of the layer surface.
|
|
|
|
QFETCH(int, anchor);
|
|
|
|
QFETCH(int, exclusiveZone);
|
|
|
|
shellSurface->set_anchor(anchor);
|
|
|
|
shellSurface->set_exclusive_zone(exclusiveZone);
|
|
|
|
shellSurface->set_size(280, 124);
|
|
|
|
surface->commit(KWayland::Client::Surface::CommitFlag::None);
|
|
|
|
|
|
|
|
// Wait for the compositor to position the surface.
|
|
|
|
QSignalSpy configureRequestedSpy(shellSurface.data(), &Test::LayerSurfaceV1::configureRequested);
|
|
|
|
QVERIFY(configureRequestedSpy.isValid());
|
|
|
|
QVERIFY(configureRequestedSpy.wait());
|
|
|
|
const QSize requestedSize = configureRequestedSpy.last().at(1).toSize();
|
|
|
|
|
|
|
|
// Map the layer surface.
|
|
|
|
shellSurface->ack_configure(configureRequestedSpy.last().at(0).toUInt());
|
2022-04-22 17:39:12 +00:00
|
|
|
Window *client = Test::renderAndWaitForShown(surface.data(), requestedSize, Qt::red);
|
2020-08-07 19:01:42 +00:00
|
|
|
QVERIFY(client);
|
|
|
|
|
|
|
|
// Verify that the work area has been adjusted.
|
|
|
|
QTEST(workspace()->clientArea(PlacementArea, client), "placementArea");
|
|
|
|
|
|
|
|
// Destroy the client.
|
|
|
|
shellSurface.reset();
|
|
|
|
QVERIFY(Test::waitForWindowDestroyed(client));
|
|
|
|
}
|
|
|
|
|
2022-04-22 17:46:41 +00:00
|
|
|
void LayerShellV1WindowTest::testFill_data()
|
2020-08-07 19:01:42 +00:00
|
|
|
{
|
|
|
|
QTest::addColumn<int>("anchor");
|
|
|
|
QTest::addColumn<QSize>("desiredSize");
|
|
|
|
QTest::addColumn<QRect>("expectedGeometry");
|
|
|
|
|
2022-03-23 10:13:38 +00:00
|
|
|
QTest::addRow("horizontal") << (Test::LayerSurfaceV1::anchor_left | Test::LayerSurfaceV1::anchor_right)
|
2020-08-07 19:01:42 +00:00
|
|
|
<< QSize(0, 124)
|
|
|
|
<< QRect(0, 450, 1280, 124);
|
|
|
|
|
2022-03-23 10:13:38 +00:00
|
|
|
QTest::addRow("vertical") << (Test::LayerSurfaceV1::anchor_top | Test::LayerSurfaceV1::anchor_bottom)
|
|
|
|
<< QSize(280, 0)
|
|
|
|
<< QRect(500, 0, 280, 1024);
|
|
|
|
|
|
|
|
QTest::addRow("all") << (Test::LayerSurfaceV1::anchor_left | Test::LayerSurfaceV1::anchor_top | Test::LayerSurfaceV1::anchor_right | Test::LayerSurfaceV1::anchor_bottom)
|
|
|
|
<< QSize(0, 0)
|
|
|
|
<< QRect(0, 0, 1280, 1024);
|
2020-08-07 19:01:42 +00:00
|
|
|
}
|
|
|
|
|
2022-04-22 17:46:41 +00:00
|
|
|
void LayerShellV1WindowTest::testFill()
|
2020-08-07 19:01:42 +00:00
|
|
|
{
|
|
|
|
// Create a layer shell surface.
|
|
|
|
QScopedPointer<KWayland::Client::Surface> surface(Test::createSurface());
|
|
|
|
QScopedPointer<Test::LayerSurfaceV1> shellSurface(Test::createLayerSurfaceV1(surface.data(), QStringLiteral("test")));
|
|
|
|
|
|
|
|
// Set the initial state of the layer surface.
|
|
|
|
QFETCH(int, anchor);
|
|
|
|
QFETCH(QSize, desiredSize);
|
|
|
|
shellSurface->set_anchor(anchor);
|
|
|
|
shellSurface->set_size(desiredSize.width(), desiredSize.height());
|
|
|
|
surface->commit(KWayland::Client::Surface::CommitFlag::None);
|
|
|
|
|
|
|
|
// Wait for the compositor to position the surface.
|
|
|
|
QSignalSpy configureRequestedSpy(shellSurface.data(), &Test::LayerSurfaceV1::configureRequested);
|
|
|
|
QVERIFY(configureRequestedSpy.isValid());
|
|
|
|
QVERIFY(configureRequestedSpy.wait());
|
|
|
|
const QSize requestedSize = configureRequestedSpy.last().at(1).toSize();
|
|
|
|
|
|
|
|
// Map the layer surface.
|
|
|
|
shellSurface->ack_configure(configureRequestedSpy.last().at(0).toUInt());
|
2022-04-22 17:39:12 +00:00
|
|
|
Window *client = Test::renderAndWaitForShown(surface.data(), requestedSize, Qt::red);
|
2020-08-07 19:01:42 +00:00
|
|
|
QVERIFY(client);
|
|
|
|
|
|
|
|
// Verify that the client is placed at expected location.
|
|
|
|
QTEST(client->frameGeometry(), "expectedGeometry");
|
|
|
|
|
|
|
|
// Destroy the client.
|
|
|
|
shellSurface.reset();
|
|
|
|
QVERIFY(Test::waitForWindowDestroyed(client));
|
|
|
|
}
|
|
|
|
|
2022-04-22 17:46:41 +00:00
|
|
|
void LayerShellV1WindowTest::testStack()
|
2020-08-07 19:01:42 +00:00
|
|
|
{
|
|
|
|
// Create a layer shell surface.
|
|
|
|
QScopedPointer<KWayland::Client::Surface> surface1(Test::createSurface());
|
|
|
|
QScopedPointer<Test::LayerSurfaceV1> shellSurface1(Test::createLayerSurfaceV1(surface1.data(), QStringLiteral("test")));
|
|
|
|
|
|
|
|
QScopedPointer<KWayland::Client::Surface> surface2(Test::createSurface());
|
|
|
|
QScopedPointer<Test::LayerSurfaceV1> shellSurface2(Test::createLayerSurfaceV1(surface2.data(), QStringLiteral("test")));
|
|
|
|
|
|
|
|
// Set the initial state of the layer surface.
|
|
|
|
shellSurface1->set_anchor(Test::LayerSurfaceV1::anchor_left);
|
|
|
|
shellSurface1->set_size(80, 124);
|
|
|
|
shellSurface1->set_exclusive_zone(80);
|
|
|
|
surface1->commit(KWayland::Client::Surface::CommitFlag::None);
|
|
|
|
|
|
|
|
shellSurface2->set_anchor(Test::LayerSurfaceV1::anchor_left);
|
|
|
|
shellSurface2->set_size(200, 124);
|
|
|
|
shellSurface2->set_exclusive_zone(200);
|
|
|
|
surface2->commit(KWayland::Client::Surface::CommitFlag::None);
|
|
|
|
|
|
|
|
// Wait for the compositor to position the surfaces.
|
|
|
|
QSignalSpy configureRequestedSpy1(shellSurface1.data(), &Test::LayerSurfaceV1::configureRequested);
|
|
|
|
QSignalSpy configureRequestedSpy2(shellSurface2.data(), &Test::LayerSurfaceV1::configureRequested);
|
|
|
|
QVERIFY(configureRequestedSpy2.wait());
|
|
|
|
const QSize requestedSize1 = configureRequestedSpy1.last().at(1).toSize();
|
|
|
|
const QSize requestedSize2 = configureRequestedSpy2.last().at(1).toSize();
|
|
|
|
|
|
|
|
// Map the layer surface.
|
|
|
|
shellSurface1->ack_configure(configureRequestedSpy1.last().at(0).toUInt());
|
2022-04-22 17:39:12 +00:00
|
|
|
Window *client1 = Test::renderAndWaitForShown(surface1.data(), requestedSize1, Qt::red);
|
2020-08-07 19:01:42 +00:00
|
|
|
QVERIFY(client1);
|
|
|
|
|
|
|
|
shellSurface2->ack_configure(configureRequestedSpy2.last().at(0).toUInt());
|
2022-04-22 17:39:12 +00:00
|
|
|
Window *client2 = Test::renderAndWaitForShown(surface2.data(), requestedSize2, Qt::red);
|
2020-08-07 19:01:42 +00:00
|
|
|
QVERIFY(client2);
|
|
|
|
|
|
|
|
// Check that the second layer surface is placed next to the first.
|
|
|
|
QCOMPARE(client1->frameGeometry(), QRect(0, 450, 80, 124));
|
|
|
|
QCOMPARE(client2->frameGeometry(), QRect(80, 450, 200, 124));
|
|
|
|
|
|
|
|
// Check that the work area has been adjusted accordingly.
|
|
|
|
QCOMPARE(workspace()->clientArea(PlacementArea, client1), QRect(280, 0, 1000, 1024));
|
|
|
|
QCOMPARE(workspace()->clientArea(PlacementArea, client2), QRect(280, 0, 1000, 1024));
|
|
|
|
|
|
|
|
// Destroy the client.
|
|
|
|
shellSurface1.reset();
|
|
|
|
QVERIFY(Test::waitForWindowDestroyed(client1));
|
|
|
|
shellSurface2.reset();
|
|
|
|
QVERIFY(Test::waitForWindowDestroyed(client2));
|
|
|
|
}
|
|
|
|
|
2022-04-22 17:46:41 +00:00
|
|
|
void LayerShellV1WindowTest::testFocus()
|
2020-08-07 19:01:42 +00:00
|
|
|
{
|
|
|
|
// Create a layer shell surface.
|
|
|
|
QScopedPointer<KWayland::Client::Surface> surface(Test::createSurface());
|
|
|
|
QScopedPointer<Test::LayerSurfaceV1> shellSurface(Test::createLayerSurfaceV1(surface.data(), QStringLiteral("test")));
|
|
|
|
|
|
|
|
// Set the initial state of the layer surface.
|
|
|
|
shellSurface->set_keyboard_interactivity(1);
|
|
|
|
shellSurface->set_size(280, 124);
|
|
|
|
surface->commit(KWayland::Client::Surface::CommitFlag::None);
|
|
|
|
|
|
|
|
// Wait for the compositor to position the surface.
|
|
|
|
QSignalSpy configureRequestedSpy(shellSurface.data(), &Test::LayerSurfaceV1::configureRequested);
|
|
|
|
QVERIFY(configureRequestedSpy.isValid());
|
|
|
|
QVERIFY(configureRequestedSpy.wait());
|
|
|
|
const QSize requestedSize = configureRequestedSpy.last().at(1).toSize();
|
|
|
|
|
|
|
|
// Map the layer surface.
|
|
|
|
shellSurface->ack_configure(configureRequestedSpy.last().at(0).toUInt());
|
2022-04-22 17:39:12 +00:00
|
|
|
Window *client = Test::renderAndWaitForShown(surface.data(), requestedSize, Qt::red);
|
2020-08-07 19:01:42 +00:00
|
|
|
QVERIFY(client);
|
|
|
|
|
|
|
|
// The layer surface must be focused when it's mapped.
|
|
|
|
QVERIFY(client->isActive());
|
|
|
|
|
|
|
|
// Destroy the client.
|
|
|
|
shellSurface.reset();
|
|
|
|
QVERIFY(Test::waitForWindowDestroyed(client));
|
|
|
|
}
|
|
|
|
|
2022-04-22 17:46:41 +00:00
|
|
|
void LayerShellV1WindowTest::testActivate_data()
|
2020-08-07 19:01:42 +00:00
|
|
|
{
|
|
|
|
QTest::addColumn<int>("layer");
|
|
|
|
QTest::addColumn<bool>("active");
|
|
|
|
|
2022-03-23 10:13:38 +00:00
|
|
|
QTest::addRow("overlay") << int(Test::LayerShellV1::layer_overlay) << true;
|
|
|
|
QTest::addRow("top") << int(Test::LayerShellV1::layer_top) << true;
|
|
|
|
QTest::addRow("bottom") << int(Test::LayerShellV1::layer_bottom) << false;
|
2020-08-07 19:01:42 +00:00
|
|
|
QTest::addRow("background") << int(Test::LayerShellV1::layer_background) << false;
|
|
|
|
}
|
|
|
|
|
2022-04-22 17:46:41 +00:00
|
|
|
void LayerShellV1WindowTest::testActivate()
|
2020-08-07 19:01:42 +00:00
|
|
|
{
|
|
|
|
// Create a layer shell surface.
|
|
|
|
QScopedPointer<KWayland::Client::Surface> surface(Test::createSurface());
|
|
|
|
QScopedPointer<Test::LayerSurfaceV1> shellSurface(Test::createLayerSurfaceV1(surface.data(), QStringLiteral("test")));
|
|
|
|
|
|
|
|
// Set the initial state of the layer surface.
|
|
|
|
QFETCH(int, layer);
|
|
|
|
shellSurface->set_layer(layer);
|
|
|
|
shellSurface->set_size(280, 124);
|
|
|
|
surface->commit(KWayland::Client::Surface::CommitFlag::None);
|
|
|
|
|
|
|
|
// Wait for the compositor to position the surface.
|
|
|
|
QSignalSpy configureRequestedSpy(shellSurface.data(), &Test::LayerSurfaceV1::configureRequested);
|
|
|
|
QVERIFY(configureRequestedSpy.isValid());
|
|
|
|
QVERIFY(configureRequestedSpy.wait());
|
|
|
|
const QSize requestedSize = configureRequestedSpy.last().at(1).toSize();
|
|
|
|
|
|
|
|
// Map the layer surface.
|
|
|
|
shellSurface->ack_configure(configureRequestedSpy.last().at(0).toUInt());
|
2022-04-22 17:39:12 +00:00
|
|
|
Window *client = Test::renderAndWaitForShown(surface.data(), requestedSize, Qt::red);
|
2020-08-07 19:01:42 +00:00
|
|
|
QVERIFY(client);
|
|
|
|
QVERIFY(!client->isActive());
|
|
|
|
|
|
|
|
// Try to activate the layer surface.
|
|
|
|
shellSurface->set_keyboard_interactivity(1);
|
|
|
|
surface->commit(KWayland::Client::Surface::CommitFlag::None);
|
|
|
|
|
2022-04-22 17:39:12 +00:00
|
|
|
QSignalSpy activeChangedSpy(client, &Window::activeChanged);
|
2020-08-07 19:01:42 +00:00
|
|
|
QVERIFY(activeChangedSpy.isValid());
|
|
|
|
QTEST(activeChangedSpy.wait(1000), "active");
|
|
|
|
|
|
|
|
// Destroy the client.
|
|
|
|
shellSurface.reset();
|
|
|
|
QVERIFY(Test::waitForWindowDestroyed(client));
|
|
|
|
}
|
|
|
|
|
2022-04-22 17:46:41 +00:00
|
|
|
void LayerShellV1WindowTest::testUnmap()
|
2020-08-07 19:01:42 +00:00
|
|
|
{
|
|
|
|
// Create a layer shell surface.
|
|
|
|
QScopedPointer<KWayland::Client::Surface> surface(Test::createSurface());
|
|
|
|
QScopedPointer<Test::LayerSurfaceV1> shellSurface(Test::createLayerSurfaceV1(surface.data(), QStringLiteral("test")));
|
|
|
|
|
|
|
|
// Set the initial state of the layer surface.
|
|
|
|
shellSurface->set_size(280, 124);
|
|
|
|
surface->commit(KWayland::Client::Surface::CommitFlag::None);
|
|
|
|
|
|
|
|
// Wait for the compositor to position the surface.
|
|
|
|
QSignalSpy configureRequestedSpy(shellSurface.data(), &Test::LayerSurfaceV1::configureRequested);
|
|
|
|
QVERIFY(configureRequestedSpy.isValid());
|
|
|
|
QVERIFY(configureRequestedSpy.wait());
|
|
|
|
|
|
|
|
// Map the layer surface.
|
|
|
|
shellSurface->ack_configure(configureRequestedSpy.last().at(0).toUInt());
|
2022-04-22 17:39:12 +00:00
|
|
|
Window *client = Test::renderAndWaitForShown(surface.data(), QSize(280, 124), Qt::red);
|
2020-08-07 19:01:42 +00:00
|
|
|
QVERIFY(client);
|
|
|
|
|
|
|
|
// Unmap the layer surface.
|
|
|
|
surface->attachBuffer(KWayland::Client::Buffer::Ptr());
|
|
|
|
surface->commit(KWayland::Client::Surface::CommitFlag::None);
|
|
|
|
QVERIFY(Test::waitForWindowDestroyed(client));
|
|
|
|
|
|
|
|
// Notify the compositor that we want to map the layer surface.
|
|
|
|
shellSurface->set_size(280, 124);
|
|
|
|
surface->commit(KWayland::Client::Surface::CommitFlag::None);
|
|
|
|
|
|
|
|
// Wait for the configure event.
|
|
|
|
QVERIFY(configureRequestedSpy.wait());
|
|
|
|
|
|
|
|
// Map the layer surface back.
|
|
|
|
shellSurface->ack_configure(configureRequestedSpy.last().at(0).toUInt());
|
|
|
|
client = Test::renderAndWaitForShown(surface.data(), QSize(280, 124), Qt::red);
|
|
|
|
QVERIFY(client);
|
|
|
|
|
|
|
|
// Destroy the client.
|
|
|
|
shellSurface.reset();
|
|
|
|
QVERIFY(Test::waitForWindowDestroyed(client));
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace KWin
|
|
|
|
|
2022-04-22 17:46:41 +00:00
|
|
|
WAYLANDTEST_MAIN(KWin::LayerShellV1WindowTest)
|
|
|
|
#include "layershellv1window_test.moc"
|