kwin/autotests/integration/shell_client_rules_test.cpp
Vlad Zagorodniy be48d36349 [autotests] Rewrite testShellClientRules
Summary:
Currently, the test doesn't verify that each rule does what it should,
e.g. a force rule is a force rule and not force temporarily, etc. This
as it turns out hides some bugs, e.g. all remember rules do not work,
forced window shortcuts can't be released, etc.

CCBUG: 403305

Reviewers: #kwin, davidedmundson

Reviewed By: #kwin, davidedmundson

Subscribers: davidedmundson, graesslin, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D18464
2019-07-09 15:13:49 +03:00

2938 lines
103 KiB
C++

/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2017 Martin Flöser <mgraesslin@kde.org>
Copyright (C) 2019 Vlad Zagorodniy <vladzzag@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "kwin_wayland_test.h"
#include "platform.h"
#include "rules.h"
#include "screens.h"
#include "shell_client.h"
#include "virtualdesktops.h"
#include "wayland_server.h"
#include "workspace.h"
#include <KWayland/Client/surface.h>
#include <KWayland/Client/xdgshell.h>
#include <linux/input.h>
using namespace KWin;
using namespace KWayland::Client;
static const QString s_socketName = QStringLiteral("wayland_test_kwin_shell_client_rules-0");
class TestShellClientRules : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase();
void init();
void cleanup();
void testDesktopDontAffect_data();
void testDesktopDontAffect();
void testDesktopApply_data();
void testDesktopApply();
void testDesktopRemember_data();
void testDesktopRemember();
void testDesktopForce_data();
void testDesktopForce();
void testDesktopApplyNow_data();
void testDesktopApplyNow();
void testDesktopForceTemporarily_data();
void testDesktopForceTemporarily();
void testMinimizeDontAffect_data();
void testMinimizeDontAffect();
void testMinimizeApply_data();
void testMinimizeApply();
void testMinimizeRemember_data();
void testMinimizeRemember();
void testMinimizeForce_data();
void testMinimizeForce();
void testMinimizeApplyNow_data();
void testMinimizeApplyNow();
void testMinimizeForceTemporarily_data();
void testMinimizeForceTemporarily();
void testSkipTaskbarDontAffect_data();
void testSkipTaskbarDontAffect();
void testSkipTaskbarApply_data();
void testSkipTaskbarApply();
void testSkipTaskbarRemember_data();
void testSkipTaskbarRemember();
void testSkipTaskbarForce_data();
void testSkipTaskbarForce();
void testSkipTaskbarApplyNow_data();
void testSkipTaskbarApplyNow();
void testSkipTaskbarForceTemporarily_data();
void testSkipTaskbarForceTemporarily();
void testSkipPagerDontAffect_data();
void testSkipPagerDontAffect();
void testSkipPagerApply_data();
void testSkipPagerApply();
void testSkipPagerRemember_data();
void testSkipPagerRemember();
void testSkipPagerForce_data();
void testSkipPagerForce();
void testSkipPagerApplyNow_data();
void testSkipPagerApplyNow();
void testSkipPagerForceTemporarily_data();
void testSkipPagerForceTemporarily();
void testSkipSwitcherDontAffect_data();
void testSkipSwitcherDontAffect();
void testSkipSwitcherApply_data();
void testSkipSwitcherApply();
void testSkipSwitcherRemember_data();
void testSkipSwitcherRemember();
void testSkipSwitcherForce_data();
void testSkipSwitcherForce();
void testSkipSwitcherApplyNow_data();
void testSkipSwitcherApplyNow();
void testSkipSwitcherForceTemporarily_data();
void testSkipSwitcherForceTemporarily();
void testKeepAboveDontAffect_data();
void testKeepAboveDontAffect();
void testKeepAboveApply_data();
void testKeepAboveApply();
void testKeepAboveRemember_data();
void testKeepAboveRemember();
void testKeepAboveForce_data();
void testKeepAboveForce();
void testKeepAboveApplyNow_data();
void testKeepAboveApplyNow();
void testKeepAboveForceTemporarily_data();
void testKeepAboveForceTemporarily();
void testKeepBelowDontAffect_data();
void testKeepBelowDontAffect();
void testKeepBelowApply_data();
void testKeepBelowApply();
void testKeepBelowRemember_data();
void testKeepBelowRemember();
void testKeepBelowForce_data();
void testKeepBelowForce();
void testKeepBelowApplyNow_data();
void testKeepBelowApplyNow();
void testKeepBelowForceTemporarily_data();
void testKeepBelowForceTemporarily();
void testShortcutDontAffect_data();
void testShortcutDontAffect();
void testShortcutApply_data();
void testShortcutApply();
void testShortcutRemember_data();
void testShortcutRemember();
void testShortcutForce_data();
void testShortcutForce();
void testShortcutApplyNow_data();
void testShortcutApplyNow();
void testShortcutForceTemporarily_data();
void testShortcutForceTemporarily();
void testDesktopFileDontAffect_data();
void testDesktopFileDontAffect();
void testDesktopFileApply_data();
void testDesktopFileApply();
void testDesktopFileRemember_data();
void testDesktopFileRemember();
void testDesktopFileForce_data();
void testDesktopFileForce();
void testDesktopFileApplyNow_data();
void testDesktopFileApplyNow();
void testDesktopFileForceTemporarily_data();
void testDesktopFileForceTemporarily();
void testActiveOpacityDontAffect_data();
void testActiveOpacityDontAffect();
void testActiveOpacityForce_data();
void testActiveOpacityForce();
void testActiveOpacityForceTemporarily_data();
void testActiveOpacityForceTemporarily();
void testInactiveOpacityDontAffect_data();
void testInactiveOpacityDontAffect();
void testInactiveOpacityForce_data();
void testInactiveOpacityForce();
void testInactiveOpacityForceTemporarily_data();
void testInactiveOpacityForceTemporarily();
void testMatchAfterNameChange();
};
void TestShellClientRules::initTestCase()
{
qRegisterMetaType<KWin::ShellClient *>();
qRegisterMetaType<KWin::AbstractClient *>();
QSignalSpy workspaceCreatedSpy(kwinApp(), &Application::workspaceCreated);
QVERIFY(workspaceCreatedSpy.isValid());
kwinApp()->platform()->setInitialWindowSize(QSize(1280, 1024));
QMetaObject::invokeMethod(kwinApp()->platform(), "setVirtualOutputs", Qt::DirectConnection, Q_ARG(int, 2));
QVERIFY(waylandServer()->init(s_socketName.toLocal8Bit()));
kwinApp()->start();
QVERIFY(workspaceCreatedSpy.wait());
QCOMPARE(screens()->count(), 2);
QCOMPARE(screens()->geometry(0), QRect(0, 0, 1280, 1024));
QCOMPARE(screens()->geometry(1), QRect(1280, 0, 1280, 1024));
waylandServer()->initWorkspace();
}
void TestShellClientRules::init()
{
VirtualDesktopManager::self()->setCurrent(VirtualDesktopManager::self()->desktops().first());
QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Decoration));
screens()->setCurrent(0);
}
void TestShellClientRules::cleanup()
{
Test::destroyWaylandConnection();
// Unreference the previous config.
RuleBook::self()->setConfig({});
workspace()->slotReconfigure();
// Restore virtual desktops to the initial state.
VirtualDesktopManager::self()->setCount(1);
QCOMPARE(VirtualDesktopManager::self()->count(), 1u);
}
#define TEST_DATA(name) \
void TestShellClientRules::name##_data() \
{ \
QTest::addColumn<Test::ShellSurfaceType>("type"); \
QTest::newRow("XdgShellV5") << Test::ShellSurfaceType::XdgShellV5; \
QTest::newRow("XdgShellV6") << Test::ShellSurfaceType::XdgShellV6; \
QTest::newRow("XdgWmBase") << Test::ShellSurfaceType::XdgShellStable; \
}
std::tuple<ShellClient *, Surface *, XdgShellSurface *> createWindow(Test::ShellSurfaceType type, const QByteArray &appId)
{
// Create an xdg surface.
Surface *surface = Test::createSurface();
XdgShellSurface *shellSurface = Test::createXdgShellSurface(type, surface, surface, Test::CreationSetup::CreateOnly);
// Assign the desired app id.
shellSurface->setAppId(appId);
// Wait for the initial configure event.
QSignalSpy configureRequestedSpy(shellSurface, &XdgShellSurface::configureRequested);
surface->commit(Surface::CommitFlag::None);
configureRequestedSpy.wait();
// Draw content of the surface.
shellSurface->ackConfigure(configureRequestedSpy.last().at(2).value<quint32>());
ShellClient *client = Test::renderAndWaitForShown(surface, QSize(100, 50), Qt::blue);
return {client, surface, shellSurface};
}
TEST_DATA(testDesktopDontAffect)
void TestShellClientRules::testDesktopDontAffect()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("desktop", 2);
group.writeEntry("desktoprule", int(Rules::DontAffect));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// We need at least two virtual desktop for this test.
VirtualDesktopManager::self()->setCount(2);
QCOMPARE(VirtualDesktopManager::self()->count(), 2u);
VirtualDesktopManager::self()->setCurrent(1);
QCOMPARE(VirtualDesktopManager::self()->current(), 1);
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The client should appear on the current virtual desktop.
QCOMPARE(client->desktop(), 1);
QCOMPARE(VirtualDesktopManager::self()->current(), 1);
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testDesktopApply)
void TestShellClientRules::testDesktopApply()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("desktop", 2);
group.writeEntry("desktoprule", int(Rules::Apply));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// We need at least two virtual desktop for this test.
VirtualDesktopManager::self()->setCount(2);
QCOMPARE(VirtualDesktopManager::self()->count(), 2u);
VirtualDesktopManager::self()->setCurrent(1);
QCOMPARE(VirtualDesktopManager::self()->current(), 1);
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The client should appear on the second virtual desktop.
QCOMPARE(client->desktop(), 2);
QCOMPARE(VirtualDesktopManager::self()->current(), 2);
// We still should be able to move the client between desktops.
workspace()->sendClientToDesktop(client, 1, true);
QCOMPARE(client->desktop(), 1);
QCOMPARE(VirtualDesktopManager::self()->current(), 2);
// If we re-open the client, it should appear on the second virtual desktop again.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
VirtualDesktopManager::self()->setCurrent(1);
QCOMPARE(VirtualDesktopManager::self()->current(), 1);
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QCOMPARE(client->desktop(), 2);
QCOMPARE(VirtualDesktopManager::self()->current(), 2);
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testDesktopRemember)
void TestShellClientRules::testDesktopRemember()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("desktop", 2);
group.writeEntry("desktoprule", int(Rules::Remember));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// We need at least two virtual desktop for this test.
VirtualDesktopManager::self()->setCount(2);
QCOMPARE(VirtualDesktopManager::self()->count(), 2u);
VirtualDesktopManager::self()->setCurrent(1);
QCOMPARE(VirtualDesktopManager::self()->current(), 1);
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QCOMPARE(client->desktop(), 2);
QCOMPARE(VirtualDesktopManager::self()->current(), 2);
// Move the client to the first virtual desktop.
workspace()->sendClientToDesktop(client, 1, true);
QCOMPARE(client->desktop(), 1);
QCOMPARE(VirtualDesktopManager::self()->current(), 2);
// If we create the client again, it should appear on the first virtual desktop.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QCOMPARE(client->desktop(), 1);
QCOMPARE(VirtualDesktopManager::self()->current(), 1);
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testDesktopForce)
void TestShellClientRules::testDesktopForce()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("desktop", 2);
group.writeEntry("desktoprule", int(Rules::Force));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// We need at least two virtual desktop for this test.
VirtualDesktopManager::self()->setCount(2);
QCOMPARE(VirtualDesktopManager::self()->count(), 2u);
VirtualDesktopManager::self()->setCurrent(1);
QCOMPARE(VirtualDesktopManager::self()->current(), 1);
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The client should appear on the second virtual desktop.
QCOMPARE(client->desktop(), 2);
QCOMPARE(VirtualDesktopManager::self()->current(), 2);
// Any attempt to move the client to another virtual desktop should fail.
workspace()->sendClientToDesktop(client, 1, true);
QCOMPARE(client->desktop(), 2);
QCOMPARE(VirtualDesktopManager::self()->current(), 2);
// If we re-open the client, it should appear on the second virtual desktop again.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
VirtualDesktopManager::self()->setCurrent(1);
QCOMPARE(VirtualDesktopManager::self()->current(), 1);
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QCOMPARE(client->desktop(), 2);
QCOMPARE(VirtualDesktopManager::self()->current(), 2);
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testDesktopApplyNow)
void TestShellClientRules::testDesktopApplyNow()
{
// We need at least two virtual desktop for this test.
VirtualDesktopManager::self()->setCount(2);
QCOMPARE(VirtualDesktopManager::self()->count(), 2u);
VirtualDesktopManager::self()->setCurrent(1);
QCOMPARE(VirtualDesktopManager::self()->current(), 1);
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QCOMPARE(client->desktop(), 1);
QCOMPARE(VirtualDesktopManager::self()->current(), 1);
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("desktop", 2);
group.writeEntry("desktoprule", int(Rules::ApplyNow));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// The client should have been moved to the second virtual desktop.
QCOMPARE(client->desktop(), 2);
QCOMPARE(VirtualDesktopManager::self()->current(), 1);
// One should still be able to move the client between desktops.
workspace()->sendClientToDesktop(client, 1, true);
QCOMPARE(client->desktop(), 1);
QCOMPARE(VirtualDesktopManager::self()->current(), 1);
// The rule should not be applied again.
client->evaluateWindowRules();
QCOMPARE(client->desktop(), 1);
QCOMPARE(VirtualDesktopManager::self()->current(), 1);
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testDesktopForceTemporarily)
void TestShellClientRules::testDesktopForceTemporarily()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("desktop", 2);
group.writeEntry("desktoprule", int(Rules::ForceTemporarily));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// We need at least two virtual desktop for this test.
VirtualDesktopManager::self()->setCount(2);
QCOMPARE(VirtualDesktopManager::self()->count(), 2u);
VirtualDesktopManager::self()->setCurrent(1);
QCOMPARE(VirtualDesktopManager::self()->current(), 1);
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The client should appear on the second virtual desktop.
QCOMPARE(client->desktop(), 2);
QCOMPARE(VirtualDesktopManager::self()->current(), 2);
// Any attempt to move the client to another virtual desktop should fail.
workspace()->sendClientToDesktop(client, 1, true);
QCOMPARE(client->desktop(), 2);
QCOMPARE(VirtualDesktopManager::self()->current(), 2);
// The rule should be discarded when the client is withdrawn.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
VirtualDesktopManager::self()->setCurrent(1);
QCOMPARE(VirtualDesktopManager::self()->current(), 1);
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QCOMPARE(client->desktop(), 1);
QCOMPARE(VirtualDesktopManager::self()->current(), 1);
// One should be able to move the client between desktops.
workspace()->sendClientToDesktop(client, 2, true);
QCOMPARE(client->desktop(), 2);
QCOMPARE(VirtualDesktopManager::self()->current(), 1);
workspace()->sendClientToDesktop(client, 1, true);
QCOMPARE(client->desktop(), 1);
QCOMPARE(VirtualDesktopManager::self()->current(), 1);
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testMinimizeDontAffect)
void TestShellClientRules::testMinimizeDontAffect()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("minimize", true);
group.writeEntry("minimizerule", int(Rules::DontAffect));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(client->isMinimizable());
// The client should not be minimized.
QVERIFY(!client->isMinimized());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testMinimizeApply)
void TestShellClientRules::testMinimizeApply()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("minimize", true);
group.writeEntry("minimizerule", int(Rules::Apply));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(client->isMinimizable());
// The client should be minimized.
QVERIFY(client->isMinimized());
// We should still be able to unminimize the client.
client->unminimize();
QVERIFY(!client->isMinimized());
// If we re-open the client, it should be minimized back again.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(client->isMinimizable());
QVERIFY(client->isMinimized());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testMinimizeRemember)
void TestShellClientRules::testMinimizeRemember()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("minimize", false);
group.writeEntry("minimizerule", int(Rules::Remember));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(client->isMinimizable());
QVERIFY(!client->isMinimized());
// Minimize the client.
client->minimize();
QVERIFY(client->isMinimized());
// If we open the client again, it should be minimized.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(client->isMinimizable());
QVERIFY(client->isMinimized());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testMinimizeForce)
void TestShellClientRules::testMinimizeForce()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("minimize", false);
group.writeEntry("minimizerule", int(Rules::Force));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(!client->isMinimizable());
QVERIFY(!client->isMinimized());
// Any attempt to minimize the client should fail.
client->minimize();
QVERIFY(!client->isMinimized());
// If we re-open the client, the minimized state should still be forced.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(!client->isMinimizable());
QVERIFY(!client->isMinimized());
client->minimize();
QVERIFY(!client->isMinimized());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testMinimizeApplyNow)
void TestShellClientRules::testMinimizeApplyNow()
{
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(client->isMinimizable());
QVERIFY(!client->isMinimized());
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("minimize", true);
group.writeEntry("minimizerule", int(Rules::ApplyNow));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// The client should be minimized now.
QVERIFY(client->isMinimizable());
QVERIFY(client->isMinimized());
// One is still able to unminimize the client.
client->unminimize();
QVERIFY(!client->isMinimized());
// The rule should not be applied again.
client->evaluateWindowRules();
QVERIFY(client->isMinimizable());
QVERIFY(!client->isMinimized());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testMinimizeForceTemporarily)
void TestShellClientRules::testMinimizeForceTemporarily()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("minimize", false);
group.writeEntry("minimizerule", int(Rules::ForceTemporarily));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(!client->isMinimizable());
QVERIFY(!client->isMinimized());
// Any attempt to minimize the client should fail until the client is closed.
client->minimize();
QVERIFY(!client->isMinimized());
// The rule should be discarded when the client is closed.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(client->isMinimizable());
QVERIFY(!client->isMinimized());
client->minimize();
QVERIFY(client->isMinimized());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testSkipTaskbarDontAffect)
void TestShellClientRules::testSkipTaskbarDontAffect()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("skiptaskbar", true);
group.writeEntry("skiptaskbarrule", int(Rules::DontAffect));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The client should not be affected by the rule.
QVERIFY(!client->skipTaskbar());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testSkipTaskbarApply)
void TestShellClientRules::testSkipTaskbarApply()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("skiptaskbar", true);
group.writeEntry("skiptaskbarrule", int(Rules::Apply));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The client should not be included on a taskbar.
QVERIFY(client->skipTaskbar());
// Though one can change that.
client->setOriginalSkipTaskbar(false);
QVERIFY(!client->skipTaskbar());
// Reopen the client, the rule should be applied again.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(client->skipTaskbar());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testSkipTaskbarRemember)
void TestShellClientRules::testSkipTaskbarRemember()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("skiptaskbar", true);
group.writeEntry("skiptaskbarrule", int(Rules::Remember));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The client should not be included on a taskbar.
QVERIFY(client->skipTaskbar());
// Change the skip-taskbar state.
client->setOriginalSkipTaskbar(false);
QVERIFY(!client->skipTaskbar());
// Reopen the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The client should be included on a taskbar.
QVERIFY(!client->skipTaskbar());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testSkipTaskbarForce)
void TestShellClientRules::testSkipTaskbarForce()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("skiptaskbar", true);
group.writeEntry("skiptaskbarrule", int(Rules::Force));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The client should not be included on a taskbar.
QVERIFY(client->skipTaskbar());
// Any attempt to change the skip-taskbar state should not succeed.
client->setOriginalSkipTaskbar(false);
QVERIFY(client->skipTaskbar());
// Reopen the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The skip-taskbar state should be still forced.
QVERIFY(client->skipTaskbar());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testSkipTaskbarApplyNow)
void TestShellClientRules::testSkipTaskbarApplyNow()
{
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(!client->skipTaskbar());
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("skiptaskbar", true);
group.writeEntry("skiptaskbarrule", int(Rules::ApplyNow));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// The client should not be on a taskbar now.
QVERIFY(client->skipTaskbar());
// Also, one change the skip-taskbar state.
client->setOriginalSkipTaskbar(false);
QVERIFY(!client->skipTaskbar());
// The rule should not be applied again.
client->evaluateWindowRules();
QVERIFY(!client->skipTaskbar());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testSkipTaskbarForceTemporarily)
void TestShellClientRules::testSkipTaskbarForceTemporarily()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("skiptaskbar", true);
group.writeEntry("skiptaskbarrule", int(Rules::ForceTemporarily));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The client should not be included on a taskbar.
QVERIFY(client->skipTaskbar());
// Any attempt to change the skip-taskbar state should not succeed.
client->setOriginalSkipTaskbar(false);
QVERIFY(client->skipTaskbar());
// The rule should be discarded when the client is closed.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(!client->skipTaskbar());
// The skip-taskbar state is no longer forced.
client->setOriginalSkipTaskbar(true);
QVERIFY(client->skipTaskbar());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testSkipPagerDontAffect)
void TestShellClientRules::testSkipPagerDontAffect()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("skippager", true);
group.writeEntry("skippagerrule", int(Rules::DontAffect));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The client should not be affected by the rule.
QVERIFY(!client->skipPager());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testSkipPagerApply)
void TestShellClientRules::testSkipPagerApply()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("skippager", true);
group.writeEntry("skippagerrule", int(Rules::Apply));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The client should not be included on a pager.
QVERIFY(client->skipPager());
// Though one can change that.
client->setSkipPager(false);
QVERIFY(!client->skipPager());
// Reopen the client, the rule should be applied again.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(client->skipPager());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testSkipPagerRemember)
void TestShellClientRules::testSkipPagerRemember()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("skippager", true);
group.writeEntry("skippagerrule", int(Rules::Remember));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The client should not be included on a pager.
QVERIFY(client->skipPager());
// Change the skip-pager state.
client->setSkipPager(false);
QVERIFY(!client->skipPager());
// Reopen the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The client should be included on a pager.
QVERIFY(!client->skipPager());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testSkipPagerForce)
void TestShellClientRules::testSkipPagerForce()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("skippager", true);
group.writeEntry("skippagerrule", int(Rules::Force));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The client should not be included on a pager.
QVERIFY(client->skipPager());
// Any attempt to change the skip-pager state should not succeed.
client->setSkipPager(false);
QVERIFY(client->skipPager());
// Reopen the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The skip-pager state should be still forced.
QVERIFY(client->skipPager());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testSkipPagerApplyNow)
void TestShellClientRules::testSkipPagerApplyNow()
{
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(!client->skipPager());
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("skippager", true);
group.writeEntry("skippagerrule", int(Rules::ApplyNow));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// The client should not be on a pager now.
QVERIFY(client->skipPager());
// Also, one change the skip-pager state.
client->setSkipPager(false);
QVERIFY(!client->skipPager());
// The rule should not be applied again.
client->evaluateWindowRules();
QVERIFY(!client->skipPager());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testSkipPagerForceTemporarily)
void TestShellClientRules::testSkipPagerForceTemporarily()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("skippager", true);
group.writeEntry("skippagerrule", int(Rules::ForceTemporarily));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The client should not be included on a pager.
QVERIFY(client->skipPager());
// Any attempt to change the skip-pager state should not succeed.
client->setSkipPager(false);
QVERIFY(client->skipPager());
// The rule should be discarded when the client is closed.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(!client->skipPager());
// The skip-pager state is no longer forced.
client->setSkipPager(true);
QVERIFY(client->skipPager());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testSkipSwitcherDontAffect)
void TestShellClientRules::testSkipSwitcherDontAffect()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("skipswitcher", true);
group.writeEntry("skipswitcherrule", int(Rules::DontAffect));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The client should not be affected by the rule.
QVERIFY(!client->skipSwitcher());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testSkipSwitcherApply)
void TestShellClientRules::testSkipSwitcherApply()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("skipswitcher", true);
group.writeEntry("skipswitcherrule", int(Rules::Apply));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The client should be excluded from window switching effects.
QVERIFY(client->skipSwitcher());
// Though one can change that.
client->setSkipSwitcher(false);
QVERIFY(!client->skipSwitcher());
// Reopen the client, the rule should be applied again.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(client->skipSwitcher());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testSkipSwitcherRemember)
void TestShellClientRules::testSkipSwitcherRemember()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("skipswitcher", true);
group.writeEntry("skipswitcherrule", int(Rules::Remember));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The client should be excluded from window switching effects.
QVERIFY(client->skipSwitcher());
// Change the skip-switcher state.
client->setSkipSwitcher(false);
QVERIFY(!client->skipSwitcher());
// Reopen the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The client should be included in window switching effects.
QVERIFY(!client->skipSwitcher());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testSkipSwitcherForce)
void TestShellClientRules::testSkipSwitcherForce()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("skipswitcher", true);
group.writeEntry("skipswitcherrule", int(Rules::Force));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The client should be excluded from window switching effects.
QVERIFY(client->skipSwitcher());
// Any attempt to change the skip-switcher state should not succeed.
client->setSkipSwitcher(false);
QVERIFY(client->skipSwitcher());
// Reopen the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The skip-switcher state should be still forced.
QVERIFY(client->skipSwitcher());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testSkipSwitcherApplyNow)
void TestShellClientRules::testSkipSwitcherApplyNow()
{
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(!client->skipSwitcher());
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("skipswitcher", true);
group.writeEntry("skipswitcherrule", int(Rules::ApplyNow));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// The client should be excluded from window switching effects now.
QVERIFY(client->skipSwitcher());
// Also, one change the skip-switcher state.
client->setSkipSwitcher(false);
QVERIFY(!client->skipSwitcher());
// The rule should not be applied again.
client->evaluateWindowRules();
QVERIFY(!client->skipSwitcher());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testSkipSwitcherForceTemporarily)
void TestShellClientRules::testSkipSwitcherForceTemporarily()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("skipswitcher", true);
group.writeEntry("skipswitcherrule", int(Rules::ForceTemporarily));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The client should be excluded from window switching effects.
QVERIFY(client->skipSwitcher());
// Any attempt to change the skip-switcher state should not succeed.
client->setSkipSwitcher(false);
QVERIFY(client->skipSwitcher());
// The rule should be discarded when the client is closed.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(!client->skipSwitcher());
// The skip-switcher state is no longer forced.
client->setSkipSwitcher(true);
QVERIFY(client->skipSwitcher());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testKeepAboveDontAffect)
void TestShellClientRules::testKeepAboveDontAffect()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("above", true);
group.writeEntry("aboverule", int(Rules::DontAffect));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The keep-above state of the client should not be affected by the rule.
QVERIFY(!client->keepAbove());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testKeepAboveApply)
void TestShellClientRules::testKeepAboveApply()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("above", true);
group.writeEntry("aboverule", int(Rules::Apply));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// Initially, the client should be kept above.
QVERIFY(client->keepAbove());
// One should also be able to alter the keep-above state.
client->setKeepAbove(false);
QVERIFY(!client->keepAbove());
// If one re-opens the client, it should be kept above back again.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(client->keepAbove());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testKeepAboveRemember)
void TestShellClientRules::testKeepAboveRemember()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("above", true);
group.writeEntry("aboverule", int(Rules::Remember));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// Initially, the client should be kept above.
QVERIFY(client->keepAbove());
// Unset the keep-above state.
client->setKeepAbove(false);
QVERIFY(!client->keepAbove());
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
// Re-open the client, it should not be kept above.
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(!client->keepAbove());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testKeepAboveForce)
void TestShellClientRules::testKeepAboveForce()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("above", true);
group.writeEntry("aboverule", int(Rules::Force));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// Initially, the client should be kept above.
QVERIFY(client->keepAbove());
// Any attemt to unset the keep-above should not succeed.
client->setKeepAbove(false);
QVERIFY(client->keepAbove());
// If we re-open the client, it should still be kept above.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(client->keepAbove());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testKeepAboveApplyNow)
void TestShellClientRules::testKeepAboveApplyNow()
{
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(!client->keepAbove());
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("above", true);
group.writeEntry("aboverule", int(Rules::ApplyNow));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// The client should now be kept above other clients.
QVERIFY(client->keepAbove());
// One is still able to change the keep-above state of the client.
client->setKeepAbove(false);
QVERIFY(!client->keepAbove());
// The rule should not be applied again.
client->evaluateWindowRules();
QVERIFY(!client->keepAbove());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testKeepAboveForceTemporarily)
void TestShellClientRules::testKeepAboveForceTemporarily()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("above", true);
group.writeEntry("aboverule", int(Rules::ForceTemporarily));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// Initially, the client should be kept above.
QVERIFY(client->keepAbove());
// Any attempt to alter the keep-above state should not succeed.
client->setKeepAbove(false);
QVERIFY(client->keepAbove());
// The rule should be discarded when the client is closed.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(!client->keepAbove());
// The keep-above state is no longer forced.
client->setKeepAbove(true);
QVERIFY(client->keepAbove());
client->setKeepAbove(false);
QVERIFY(!client->keepAbove());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testKeepBelowDontAffect)
void TestShellClientRules::testKeepBelowDontAffect()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("below", true);
group.writeEntry("belowrule", int(Rules::DontAffect));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The keep-below state of the client should not be affected by the rule.
QVERIFY(!client->keepBelow());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testKeepBelowApply)
void TestShellClientRules::testKeepBelowApply()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("below", true);
group.writeEntry("belowrule", int(Rules::Apply));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// Initially, the client should be kept below.
QVERIFY(client->keepBelow());
// One should also be able to alter the keep-below state.
client->setKeepBelow(false);
QVERIFY(!client->keepBelow());
// If one re-opens the client, it should be kept above back again.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(client->keepBelow());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testKeepBelowRemember)
void TestShellClientRules::testKeepBelowRemember()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("below", true);
group.writeEntry("belowrule", int(Rules::Remember));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// Initially, the client should be kept below.
QVERIFY(client->keepBelow());
// Unset the keep-below state.
client->setKeepBelow(false);
QVERIFY(!client->keepBelow());
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
// Re-open the client, it should not be kept below.
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(!client->keepBelow());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testKeepBelowForce)
void TestShellClientRules::testKeepBelowForce()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("below", true);
group.writeEntry("belowrule", int(Rules::Force));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// Initially, the client should be kept below.
QVERIFY(client->keepBelow());
// Any attemt to unset the keep-below should not succeed.
client->setKeepBelow(false);
QVERIFY(client->keepBelow());
// If we re-open the client, it should still be kept below.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(client->keepBelow());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testKeepBelowApplyNow)
void TestShellClientRules::testKeepBelowApplyNow()
{
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(!client->keepBelow());
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("below", true);
group.writeEntry("belowrule", int(Rules::ApplyNow));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// The client should now be kept below other clients.
QVERIFY(client->keepBelow());
// One is still able to change the keep-below state of the client.
client->setKeepBelow(false);
QVERIFY(!client->keepBelow());
// The rule should not be applied again.
client->evaluateWindowRules();
QVERIFY(!client->keepBelow());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testKeepBelowForceTemporarily)
void TestShellClientRules::testKeepBelowForceTemporarily()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("below", true);
group.writeEntry("belowrule", int(Rules::ForceTemporarily));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// Initially, the client should be kept below.
QVERIFY(client->keepBelow());
// Any attempt to alter the keep-below state should not succeed.
client->setKeepBelow(false);
QVERIFY(client->keepBelow());
// The rule should be discarded when the client is closed.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(!client->keepBelow());
// The keep-below state is no longer forced.
client->setKeepBelow(true);
QVERIFY(client->keepBelow());
client->setKeepBelow(false);
QVERIFY(!client->keepBelow());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testShortcutDontAffect)
void TestShellClientRules::testShortcutDontAffect()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("shortcut", "Ctrl+Alt+1");
group.writeEntry("shortcutrule", int(Rules::DontAffect));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QCOMPARE(client->shortcut(), QKeySequence());
client->minimize();
QVERIFY(client->isMinimized());
// If we press the window shortcut, nothing should happen.
QSignalSpy clientUnminimizedSpy(client, &AbstractClient::clientUnminimized);
QVERIFY(clientUnminimizedSpy.isValid());
quint32 timestamp = 1;
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTCTRL, timestamp++);
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTALT, timestamp++);
kwinApp()->platform()->keyboardKeyPressed(KEY_1, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_1, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTALT, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTCTRL, timestamp++);
QVERIFY(!clientUnminimizedSpy.wait(100));
QVERIFY(client->isMinimized());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testShortcutApply)
void TestShellClientRules::testShortcutApply()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("shortcut", "Ctrl+Alt+1");
group.writeEntry("shortcutrule", int(Rules::Apply));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// If we press the window shortcut, the window should be brought back to user.
QSignalSpy clientUnminimizedSpy(client, &AbstractClient::clientUnminimized);
QVERIFY(clientUnminimizedSpy.isValid());
quint32 timestamp = 1;
QCOMPARE(client->shortcut(), (QKeySequence{Qt::CTRL + Qt::ALT + Qt::Key_1}));
client->minimize();
QVERIFY(client->isMinimized());
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTCTRL, timestamp++);
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTALT, timestamp++);
kwinApp()->platform()->keyboardKeyPressed(KEY_1, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_1, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTALT, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTCTRL, timestamp++);
QVERIFY(clientUnminimizedSpy.wait());
QVERIFY(!client->isMinimized());
// One can also change the shortcut.
client->setShortcut(QStringLiteral("Ctrl+Alt+2"));
QCOMPARE(client->shortcut(), (QKeySequence{Qt::CTRL + Qt::ALT + Qt::Key_2}));
client->minimize();
QVERIFY(client->isMinimized());
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTCTRL, timestamp++);
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTALT, timestamp++);
kwinApp()->platform()->keyboardKeyPressed(KEY_2, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_2, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTALT, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTCTRL, timestamp++);
QVERIFY(clientUnminimizedSpy.wait());
QVERIFY(!client->isMinimized());
// The old shortcut should do nothing.
client->minimize();
QVERIFY(client->isMinimized());
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTCTRL, timestamp++);
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTALT, timestamp++);
kwinApp()->platform()->keyboardKeyPressed(KEY_1, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_1, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTALT, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTCTRL, timestamp++);
QVERIFY(!clientUnminimizedSpy.wait(100));
QVERIFY(client->isMinimized());
// Reopen the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The window shortcut should be set back to Ctrl+Alt+1.
QCOMPARE(client->shortcut(), (QKeySequence{Qt::CTRL + Qt::ALT + Qt::Key_1}));
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testShortcutRemember)
void TestShellClientRules::testShortcutRemember()
{
QSKIP("KWin core doesn't try to save the last used window shortcut");
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("shortcut", "Ctrl+Alt+1");
group.writeEntry("shortcutrule", int(Rules::Remember));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// If we press the window shortcut, the window should be brought back to user.
QSignalSpy clientUnminimizedSpy(client, &AbstractClient::clientUnminimized);
QVERIFY(clientUnminimizedSpy.isValid());
quint32 timestamp = 1;
QCOMPARE(client->shortcut(), (QKeySequence{Qt::CTRL + Qt::ALT + Qt::Key_1}));
client->minimize();
QVERIFY(client->isMinimized());
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTCTRL, timestamp++);
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTALT, timestamp++);
kwinApp()->platform()->keyboardKeyPressed(KEY_1, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_1, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTALT, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTCTRL, timestamp++);
QVERIFY(clientUnminimizedSpy.wait());
QVERIFY(!client->isMinimized());
// Change the window shortcut to Ctrl+Alt+2.
client->setShortcut(QStringLiteral("Ctrl+Alt+2"));
QCOMPARE(client->shortcut(), (QKeySequence{Qt::CTRL + Qt::ALT + Qt::Key_2}));
client->minimize();
QVERIFY(client->isMinimized());
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTCTRL, timestamp++);
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTALT, timestamp++);
kwinApp()->platform()->keyboardKeyPressed(KEY_2, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_2, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTALT, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTCTRL, timestamp++);
QVERIFY(clientUnminimizedSpy.wait());
QVERIFY(!client->isMinimized());
// Reopen the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The window shortcut should be set to the last known value.
QCOMPARE(client->shortcut(), (QKeySequence{Qt::CTRL + Qt::ALT + Qt::Key_2}));
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testShortcutForce)
void TestShellClientRules::testShortcutForce()
{
QSKIP("KWin core can't release forced window shortcuts");
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("shortcut", "Ctrl+Alt+1");
group.writeEntry("shortcutrule", int(Rules::Force));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// If we press the window shortcut, the window should be brought back to user.
QSignalSpy clientUnminimizedSpy(client, &AbstractClient::clientUnminimized);
QVERIFY(clientUnminimizedSpy.isValid());
quint32 timestamp = 1;
QCOMPARE(client->shortcut(), (QKeySequence{Qt::CTRL + Qt::ALT + Qt::Key_1}));
client->minimize();
QVERIFY(client->isMinimized());
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTCTRL, timestamp++);
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTALT, timestamp++);
kwinApp()->platform()->keyboardKeyPressed(KEY_1, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_1, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTALT, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTCTRL, timestamp++);
QVERIFY(clientUnminimizedSpy.wait());
QVERIFY(!client->isMinimized());
// Any attempt to change the window shortcut should not succeed.
client->setShortcut(QStringLiteral("Ctrl+Alt+2"));
QCOMPARE(client->shortcut(), (QKeySequence{Qt::CTRL + Qt::ALT + Qt::Key_1}));
client->minimize();
QVERIFY(client->isMinimized());
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTCTRL, timestamp++);
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTALT, timestamp++);
kwinApp()->platform()->keyboardKeyPressed(KEY_2, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_2, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTALT, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTCTRL, timestamp++);
QVERIFY(!clientUnminimizedSpy.wait(100));
QVERIFY(client->isMinimized());
// Reopen the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// The window shortcut should still be forced.
QCOMPARE(client->shortcut(), (QKeySequence{Qt::CTRL + Qt::ALT + Qt::Key_1}));
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testShortcutApplyNow)
void TestShellClientRules::testShortcutApplyNow()
{
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(client->shortcut().isEmpty());
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("shortcut", "Ctrl+Alt+1");
group.writeEntry("shortcutrule", int(Rules::ApplyNow));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// The client should now have a window shortcut assigned.
QCOMPARE(client->shortcut(), (QKeySequence{Qt::CTRL + Qt::ALT + Qt::Key_1}));
QSignalSpy clientUnminimizedSpy(client, &AbstractClient::clientUnminimized);
QVERIFY(clientUnminimizedSpy.isValid());
quint32 timestamp = 1;
client->minimize();
QVERIFY(client->isMinimized());
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTCTRL, timestamp++);
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTALT, timestamp++);
kwinApp()->platform()->keyboardKeyPressed(KEY_1, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_1, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTALT, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTCTRL, timestamp++);
QVERIFY(clientUnminimizedSpy.wait());
QVERIFY(!client->isMinimized());
// Assign a different shortcut.
client->setShortcut(QStringLiteral("Ctrl+Alt+2"));
QCOMPARE(client->shortcut(), (QKeySequence{Qt::CTRL + Qt::ALT + Qt::Key_2}));
client->minimize();
QVERIFY(client->isMinimized());
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTCTRL, timestamp++);
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTALT, timestamp++);
kwinApp()->platform()->keyboardKeyPressed(KEY_2, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_2, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTALT, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTCTRL, timestamp++);
QVERIFY(clientUnminimizedSpy.wait());
QVERIFY(!client->isMinimized());
// The rule should not be applied again.
client->evaluateWindowRules();
QCOMPARE(client->shortcut(), (QKeySequence{Qt::CTRL + Qt::ALT + Qt::Key_2}));
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testShortcutForceTemporarily)
void TestShellClientRules::testShortcutForceTemporarily()
{
QSKIP("KWin core can't release forced window shortcuts");
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("shortcut", "Ctrl+Alt+1");
group.writeEntry("shortcutrule", int(Rules::ForceTemporarily));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
// If we press the window shortcut, the window should be brought back to user.
QSignalSpy clientUnminimizedSpy(client, &AbstractClient::clientUnminimized);
QVERIFY(clientUnminimizedSpy.isValid());
quint32 timestamp = 1;
QCOMPARE(client->shortcut(), (QKeySequence{Qt::CTRL + Qt::ALT + Qt::Key_1}));
client->minimize();
QVERIFY(client->isMinimized());
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTCTRL, timestamp++);
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTALT, timestamp++);
kwinApp()->platform()->keyboardKeyPressed(KEY_1, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_1, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTALT, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTCTRL, timestamp++);
QVERIFY(clientUnminimizedSpy.wait());
QVERIFY(!client->isMinimized());
// Any attempt to change the window shortcut should not succeed.
client->setShortcut(QStringLiteral("Ctrl+Alt+2"));
QCOMPARE(client->shortcut(), (QKeySequence{Qt::CTRL + Qt::ALT + Qt::Key_1}));
client->minimize();
QVERIFY(client->isMinimized());
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTCTRL, timestamp++);
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTALT, timestamp++);
kwinApp()->platform()->keyboardKeyPressed(KEY_2, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_2, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTALT, timestamp++);
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTCTRL, timestamp++);
QVERIFY(!clientUnminimizedSpy.wait(100));
QVERIFY(client->isMinimized());
// The rule should be discarded when the client is closed.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(client->shortcut().isEmpty());
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testDesktopFileDontAffect)
void TestShellClientRules::testDesktopFileDontAffect()
{
// Currently, the desktop file name is derived from the app id. If the app id is
// changed, then the old rules will be lost. Either setDesktopFileName should
// be exposed or the desktop file name rule should be removed for wayland clients.
QSKIP("Needs changes in KWin core to pass");
}
TEST_DATA(testDesktopFileApply)
void TestShellClientRules::testDesktopFileApply()
{
// Currently, the desktop file name is derived from the app id. If the app id is
// changed, then the old rules will be lost. Either setDesktopFileName should
// be exposed or the desktop file name rule should be removed for wayland clients.
QSKIP("Needs changes in KWin core to pass");
}
TEST_DATA(testDesktopFileRemember)
void TestShellClientRules::testDesktopFileRemember()
{
// Currently, the desktop file name is derived from the app id. If the app id is
// changed, then the old rules will be lost. Either setDesktopFileName should
// be exposed or the desktop file name rule should be removed for wayland clients.
QSKIP("Needs changes in KWin core to pass");
}
TEST_DATA(testDesktopFileForce)
void TestShellClientRules::testDesktopFileForce()
{
// Currently, the desktop file name is derived from the app id. If the app id is
// changed, then the old rules will be lost. Either setDesktopFileName should
// be exposed or the desktop file name rule should be removed for wayland clients.
QSKIP("Needs changes in KWin core to pass");
}
TEST_DATA(testDesktopFileApplyNow)
void TestShellClientRules::testDesktopFileApplyNow()
{
// Currently, the desktop file name is derived from the app id. If the app id is
// changed, then the old rules will be lost. Either setDesktopFileName should
// be exposed or the desktop file name rule should be removed for wayland clients.
QSKIP("Needs changes in KWin core to pass");
}
TEST_DATA(testDesktopFileForceTemporarily)
void TestShellClientRules::testDesktopFileForceTemporarily()
{
// Currently, the desktop file name is derived from the app id. If the app id is
// changed, then the old rules will be lost. Either setDesktopFileName should
// be exposed or the desktop file name rule should be removed for wayland clients.
QSKIP("Needs changes in KWin core to pass");
}
TEST_DATA(testActiveOpacityDontAffect)
void TestShellClientRules::testActiveOpacityDontAffect()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("opacityactive", 90);
group.writeEntry("opacityactiverule", int(Rules::DontAffect));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(client->isActive());
// The opacity should not be affected by the rule.
QCOMPARE(client->opacity(), 1.0);
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testActiveOpacityForce)
void TestShellClientRules::testActiveOpacityForce()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("opacityactive", 90);
group.writeEntry("opacityactiverule", int(Rules::Force));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(client->isActive());
QCOMPARE(client->opacity(), 0.9);
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testActiveOpacityForceTemporarily)
void TestShellClientRules::testActiveOpacityForceTemporarily()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("opacityactive", 90);
group.writeEntry("opacityactiverule", int(Rules::ForceTemporarily));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(client->isActive());
QCOMPARE(client->opacity(), 0.9);
// The rule should be discarded when the client is closed.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(client->isActive());
QCOMPARE(client->opacity(), 1.0);
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testInactiveOpacityDontAffect)
void TestShellClientRules::testInactiveOpacityDontAffect()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("opacityinactive", 80);
group.writeEntry("opacityinactiverule", int(Rules::DontAffect));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(client->isActive());
// Make the client inactive.
workspace()->setActiveClient(nullptr);
QVERIFY(!client->isActive());
// The opacity of the client should not be affected by the rule.
QCOMPARE(client->opacity(), 1.0);
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testInactiveOpacityForce)
void TestShellClientRules::testInactiveOpacityForce()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("opacityinactive", 80);
group.writeEntry("opacityinactiverule", int(Rules::Force));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(client->isActive());
QCOMPARE(client->opacity(), 1.0);
// Make the client inactive.
workspace()->setActiveClient(nullptr);
QVERIFY(!client->isActive());
// The opacity should be forced by the rule.
QCOMPARE(client->opacity(), 0.8);
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
TEST_DATA(testInactiveOpacityForceTemporarily)
void TestShellClientRules::testInactiveOpacityForceTemporarily()
{
// Initialize RuleBook with the test rule.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("opacityinactive", 80);
group.writeEntry("opacityinactiverule", int(Rules::ForceTemporarily));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
// Create the test client.
QFETCH(Test::ShellSurfaceType, type);
ShellClient *client;
Surface *surface;
XdgShellSurface *shellSurface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(client->isActive());
QCOMPARE(client->opacity(), 1.0);
// Make the client inactive.
workspace()->setActiveClient(nullptr);
QVERIFY(!client->isActive());
// The opacity should be forced by the rule.
QCOMPARE(client->opacity(), 0.8);
// The rule should be discarded when the client is closed.
delete shellSurface;
delete surface;
std::tie(client, surface, shellSurface) = createWindow(type, "org.kde.foo");
QVERIFY(client);
QVERIFY(client->isActive());
QCOMPARE(client->opacity(), 1.0);
workspace()->setActiveClient(nullptr);
QVERIFY(!client->isActive());
QCOMPARE(client->opacity(), 1.0);
// Destroy the client.
delete shellSurface;
delete surface;
QVERIFY(Test::waitForWindowDestroyed(client));
}
void TestShellClientRules::testMatchAfterNameChange()
{
KSharedConfig::Ptr config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
config->group("General").writeEntry("count", 1);
KConfigGroup group = config->group("1");
group.writeEntry("above", true);
group.writeEntry("aboverule", int(Rules::Force));
group.writeEntry("wmclass", "org.kde.foo");
group.writeEntry("wmclasscomplete", false);
group.writeEntry("wmclassmatch", int(Rules::ExactMatch));
group.sync();
RuleBook::self()->setConfig(config);
workspace()->slotReconfigure();
QScopedPointer<Surface> surface(Test::createSurface());
QScopedPointer<XdgShellSurface> shellSurface(Test::createXdgShellV6Surface(surface.data()));
auto c = Test::renderAndWaitForShown(surface.data(), QSize(100, 50), Qt::blue);
QVERIFY(c);
QVERIFY(c->isActive());
QCOMPARE(c->keepAbove(), false);
QSignalSpy desktopFileNameSpy(c, &AbstractClient::desktopFileNameChanged);
QVERIFY(desktopFileNameSpy.isValid());
shellSurface->setAppId(QByteArrayLiteral("org.kde.foo"));
QVERIFY(desktopFileNameSpy.wait());
QCOMPARE(c->keepAbove(), true);
}
WAYLANDTEST_MAIN(TestShellClientRules)
#include "shell_client_rules_test.moc"