1 /*
2     KWin - the KDE window manager
3     This file is part of the KDE project.
4 
5     SPDX-FileCopyrightText: 2012 Martin Gräßlin <mgraesslin@kde.org>
6 
7     SPDX-License-Identifier: GPL-2.0-or-later
8 */
9 #include "input.h"
10 #include "virtualdesktops.h"
11 // KDE
12 #include <KConfigGroup>
13 
14 #include <QAction>
15 #include <QtTest>
16 
17 namespace KWin {
18 
19 int screen_number = 0;
20 
21 InputRedirection *InputRedirection::s_self = nullptr;
22 
registerShortcut(const QKeySequence & shortcut,QAction * action)23 void InputRedirection::registerShortcut(const QKeySequence &shortcut, QAction *action)
24 {
25     Q_UNUSED(shortcut)
26     Q_UNUSED(action)
27 }
28 
registerAxisShortcut(Qt::KeyboardModifiers modifiers,PointerAxisDirection axis,QAction * action)29 void InputRedirection::registerAxisShortcut(Qt::KeyboardModifiers modifiers, PointerAxisDirection axis, QAction *action)
30 {
31    Q_UNUSED(modifiers)
32    Q_UNUSED(axis)
33    Q_UNUSED(action)
34 }
35 
registerTouchpadSwipeShortcut(SwipeDirection,QAction *)36 void InputRedirection::registerTouchpadSwipeShortcut(SwipeDirection, QAction*)
37 {
38 }
39 
40 }
41 
42 Q_DECLARE_METATYPE(Qt::Orientation)
43 
44 using namespace KWin;
45 
46 class TestVirtualDesktops : public QObject
47 {
48     Q_OBJECT
49 private Q_SLOTS:
50     void init();
51     void cleanup();
52     void count_data();
53     void count();
54     void navigationWrapsAround_data();
55     void navigationWrapsAround();
56     void current_data();
57     void current();
58     void currentChangeOnCountChange_data();
59     void currentChangeOnCountChange();
60     void next_data();
61     void next();
62     void previous_data();
63     void previous();
64     void left_data();
65     void left();
66     void right_data();
67     void right();
68     void above_data();
69     void above();
70     void below_data();
71     void below();
72     void updateGrid_data();
73     void updateGrid();
74     void updateLayout_data();
75     void updateLayout();
76     void name_data();
77     void name();
78     void switchToShortcuts();
79     void changeRows();
80     void load();
81     void save();
82 
83 private:
84     void addDirectionColumns();
85     template<typename T>
86     void testDirection(const QString &actionName);
87 };
88 
init()89 void TestVirtualDesktops::init()
90 {
91     VirtualDesktopManager::create();
92     screen_number = 0;
93 }
94 
cleanup()95 void TestVirtualDesktops::cleanup()
96 {
97     delete VirtualDesktopManager::self();
98 }
99 
100 static const uint s_countInitValue = 2;
101 
count_data()102 void TestVirtualDesktops::count_data()
103 {
104     QTest::addColumn<uint>("request");
105     QTest::addColumn<uint>("result");
106     QTest::addColumn<bool>("signal");
107     QTest::addColumn<bool>("removedSignal");
108 
109     QTest::newRow("Minimum")       << (uint)1 << (uint)1 << true << true;
110     QTest::newRow("Below Minimum") << (uint)0 << (uint)1 << true << true;
111     QTest::newRow("Normal Value")  << (uint)10 << (uint)10 << true << false;
112     QTest::newRow("Maximum")       << VirtualDesktopManager::maximum() << VirtualDesktopManager::maximum() << true << false;
113     QTest::newRow("Above Maximum") << VirtualDesktopManager::maximum() + 1 << VirtualDesktopManager::maximum() << true << false;
114     QTest::newRow("Unchanged")     << s_countInitValue << s_countInitValue << false << false;
115 }
116 
count()117 void TestVirtualDesktops::count()
118 {
119     VirtualDesktopManager *vds = VirtualDesktopManager::self();
120     QCOMPARE(vds->count(), (uint)0);
121     // start with a useful desktop count
122     vds->setCount(s_countInitValue);
123 
124     QSignalSpy spy(vds, &VirtualDesktopManager::countChanged);
125     QSignalSpy desktopsRemoved(vds, &VirtualDesktopManager::desktopRemoved);
126 
127     auto vdToRemove = vds->desktops().last();
128 
129     QFETCH(uint, request);
130     QFETCH(uint, result);
131     QFETCH(bool, signal);
132     QFETCH(bool, removedSignal);
133     vds->setCount(request);
134     QCOMPARE(vds->count(), result);
135     QCOMPARE(spy.isEmpty(), !signal);
136     if (!spy.isEmpty()) {
137         QList<QVariant> arguments = spy.takeFirst();
138         QCOMPARE(arguments.count(), 2);
139         QCOMPARE(arguments.at(0).type(), QVariant::UInt);
140         QCOMPARE(arguments.at(1).type(), QVariant::UInt);
141         QCOMPARE(arguments.at(0).toUInt(), s_countInitValue);
142         QCOMPARE(arguments.at(1).toUInt(), result);
143     }
144     QCOMPARE(desktopsRemoved.isEmpty(), !removedSignal);
145     if (!desktopsRemoved.isEmpty()) {
146         QList<QVariant> arguments = desktopsRemoved.takeFirst();
147         QCOMPARE(arguments.count(), 1);
148         QCOMPARE(arguments.at(0).value<KWin::VirtualDesktop*>(), vdToRemove);
149     }
150 }
151 
navigationWrapsAround_data()152 void TestVirtualDesktops::navigationWrapsAround_data()
153 {
154     QTest::addColumn<bool>("init");
155     QTest::addColumn<bool>("request");
156     QTest::addColumn<bool>("result");
157     QTest::addColumn<bool>("signal");
158 
159     QTest::newRow("enable")        << false << true  << true  << true;
160     QTest::newRow("disable")       << true  << false << false << true;
161     QTest::newRow("keep enabled")  << true  << true  << true  << false;
162     QTest::newRow("keep disabled") << false << false << false << false;
163 }
164 
navigationWrapsAround()165 void TestVirtualDesktops::navigationWrapsAround()
166 {
167     VirtualDesktopManager *vds = VirtualDesktopManager::self();
168     QCOMPARE(vds->isNavigationWrappingAround(), false);
169     QFETCH(bool, init);
170     QFETCH(bool, request);
171     QFETCH(bool, result);
172     QFETCH(bool, signal);
173 
174     // set to init value
175     vds->setNavigationWrappingAround(init);
176     QCOMPARE(vds->isNavigationWrappingAround(), init);
177 
178     QSignalSpy spy(vds, &VirtualDesktopManager::navigationWrappingAroundChanged);
179     vds->setNavigationWrappingAround(request);
180     QCOMPARE(vds->isNavigationWrappingAround(), result);
181     QCOMPARE(spy.isEmpty(), !signal);
182 }
183 
current_data()184 void TestVirtualDesktops::current_data()
185 {
186     QTest::addColumn<uint>("count");
187     QTest::addColumn<uint>("init");
188     QTest::addColumn<uint>("request");
189     QTest::addColumn<uint>("result");
190     QTest::addColumn<bool>("signal");
191 
192     QTest::newRow("lower")         << (uint)4 << (uint)3 << (uint)2 << (uint)2 << true;
193     QTest::newRow("higher")        << (uint)4 << (uint)1 << (uint)2 << (uint)2 << true;
194     QTest::newRow("maximum")       << (uint)4 << (uint)1 << (uint)4 << (uint)4 << true;
195     QTest::newRow("above maximum") << (uint)4 << (uint)1 << (uint)5 << (uint)1 << false;
196     QTest::newRow("minimum")       << (uint)4 << (uint)2 << (uint)1 << (uint)1 << true;
197     QTest::newRow("below minimum") << (uint)4 << (uint)2 << (uint)0 << (uint)2 << false;
198     QTest::newRow("unchanged")     << (uint)4 << (uint)2 << (uint)2 << (uint)2 << false;
199 }
200 
current()201 void TestVirtualDesktops::current()
202 {
203     VirtualDesktopManager *vds = VirtualDesktopManager::self();
204     QCOMPARE(vds->current(), (uint)0);
205     QFETCH(uint, count);
206     vds->setCount(count);
207     QFETCH(uint, init);
208     QVERIFY(vds->setCurrent(init));
209     QCOMPARE(vds->current(), init);
210 
211     QSignalSpy spy(vds, &VirtualDesktopManager::currentChanged);
212 
213     QFETCH(uint, request);
214     QFETCH(uint, result);
215     QFETCH(bool, signal);
216     QCOMPARE(vds->setCurrent(request), signal);
217     QCOMPARE(vds->current(), result);
218     QCOMPARE(spy.isEmpty(), !signal);
219     if (!spy.isEmpty()) {
220         QList<QVariant> arguments = spy.takeFirst();
221         QCOMPARE(arguments.count(), 2);
222         QCOMPARE(arguments.at(0).type(), QVariant::UInt);
223         QCOMPARE(arguments.at(1).type(), QVariant::UInt);
224         QCOMPARE(arguments.at(0).toUInt(), init);
225         QCOMPARE(arguments.at(1).toUInt(), result);
226     }
227 }
228 
currentChangeOnCountChange_data()229 void TestVirtualDesktops::currentChangeOnCountChange_data()
230 {
231     QTest::addColumn<uint>("initCount");
232     QTest::addColumn<uint>("initCurrent");
233     QTest::addColumn<uint>("request");
234     QTest::addColumn<uint>("current");
235     QTest::addColumn<bool>("signal");
236 
237     QTest::newRow("increment")                << (uint)4 << (uint)2 << (uint)5 << (uint)2 << false;
238     QTest::newRow("increment on last")        << (uint)4 << (uint)4 << (uint)5 << (uint)4 << false;
239     QTest::newRow("decrement")                << (uint)4 << (uint)2 << (uint)3 << (uint)2 << false;
240     QTest::newRow("decrement on second last") << (uint)4 << (uint)3 << (uint)3 << (uint)3 << false;
241     QTest::newRow("decrement on last")        << (uint)4 << (uint)4 << (uint)3 << (uint)3 << true;
242     QTest::newRow("multiple decrement")       << (uint)4 << (uint)2 << (uint)1 << (uint)1 << true;
243 }
244 
currentChangeOnCountChange()245 void TestVirtualDesktops::currentChangeOnCountChange()
246 {
247     VirtualDesktopManager *vds = VirtualDesktopManager::self();
248     QFETCH(uint, initCount);
249     QFETCH(uint, initCurrent);
250     vds->setCount(initCount);
251     vds->setCurrent(initCurrent);
252 
253     QSignalSpy spy(vds, &VirtualDesktopManager::currentChanged);
254 
255     QFETCH(uint, request);
256     QFETCH(uint, current);
257     QFETCH(bool, signal);
258 
259     vds->setCount(request);
260     QCOMPARE(vds->current(), current);
261     QCOMPARE(spy.isEmpty(), !signal);
262 }
263 
addDirectionColumns()264 void TestVirtualDesktops::addDirectionColumns()
265 {
266     QTest::addColumn<uint>("initCount");
267     QTest::addColumn<uint>("initCurrent");
268     QTest::addColumn<bool>("wrap");
269     QTest::addColumn<uint>("result");
270 }
271 
272 template <typename T>
testDirection(const QString & actionName)273 void TestVirtualDesktops::testDirection(const QString &actionName)
274 {
275     VirtualDesktopManager *vds = VirtualDesktopManager::self();
276     QFETCH(uint, initCount);
277     QFETCH(uint, initCurrent);
278     vds->setCount(initCount);
279     vds->setCurrent(initCurrent);
280 
281     QFETCH(bool, wrap);
282     QFETCH(uint, result);
283     T functor;
284     QCOMPARE(functor(nullptr, wrap)->x11DesktopNumber(), result);
285 
286     vds->setNavigationWrappingAround(wrap);
287     vds->initShortcuts();
288     QAction *action = vds->findChild<QAction*>(actionName);
289     QVERIFY(action);
290     action->trigger();
291     QCOMPARE(vds->current(), result);
292     QCOMPARE(functor(initCurrent, wrap), result);
293 }
294 
next_data()295 void TestVirtualDesktops::next_data()
296 {
297     addDirectionColumns();
298 
299     QTest::newRow("one desktop, wrap")        << (uint)1 << (uint)1 << true  << (uint)1;
300     QTest::newRow("one desktop, no wrap")     << (uint)1 << (uint)1 << false << (uint)1;
301     QTest::newRow("desktops, wrap")           << (uint)4 << (uint)1 << true  << (uint)2;
302     QTest::newRow("desktops, no wrap")        << (uint)4 << (uint)1 << false << (uint)2;
303     QTest::newRow("desktops at end, wrap")    << (uint)4 << (uint)4 << true  << (uint)1;
304     QTest::newRow("desktops at end, no wrap") << (uint)4 << (uint)4 << false << (uint)4;
305 }
306 
next()307 void TestVirtualDesktops::next()
308 {
309     testDirection<DesktopNext>(QStringLiteral("Switch to Next Desktop"));
310 }
311 
previous_data()312 void TestVirtualDesktops::previous_data()
313 {
314     addDirectionColumns();
315 
316     QTest::newRow("one desktop, wrap")          << (uint)1 << (uint)1 << true  << (uint)1;
317     QTest::newRow("one desktop, no wrap")       << (uint)1 << (uint)1 << false << (uint)1;
318     QTest::newRow("desktops, wrap")             << (uint)4 << (uint)3 << true  << (uint)2;
319     QTest::newRow("desktops, no wrap")          << (uint)4 << (uint)3 << false << (uint)2;
320     QTest::newRow("desktops at start, wrap")    << (uint)4 << (uint)1 << true  << (uint)4;
321     QTest::newRow("desktops at start, no wrap") << (uint)4 << (uint)1 << false << (uint)1;
322 }
323 
previous()324 void TestVirtualDesktops::previous()
325 {
326     testDirection<DesktopPrevious>(QStringLiteral("Switch to Previous Desktop"));
327 }
328 
left_data()329 void TestVirtualDesktops::left_data()
330 {
331     addDirectionColumns();
332     QTest::newRow("one desktop, wrap")          << (uint)1 << (uint)1 << true  << (uint)1;
333     QTest::newRow("one desktop, no wrap")       << (uint)1 << (uint)1 << false << (uint)1;
334     QTest::newRow("desktops, wrap, 1st row")    << (uint)4 << (uint)2 << true  << (uint)1;
335     QTest::newRow("desktops, no wrap, 1st row") << (uint)4 << (uint)2 << false << (uint)1;
336     QTest::newRow("desktops, wrap, 2nd row")    << (uint)4 << (uint)4 << true  << (uint)3;
337     QTest::newRow("desktops, no wrap, 2nd row") << (uint)4 << (uint)4 << false << (uint)3;
338 
339     QTest::newRow("desktops at start, wrap, 1st row")    << (uint)4 << (uint)1 << true  << (uint)2;
340     QTest::newRow("desktops at start, no wrap, 1st row") << (uint)4 << (uint)1 << false << (uint)1;
341     QTest::newRow("desktops at start, wrap, 2nd row")    << (uint)4 << (uint)3 << true  << (uint)4;
342     QTest::newRow("desktops at start, no wrap, 2nd row") << (uint)4 << (uint)3 << false << (uint)3;
343 
344     QTest::newRow("non symmetric, start") << (uint)5 << (uint)5 << false << (uint)4;
345     QTest::newRow("non symmetric, end, no wrap") << (uint)5 << (uint)4 << false << (uint)4;
346     QTest::newRow("non symmetric, end, wrap") << (uint)5 << (uint)4 << true << (uint)5;
347 }
348 
left()349 void TestVirtualDesktops::left()
350 {
351     testDirection<DesktopLeft>(QStringLiteral("Switch One Desktop to the Left"));
352 }
353 
right_data()354 void TestVirtualDesktops::right_data()
355 {
356     addDirectionColumns();
357     QTest::newRow("one desktop, wrap")          << (uint)1 << (uint)1 << true  << (uint)1;
358     QTest::newRow("one desktop, no wrap")       << (uint)1 << (uint)1 << false << (uint)1;
359     QTest::newRow("desktops, wrap, 1st row")    << (uint)4 << (uint)1 << true  << (uint)2;
360     QTest::newRow("desktops, no wrap, 1st row") << (uint)4 << (uint)1 << false << (uint)2;
361     QTest::newRow("desktops, wrap, 2nd row")    << (uint)4 << (uint)3 << true  << (uint)4;
362     QTest::newRow("desktops, no wrap, 2nd row") << (uint)4 << (uint)3 << false << (uint)4;
363 
364     QTest::newRow("desktops at start, wrap, 1st row")    << (uint)4 << (uint)2 << true  << (uint)1;
365     QTest::newRow("desktops at start, no wrap, 1st row") << (uint)4 << (uint)2 << false << (uint)2;
366     QTest::newRow("desktops at start, wrap, 2nd row")    << (uint)4 << (uint)4 << true  << (uint)3;
367     QTest::newRow("desktops at start, no wrap, 2nd row") << (uint)4 << (uint)4 << false << (uint)4;
368 
369     QTest::newRow("non symmetric, start") << (uint)5 << (uint)4 << false << (uint)5;
370     QTest::newRow("non symmetric, end, no wrap") << (uint)5 << (uint)5 << false << (uint)5;
371     QTest::newRow("non symmetric, end, wrap") << (uint)5 << (uint)5 << true << (uint)4;
372 }
373 
right()374 void TestVirtualDesktops::right()
375 {
376     testDirection<DesktopRight>(QStringLiteral("Switch One Desktop to the Right"));
377 }
378 
above_data()379 void TestVirtualDesktops::above_data()
380 {
381     addDirectionColumns();
382     QTest::newRow("one desktop, wrap")             << (uint)1 << (uint)1 << true  << (uint)1;
383     QTest::newRow("one desktop, no wrap")          << (uint)1 << (uint)1 << false << (uint)1;
384     QTest::newRow("desktops, wrap, 1st column")    << (uint)4 << (uint)3 << true  << (uint)1;
385     QTest::newRow("desktops, no wrap, 1st column") << (uint)4 << (uint)3 << false << (uint)1;
386     QTest::newRow("desktops, wrap, 2nd column")    << (uint)4 << (uint)4 << true  << (uint)2;
387     QTest::newRow("desktops, no wrap, 2nd column") << (uint)4 << (uint)4 << false << (uint)2;
388 
389     QTest::newRow("desktops at start, wrap, 1st column")    << (uint)4 << (uint)1 << true  << (uint)3;
390     QTest::newRow("desktops at start, no wrap, 1st column") << (uint)4 << (uint)1 << false << (uint)1;
391     QTest::newRow("desktops at start, wrap, 2nd column")    << (uint)4 << (uint)2 << true  << (uint)4;
392     QTest::newRow("desktops at start, no wrap, 2nd column") << (uint)4 << (uint)2 << false << (uint)2;
393 }
394 
above()395 void TestVirtualDesktops::above()
396 {
397     testDirection<DesktopAbove>(QStringLiteral("Switch One Desktop Up"));
398 }
399 
below_data()400 void TestVirtualDesktops::below_data()
401 {
402     addDirectionColumns();
403     QTest::newRow("one desktop, wrap")             << (uint)1 << (uint)1 << true  << (uint)1;
404     QTest::newRow("one desktop, no wrap")          << (uint)1 << (uint)1 << false << (uint)1;
405     QTest::newRow("desktops, wrap, 1st column")    << (uint)4 << (uint)1 << true  << (uint)3;
406     QTest::newRow("desktops, no wrap, 1st column") << (uint)4 << (uint)1 << false << (uint)3;
407     QTest::newRow("desktops, wrap, 2nd column")    << (uint)4 << (uint)2 << true  << (uint)4;
408     QTest::newRow("desktops, no wrap, 2nd column") << (uint)4 << (uint)2 << false << (uint)4;
409 
410     QTest::newRow("desktops at start, wrap, 1st column")    << (uint)4 << (uint)3 << true  << (uint)1;
411     QTest::newRow("desktops at start, no wrap, 1st column") << (uint)4 << (uint)3 << false << (uint)3;
412     QTest::newRow("desktops at start, wrap, 2nd column")    << (uint)4 << (uint)4 << true  << (uint)2;
413     QTest::newRow("desktops at start, no wrap, 2nd column") << (uint)4 << (uint)4 << false << (uint)4;
414 }
415 
below()416 void TestVirtualDesktops::below()
417 {
418     testDirection<DesktopBelow>(QStringLiteral("Switch One Desktop Down"));
419 }
420 
updateGrid_data()421 void TestVirtualDesktops::updateGrid_data()
422 {
423     QTest::addColumn<uint>("initCount");
424     QTest::addColumn<QSize>("size");
425     QTest::addColumn<Qt::Orientation>("orientation");
426     QTest::addColumn<QPoint>("coords");
427     QTest::addColumn<uint>("desktop");
428     const Qt::Orientation h = Qt::Horizontal;
429     const Qt::Orientation v = Qt::Vertical;
430 
431     QTest::newRow("one desktop, h")    << (uint)1 << QSize(1, 1) << h << QPoint(0, 0) << (uint)1;
432     QTest::newRow("one desktop, v")    << (uint)1 << QSize(1, 1) << v << QPoint(0, 0) << (uint)1;
433     QTest::newRow("one desktop, h, 0") << (uint)1 << QSize(1, 1) << h << QPoint(1, 0) << (uint)0;
434     QTest::newRow("one desktop, v, 0") << (uint)1 << QSize(1, 1) << v << QPoint(0, 1) << (uint)0;
435 
436     QTest::newRow("two desktops, h, 1") << (uint)2 << QSize(2, 1) << h << QPoint(0, 0) << (uint)1;
437     QTest::newRow("two desktops, h, 2") << (uint)2 << QSize(2, 1) << h << QPoint(1, 0) << (uint)2;
438     QTest::newRow("two desktops, h, 3") << (uint)2 << QSize(2, 1) << h << QPoint(0, 1) << (uint)0;
439     QTest::newRow("two desktops, h, 4") << (uint)2 << QSize(2, 1) << h << QPoint(2, 0) << (uint)0;
440 
441     QTest::newRow("two desktops, v, 1") << (uint)2 << QSize(2, 1) << v << QPoint(0, 0) << (uint)1;
442     QTest::newRow("two desktops, v, 2") << (uint)2 << QSize(2, 1) << v << QPoint(1, 0) << (uint)2;
443     QTest::newRow("two desktops, v, 3") << (uint)2 << QSize(2, 1) << v << QPoint(0, 1) << (uint)0;
444     QTest::newRow("two desktops, v, 4") << (uint)2 << QSize(2, 1) << v << QPoint(2, 0) << (uint)0;
445 
446     QTest::newRow("four desktops, h, one row, 1") << (uint)4 << QSize(4, 1) << h << QPoint(0, 0) << (uint)1;
447     QTest::newRow("four desktops, h, one row, 2") << (uint)4 << QSize(4, 1) << h << QPoint(1, 0) << (uint)2;
448     QTest::newRow("four desktops, h, one row, 3") << (uint)4 << QSize(4, 1) << h << QPoint(2, 0) << (uint)3;
449     QTest::newRow("four desktops, h, one row, 4") << (uint)4 << QSize(4, 1) << h << QPoint(3, 0) << (uint)4;
450 
451     QTest::newRow("four desktops, v, one column, 1") << (uint)4 << QSize(1, 4) << v << QPoint(0, 0) << (uint)1;
452     QTest::newRow("four desktops, v, one column, 2") << (uint)4 << QSize(1, 4) << v << QPoint(0, 1) << (uint)2;
453     QTest::newRow("four desktops, v, one column, 3") << (uint)4 << QSize(1, 4) << v << QPoint(0, 2) << (uint)3;
454     QTest::newRow("four desktops, v, one column, 4") << (uint)4 << QSize(1, 4) << v << QPoint(0, 3) << (uint)4;
455 
456     QTest::newRow("four desktops, h, grid, 1") << (uint)4 << QSize(2, 2) << h << QPoint(0, 0) << (uint)1;
457     QTest::newRow("four desktops, h, grid, 2") << (uint)4 << QSize(2, 2) << h << QPoint(1, 0) << (uint)2;
458     QTest::newRow("four desktops, h, grid, 3") << (uint)4 << QSize(2, 2) << h << QPoint(0, 1) << (uint)3;
459     QTest::newRow("four desktops, h, grid, 4") << (uint)4 << QSize(2, 2) << h << QPoint(1, 1) << (uint)4;
460     QTest::newRow("four desktops, h, grid, 0/3") << (uint)4 << QSize(2, 2) << h << QPoint(0, 3) << (uint)0;
461 
462     QTest::newRow("three desktops, h, grid, 1") << (uint)3 << QSize(2, 2) << h << QPoint(0, 0) << (uint)1;
463     QTest::newRow("three desktops, h, grid, 2") << (uint)3 << QSize(2, 2) << h << QPoint(1, 0) << (uint)2;
464     QTest::newRow("three desktops, h, grid, 3") << (uint)3 << QSize(2, 2) << h << QPoint(0, 1) << (uint)3;
465     QTest::newRow("three desktops, h, grid, 4") << (uint)3 << QSize(2, 2) << h << QPoint(1, 1) << (uint)0;
466 }
467 
updateGrid()468 void TestVirtualDesktops::updateGrid()
469 {
470     VirtualDesktopManager *vds = VirtualDesktopManager::self();
471     QFETCH(uint, initCount);
472     vds->setCount(initCount);
473     VirtualDesktopGrid grid;
474 
475     QFETCH(QSize, size);
476     QFETCH(Qt::Orientation, orientation);
477     QCOMPARE(vds->desktops().count(), int(initCount));
478     grid.update(size, orientation, vds->desktops());
479     QCOMPARE(grid.size(), size);
480     QCOMPARE(grid.width(), size.width());
481     QCOMPARE(grid.height(), size.height());
482     QFETCH(QPoint, coords);
483     QFETCH(uint, desktop);
484     QCOMPARE(grid.at(coords), vds->desktopForX11Id(desktop));
485     if (desktop != 0) {
486         QCOMPARE(grid.gridCoords(desktop), coords);
487     }
488 }
489 
updateLayout_data()490 void TestVirtualDesktops::updateLayout_data()
491 {
492     QTest::addColumn<uint>("desktop");
493     QTest::addColumn<QSize>("result");
494 
495     QTest::newRow("01") << (uint)1  << QSize(1, 1);
496     QTest::newRow("02") << (uint)2  << QSize(1, 2);
497     QTest::newRow("03") << (uint)3  << QSize(2, 2);
498     QTest::newRow("04") << (uint)4  << QSize(2, 2);
499     QTest::newRow("05") << (uint)5  << QSize(3, 2);
500     QTest::newRow("06") << (uint)6  << QSize(3, 2);
501     QTest::newRow("07") << (uint)7  << QSize(4, 2);
502     QTest::newRow("08") << (uint)8  << QSize(4, 2);
503     QTest::newRow("09") << (uint)9  << QSize(5, 2);
504     QTest::newRow("10") << (uint)10 << QSize(5, 2);
505     QTest::newRow("11") << (uint)11 << QSize(6, 2);
506     QTest::newRow("12") << (uint)12 << QSize(6, 2);
507     QTest::newRow("13") << (uint)13 << QSize(7, 2);
508     QTest::newRow("14") << (uint)14 << QSize(7, 2);
509     QTest::newRow("15") << (uint)15 << QSize(8, 2);
510     QTest::newRow("16") << (uint)16 << QSize(8, 2);
511     QTest::newRow("17") << (uint)17 << QSize(9, 2);
512     QTest::newRow("18") << (uint)18 << QSize(9, 2);
513     QTest::newRow("19") << (uint)19 << QSize(10, 2);
514     QTest::newRow("20") << (uint)20 << QSize(10, 2);
515 }
516 
updateLayout()517 void TestVirtualDesktops::updateLayout()
518 {
519     VirtualDesktopManager *vds = VirtualDesktopManager::self();
520     QSignalSpy spy(vds, &VirtualDesktopManager::layoutChanged);
521     // call update layout - implicitly through setCount
522     QFETCH(uint, desktop);
523     QFETCH(QSize, result);
524     vds->setCount(desktop);
525     QCOMPARE(vds->grid().size(), result);
526     QCOMPARE(spy.count(), 1);
527     const QVariantList &arguments = spy.at(0);
528     QCOMPARE(arguments.at(0).toInt(), result.width());
529     QCOMPARE(arguments.at(1).toInt(), result.height());
530     // calling update layout again should not change anything
531     vds->updateLayout();
532     QCOMPARE(vds->grid().size(), result);
533     QCOMPARE(spy.count(), 2);
534     const QVariantList &arguments2 = spy.at(1);
535     QCOMPARE(arguments2.at(0).toInt(), result.width());
536     QCOMPARE(arguments2.at(1).toInt(), result.height());
537 }
538 
name_data()539 void TestVirtualDesktops::name_data()
540 {
541     QTest::addColumn<uint>("initCount");
542     QTest::addColumn<uint>("desktop");
543     QTest::addColumn<QString>("desktopName");
544 
545     QTest::newRow("desktop 1") << (uint)5 << (uint)1 << "Desktop 1";
546     QTest::newRow("desktop 2") << (uint)5 << (uint)2 << "Desktop 2";
547     QTest::newRow("desktop 3") << (uint)5 << (uint)3 << "Desktop 3";
548     QTest::newRow("desktop 4") << (uint)5 << (uint)4 << "Desktop 4";
549     QTest::newRow("desktop 5") << (uint)5 << (uint)5 << "Desktop 5";
550 }
551 
name()552 void TestVirtualDesktops::name()
553 {
554     VirtualDesktopManager *vds = VirtualDesktopManager::self();
555     QFETCH(uint, initCount);
556     vds->setCount(initCount);
557     QFETCH(uint, desktop);
558 
559     const VirtualDesktop *vd = vds->desktopForX11Id(desktop);
560     QTEST(vd->name(), "desktopName");
561 }
562 
switchToShortcuts()563 void TestVirtualDesktops::switchToShortcuts()
564 {
565     VirtualDesktopManager *vds = VirtualDesktopManager::self();
566     vds->setCount(vds->maximum());
567     vds->setCurrent(vds->maximum());
568     QCOMPARE(vds->current(), vds->maximum());
569     vds->initShortcuts();
570     const QString toDesktop = QStringLiteral("Switch to Desktop %1");
571     for (uint i=1; i<=vds->maximum(); ++i) {
572         const QString desktop(toDesktop.arg(i));
573         QAction *action = vds->findChild<QAction*>(desktop);
574         QVERIFY2(action, desktop.toUtf8().constData());
575         action->trigger();
576         QCOMPARE(vds->current(), i);
577     }
578     // invoke switchTo not from a QAction
579     QMetaObject::invokeMethod(vds, "slotSwitchTo");
580     // should still be on max
581     QCOMPARE(vds->current(), vds->maximum());
582 }
583 
changeRows()584 void TestVirtualDesktops::changeRows()
585 {
586     VirtualDesktopManager *vds = VirtualDesktopManager::self();
587 
588     vds->setCount(4);
589     vds->setRows(4);
590     QCOMPARE(vds->rows(), 4);
591 
592     vds->setRows(5);
593     QCOMPARE(vds->rows(), 4);
594 
595     vds->setCount(2);
596     QCOMPARE(vds->rows(), 2);
597 }
598 
load()599 void TestVirtualDesktops::load()
600 {
601     VirtualDesktopManager *vds = VirtualDesktopManager::self();
602     // no config yet, load should not change anything
603     vds->load();
604     QCOMPARE(vds->count(), (uint)0);
605     // empty config should create one desktop
606     KSharedConfig::Ptr config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
607     vds->setConfig(config);
608     vds->load();
609     QCOMPARE(vds->count(), (uint)1);
610     // setting a sensible number
611     config->group("Desktops").writeEntry("Number", 4);
612     vds->load();
613     QCOMPARE(vds->count(), (uint)4);
614 
615     // setting the config value and reloading should update
616     config->group("Desktops").writeEntry("Number", 5);
617     vds->load();
618     QCOMPARE(vds->count(), (uint)5);
619 }
620 
save()621 void TestVirtualDesktops::save()
622 {
623     VirtualDesktopManager *vds = VirtualDesktopManager::self();
624     vds->setCount(4);
625     // no config yet, just to ensure it actually works
626     vds->save();
627     KSharedConfig::Ptr config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
628     vds->setConfig(config);
629 
630     // now save should create the group "Desktops"
631     QCOMPARE(config->hasGroup("Desktops"), false);
632     vds->save();
633     QCOMPARE(config->hasGroup("Desktops"), true);
634     KConfigGroup desktops = config->group("Desktops");
635     QCOMPARE(desktops.readEntry<int>("Number", 1), 4);
636     QCOMPARE(desktops.hasKey("Name_1"), false);
637     QCOMPARE(desktops.hasKey("Name_2"), false);
638     QCOMPARE(desktops.hasKey("Name_3"), false);
639     QCOMPARE(desktops.hasKey("Name_4"), false);
640 }
641 
642 QTEST_MAIN(TestVirtualDesktops)
643 #include "test_virtual_desktops.moc"
644