KWin
Loading...
Searching...
No Matches
tabbox_test.cpp
Go to the documentation of this file.
1/*
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5 SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
6
7 SPDX-License-Identifier: GPL-2.0-or-later
8*/
9#include "kwin_wayland_test.h"
10
11#include "input.h"
12#include "pointer_input.h"
13#include "tabbox/tabbox.h"
14#include "wayland_server.h"
15#include "window.h"
16#include "workspace.h"
17
18#include <KConfigGroup>
19#include <KWayland/Client/surface.h>
20
21#include <linux/input.h>
22
23using namespace KWin;
24
25static const QString s_socketName = QStringLiteral("wayland_test_kwin_tabbox-0");
26
27class TabBoxTest : public QObject
28{
29 Q_OBJECT
30private Q_SLOTS:
31 void initTestCase();
32 void init();
33 void cleanup();
34
35 void testMoveForward();
36 void testMoveBackward();
37 void testCapsLock();
38};
39
40void TabBoxTest::initTestCase()
41{
42 qRegisterMetaType<KWin::Window *>();
43 QSignalSpy applicationStartedSpy(kwinApp(), &Application::started);
44 QVERIFY(waylandServer()->init(s_socketName));
46 QRect(0, 0, 1280, 1024),
47 QRect(1280, 0, 1280, 1024),
48 });
49
50 KSharedConfigPtr c = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
51 c->group(QStringLiteral("TabBox")).writeEntry("ShowTabBox", false);
52 c->sync();
53 kwinApp()->setConfig(c);
54 qputenv("KWIN_XKB_DEFAULT_KEYMAP", "1");
55
56 kwinApp()->start();
57 QVERIFY(applicationStartedSpy.wait());
58}
59
60void TabBoxTest::init()
61{
63 workspace()->setActiveOutput(QPoint(640, 512));
64 KWin::input()->pointer()->warp(QPoint(640, 512));
65}
66
67void TabBoxTest::cleanup()
68{
70}
71
72void TabBoxTest::testCapsLock()
73{
74#if !KWIN_BUILD_GLOBALSHORTCUTS
75 QSKIP("Can't test shortcuts without shortcuts");
76 return;
77#endif
78
79 // this test verifies that Alt+tab works correctly also when Capslock is on
80 // bug 368590
81
82 // first create three windows
83 std::unique_ptr<KWayland::Client::Surface> surface1(Test::createSurface());
84 std::unique_ptr<Test::XdgToplevel> shellSurface1(Test::createXdgToplevelSurface(surface1.get()));
85 auto c1 = Test::renderAndWaitForShown(surface1.get(), QSize(100, 50), Qt::blue);
86 QVERIFY(c1);
87 QVERIFY(c1->isActive());
88 std::unique_ptr<KWayland::Client::Surface> surface2(Test::createSurface());
89 std::unique_ptr<Test::XdgToplevel> shellSurface2(Test::createXdgToplevelSurface(surface2.get()));
90 auto c2 = Test::renderAndWaitForShown(surface2.get(), QSize(100, 50), Qt::red);
91 QVERIFY(c2);
92 QVERIFY(c2->isActive());
93 std::unique_ptr<KWayland::Client::Surface> surface3(Test::createSurface());
94 std::unique_ptr<Test::XdgToplevel> shellSurface3(Test::createXdgToplevelSurface(surface3.get()));
95 auto c3 = Test::renderAndWaitForShown(surface3.get(), QSize(100, 50), Qt::red);
96 QVERIFY(c3);
97 QVERIFY(c3->isActive());
98
99 // Setup tabbox signal spies
100 QSignalSpy tabboxAddedSpy(workspace()->tabbox(), &TabBox::TabBox::tabBoxAdded);
101 QSignalSpy tabboxClosedSpy(workspace()->tabbox(), &TabBox::TabBox::tabBoxClosed);
102
103 // enable capslock
104 quint32 timestamp = 0;
105 Test::keyboardKeyPressed(KEY_CAPSLOCK, timestamp++);
106 Test::keyboardKeyReleased(KEY_CAPSLOCK, timestamp++);
107 QCOMPARE(input()->keyboardModifiers(), Qt::NoModifier);
108
109 // press alt+tab
110 Test::keyboardKeyPressed(KEY_LEFTALT, timestamp++);
111 QCOMPARE(input()->keyboardModifiers(), Qt::AltModifier);
112 Test::keyboardKeyPressed(KEY_TAB, timestamp++);
113 Test::keyboardKeyReleased(KEY_TAB, timestamp++);
114
115 QVERIFY(tabboxAddedSpy.wait());
116 QVERIFY(workspace()->tabbox()->isGrabbed());
117
118 // release alt
119 Test::keyboardKeyReleased(KEY_LEFTALT, timestamp++);
120 QCOMPARE(tabboxClosedSpy.count(), 1);
121 QCOMPARE(workspace()->tabbox()->isGrabbed(), false);
122
123 // release caps lock
124 Test::keyboardKeyPressed(KEY_CAPSLOCK, timestamp++);
125 Test::keyboardKeyReleased(KEY_CAPSLOCK, timestamp++);
126 QCOMPARE(input()->keyboardModifiers(), Qt::NoModifier);
127 QCOMPARE(tabboxClosedSpy.count(), 1);
128 QCOMPARE(workspace()->tabbox()->isGrabbed(), false);
129 QCOMPARE(workspace()->activeWindow(), c2);
130
131 surface3.reset();
132 QVERIFY(Test::waitForWindowClosed(c3));
133 surface2.reset();
134 QVERIFY(Test::waitForWindowClosed(c2));
135 surface1.reset();
136 QVERIFY(Test::waitForWindowClosed(c1));
137}
138
139void TabBoxTest::testMoveForward()
140{
141#if !KWIN_BUILD_GLOBALSHORTCUTS
142 QSKIP("Can't test shortcuts without shortcuts");
143 return;
144#endif
145
146 // this test verifies that Alt+tab works correctly moving forward
147
148 // first create three windows
149 std::unique_ptr<KWayland::Client::Surface> surface1(Test::createSurface());
150 std::unique_ptr<Test::XdgToplevel> shellSurface1(Test::createXdgToplevelSurface(surface1.get()));
151 auto c1 = Test::renderAndWaitForShown(surface1.get(), QSize(100, 50), Qt::blue);
152 QVERIFY(c1);
153 QVERIFY(c1->isActive());
154 std::unique_ptr<KWayland::Client::Surface> surface2(Test::createSurface());
155 std::unique_ptr<Test::XdgToplevel> shellSurface2(Test::createXdgToplevelSurface(surface2.get()));
156 auto c2 = Test::renderAndWaitForShown(surface2.get(), QSize(100, 50), Qt::red);
157 QVERIFY(c2);
158 QVERIFY(c2->isActive());
159 std::unique_ptr<KWayland::Client::Surface> surface3(Test::createSurface());
160 std::unique_ptr<Test::XdgToplevel> shellSurface3(Test::createXdgToplevelSurface(surface3.get()));
161 auto c3 = Test::renderAndWaitForShown(surface3.get(), QSize(100, 50), Qt::red);
162 QVERIFY(c3);
163 QVERIFY(c3->isActive());
164
165 // Setup tabbox signal spies
166 QSignalSpy tabboxAddedSpy(workspace()->tabbox(), &TabBox::TabBox::tabBoxAdded);
167 QSignalSpy tabboxClosedSpy(workspace()->tabbox(), &TabBox::TabBox::tabBoxClosed);
168
169 // press alt+tab
170 quint32 timestamp = 0;
171 Test::keyboardKeyPressed(KEY_LEFTALT, timestamp++);
172 QCOMPARE(input()->keyboardModifiers(), Qt::AltModifier);
173 Test::keyboardKeyPressed(KEY_TAB, timestamp++);
174 Test::keyboardKeyReleased(KEY_TAB, timestamp++);
175
176 QVERIFY(tabboxAddedSpy.wait());
177 QVERIFY(workspace()->tabbox()->isGrabbed());
178
179 // release alt
180 Test::keyboardKeyReleased(KEY_LEFTALT, timestamp++);
181 QCOMPARE(tabboxClosedSpy.count(), 1);
182 QCOMPARE(workspace()->tabbox()->isGrabbed(), false);
183 QCOMPARE(workspace()->activeWindow(), c2);
184
185 surface3.reset();
186 QVERIFY(Test::waitForWindowClosed(c3));
187 surface2.reset();
188 QVERIFY(Test::waitForWindowClosed(c2));
189 surface1.reset();
190 QVERIFY(Test::waitForWindowClosed(c1));
191}
192
193void TabBoxTest::testMoveBackward()
194{
195#if !KWIN_BUILD_GLOBALSHORTCUTS
196 QSKIP("Can't test shortcuts without shortcuts");
197 return;
198#endif
199
200 // this test verifies that Alt+Shift+tab works correctly moving backward
201
202 // first create three windows
203 std::unique_ptr<KWayland::Client::Surface> surface1(Test::createSurface());
204 std::unique_ptr<Test::XdgToplevel> shellSurface1(Test::createXdgToplevelSurface(surface1.get()));
205 auto c1 = Test::renderAndWaitForShown(surface1.get(), QSize(100, 50), Qt::blue);
206 QVERIFY(c1);
207 QVERIFY(c1->isActive());
208 std::unique_ptr<KWayland::Client::Surface> surface2(Test::createSurface());
209 std::unique_ptr<Test::XdgToplevel> shellSurface2(Test::createXdgToplevelSurface(surface2.get()));
210 auto c2 = Test::renderAndWaitForShown(surface2.get(), QSize(100, 50), Qt::red);
211 QVERIFY(c2);
212 QVERIFY(c2->isActive());
213 std::unique_ptr<KWayland::Client::Surface> surface3(Test::createSurface());
214 std::unique_ptr<Test::XdgToplevel> shellSurface3(Test::createXdgToplevelSurface(surface3.get()));
215 auto c3 = Test::renderAndWaitForShown(surface3.get(), QSize(100, 50), Qt::red);
216 QVERIFY(c3);
217 QVERIFY(c3->isActive());
218
219 // Setup tabbox signal spies
220 QSignalSpy tabboxAddedSpy(workspace()->tabbox(), &TabBox::TabBox::tabBoxAdded);
221 QSignalSpy tabboxClosedSpy(workspace()->tabbox(), &TabBox::TabBox::tabBoxClosed);
222
223 // press alt+shift+tab
224 quint32 timestamp = 0;
225 Test::keyboardKeyPressed(KEY_LEFTALT, timestamp++);
226 QCOMPARE(input()->keyboardModifiers(), Qt::AltModifier);
227 Test::keyboardKeyPressed(KEY_LEFTSHIFT, timestamp++);
228 QCOMPARE(input()->keyboardModifiers(), Qt::AltModifier | Qt::ShiftModifier);
229 Test::keyboardKeyPressed(KEY_TAB, timestamp++);
230 Test::keyboardKeyReleased(KEY_TAB, timestamp++);
231
232 QVERIFY(tabboxAddedSpy.wait());
233 QVERIFY(workspace()->tabbox()->isGrabbed());
234
235 // release alt
236 Test::keyboardKeyReleased(KEY_LEFTSHIFT, timestamp++);
237 QCOMPARE(tabboxClosedSpy.count(), 0);
238 Test::keyboardKeyReleased(KEY_LEFTALT, timestamp++);
239 QCOMPARE(tabboxClosedSpy.count(), 1);
240 QCOMPARE(workspace()->tabbox()->isGrabbed(), false);
241 QCOMPARE(workspace()->activeWindow(), c1);
242
243 surface3.reset();
244 QVERIFY(Test::waitForWindowClosed(c3));
245 surface2.reset();
246 QVERIFY(Test::waitForWindowClosed(c2));
247 surface1.reset();
248 QVERIFY(Test::waitForWindowClosed(c1));
249}
250
252#include "tabbox_test.moc"
PointerInputRedirection * pointer() const
Definition input.h:220
void warp(const QPointF &pos)
void setActiveOutput(Output *output)
#define WAYLANDTEST_MAIN(TestObject)
Window * renderAndWaitForShown(KWayland::Client::Surface *surface, const QSize &size, const QColor &color, const QImage::Format &format=QImage::Format_ARGB32, int timeout=5000)
void keyboardKeyReleased(quint32 key, quint32 time)
void destroyWaylandConnection()
void setOutputConfig(const QList< QRect > &geometries)
void keyboardKeyPressed(quint32 key, quint32 time)
bool setupWaylandConnection(AdditionalWaylandInterfaces flags=AdditionalWaylandInterfaces())
std::unique_ptr< KWayland::Client::Surface > createSurface()
XdgToplevel * createXdgToplevelSurface(KWayland::Client::Surface *surface, QObject *parent=nullptr)
bool waitForWindowClosed(Window *window)
WaylandServer * waylandServer()
Workspace * workspace()
Definition workspace.h:830
InputRedirection * input()
Definition input.h:549