Files
fedora-tools/plasma-task-group-shortcuts/tests/test-preview.cpp
T

174 lines
7.3 KiB
C++

// SPDX-License-Identifier: MIT
#include <QQmlComponent>
#include <QQmlEngine>
#include <QQuickWindow>
#include <QQuickItem>
#include <QTest>
#include <memory>
#include <QDBusConnection>
#include <QSignalSpy>
#include <plasma/plasma.h>
#include "../previewplacement.h"
#include "../taskbargeometry.h"
#include <abstracttasksmodel.h>
#include <tasksmodel.h>
class PreviewTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void placementTracksButtonAndScreenEdges()
{
const QRect screen(0, 0, 1000, 800);
const QSize size(300, 200);
QCOMPARE(previewPosition(QRect(400, 760, 100, 40), screen, size, Plasma::Types::BottomEdge), QPoint(300, 560));
QCOMPARE(previewPosition(QRect(0, 760, 100, 40), screen, size, Plasma::Types::BottomEdge), QPoint(0, 560));
QCOMPARE(previewPosition(QRect(900, 760, 100, 40), screen, size, Plasma::Types::BottomEdge), QPoint(700, 560));
QCOMPARE(previewPosition(QRect(400, 0, 100, 40), screen, size, Plasma::Types::TopEdge), QPoint(300, 40));
QCOMPARE(previewPosition(QRect(0, 300, 40, 100), screen, size, Plasma::Types::LeftEdge), QPoint(40, 250));
QCOMPARE(previewPosition(QRect(960, 300, 40, 100), screen, size, Plasma::Types::RightEdge), QPoint(660, 250));
QCOMPARE(previewPosition(QRect(-1000, 760, 100, 40), QRect(-1000, 0, 1000, 800), size,
Plasma::Types::BottomEdge), QPoint(-1000, 560));
QCOMPARE(previewPosition({}, screen, size, Plasma::Types::BottomEdge), QPoint(350, 600));
}
void geometryBridgeOnWayland()
{
if (QGuiApplication::platformName() != QLatin1String("wayland")) {
QSKIP("Requires KWin's Wayland compositor");
}
auto bus = QDBusConnection::sessionBus();
const QString service = QStringLiteral("se.ajpanton.plasma-task-group-shortcuts");
QVERIFY(bus.registerService(service));
{
TaskbarGeometry geometry;
QSignalSpy results(&geometry, &TaskbarGeometry::received);
QSignalSpy lookups(&geometry, &TaskbarGeometry::lookup);
// The script must respond even when a window has disappeared.
geometry.request(QStringLiteral("nonexistent-window"));
QTRY_COMPARE(lookups.count(), 1);
QTRY_COMPARE(results.count(), 1);
QVERIFY(results.first().first().toRectF().isEmpty());
geometry.request(QStringLiteral("another-window"));
geometry.cancel();
QTest::qWait(100);
QCOMPARE(results.count(), 1);
}
QVERIFY(bus.unregisterService(service));
}
void findsPublishedButtonGeometryOnWayland()
{
if (QGuiApplication::platformName() != QLatin1String("wayland")) {
QSKIP("Requires KWin and the plasma-window-management protocol");
}
TaskManager::TasksModel model;
model.setGroupMode(TaskManager::TasksModel::GroupDisabled);
QQuickWindow target;
target.setTitle(QStringLiteral("Task group geometry test"));
target.resize(400, 300);
target.show();
QTRY_VERIFY(target.isExposed());
const auto matching = [&] {
return model.match(model.index(0, 0), Qt::DisplayRole, target.title());
};
QTRY_VERIFY(!matching().isEmpty());
const QModelIndex index = matching().first();
const QString uuid = index.data(TaskManager::AbstractTasksModel::WinIdList).toList().first().toString();
QVERIFY(!uuid.isEmpty());
QQuickWindow panel;
panel.setTitle(QStringLiteral("Task group geometry panel"));
panel.resize(1000, 40);
panel.show();
QTRY_VERIFY(panel.isExposed());
const auto panelTask = [&] {
return model.match(model.index(0, 0), Qt::DisplayRole, panel.title());
};
QTRY_VERIFY(!panelTask().isEmpty());
QTRY_VERIFY(panelTask().first().data(TaskManager::AbstractTasksModel::Geometry).toRect().isValid());
const QPoint origin = panelTask().first().data(TaskManager::AbstractTasksModel::Geometry).toRect().topLeft();
const QRect button(origin + QPoint(120, 0), QSize(180, 40));
QQuickItem delegate(panel.contentItem());
delegate.setPosition(QPointF(120, 0));
delegate.setSize(QSizeF(180, 40));
model.requestPublishDelegateGeometry(index, button, &delegate);
QTest::qWait(100);
auto bus = QDBusConnection::sessionBus();
const QString service = QStringLiteral("se.ajpanton.plasma-task-group-shortcuts");
QVERIFY(bus.registerService(service));
{
TaskbarGeometry geometry;
QSignalSpy results(&geometry, &TaskbarGeometry::received);
geometry.request(uuid);
QTRY_COMPARE(results.count(), 1);
QCOMPARE(results.first().first().toRectF(), QRectF(button));
}
QVERIFY(bus.unregisterService(service));
}
void loadsWithoutTakingFocus()
{
QTest::failOnWarning(QRegularExpression(QStringLiteral(".*Failed to create .*popup.*")));
QQmlEngine engine;
QQmlComponent component(&engine, QUrl(QStringLiteral("qrc:/Preview.qml")));
std::unique_ptr<QObject> object(component.create());
QVERIFY2(object, qPrintable(component.errorString()));
auto *window = qobject_cast<QQuickWindow *>(object.get());
QVERIFY(window);
QVERIFY(!window->isVisible());
QCOMPARE(window->type(), Qt::Tool);
QVERIFY(!window->transientParent());
QVERIFY(window->flags().testFlag(Qt::FramelessWindowHint));
QVERIFY(window->flags().testFlag(Qt::WindowDoesNotAcceptFocus));
QVERIFY(window->flags().testFlag(Qt::WindowTransparentForInput));
window->show();
QTRY_VERIFY(window->isExposed());
// Wayland can reject a window with an asynchronously delivered close.
QTest::qWait(100);
QVERIFY(window->isVisible());
QVERIFY(window->isExposed());
QTRY_VERIFY(window->width() > 0);
QTRY_VERIFY(window->height() > 0);
QVERIFY(window->flags().testFlag(Qt::WindowDoesNotAcceptFocus));
window->setProperty("windowTitle", QStringLiteral("Test window"));
window->setProperty("position", 2);
window->setProperty("count", 3);
QCOMPARE(window->property("windowTitle").toString(), QStringLiteral("Test window"));
window->hide();
}
void preservesFocusOnWayland()
{
if (QGuiApplication::platformName() != QLatin1String("wayland")) {
QSKIP("Requires a Wayland compositor");
}
QQuickWindow original;
original.resize(400, 300);
original.show();
QTRY_VERIFY(original.isActive());
QQmlEngine engine;
QQmlComponent component(&engine, QUrl(QStringLiteral("qrc:/Preview.qml")));
std::unique_ptr<QObject> object(component.create());
QVERIFY2(object, qPrintable(component.errorString()));
auto *preview = qobject_cast<QQuickWindow *>(object.get());
QVERIFY(preview);
preview->show();
QTRY_VERIFY(preview->isExposed());
QTest::qWait(100);
QVERIFY(preview->isVisible());
QVERIFY(!preview->isActive());
QVERIFY(original.isActive());
preview->hide();
QTest::qWait(100);
QVERIFY(original.isActive());
}
};
QTEST_MAIN(PreviewTest)
#include "test-preview.moc"