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 #ifndef KWIN_VIRTUAL_DESKTOPS_H
10 #define KWIN_VIRTUAL_DESKTOPS_H
11 // KWin
12 #include <kwinglobals.h>
13 #include <kwin_export.h>
14 // Qt includes
15 #include <QObject>
16 #include <QPoint>
17 #include <QPointer>
18 #include <QSize>
19
20 // KDE includes
21 #include <KConfig>
22 #include <KSharedConfig>
23
24 class KLocalizedString;
25 class NETRootInfo;
26 class QAction;
27
28 namespace KWaylandServer
29 {
30 class PlasmaVirtualDesktopManagementInterface;
31 }
32
33 namespace KWin {
34
35 class KWIN_EXPORT VirtualDesktop : public QObject
36 {
37 Q_OBJECT
38 Q_PROPERTY(QString id READ id CONSTANT)
39 Q_PROPERTY(uint x11DesktopNumber READ x11DesktopNumber NOTIFY x11DesktopNumberChanged)
40 Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
41 public:
42 explicit VirtualDesktop(QObject *parent = nullptr);
43 ~VirtualDesktop() override;
44
45 void setId(const QString &id);
id()46 QString id() const {
47 return m_id;
48 }
49
50 void setName(const QString &name);
name()51 QString name() const {
52 return m_name;
53 }
54
55 void setX11DesktopNumber(uint number);
x11DesktopNumber()56 uint x11DesktopNumber() const {
57 return m_x11DesktopNumber;
58 }
59
60 Q_SIGNALS:
61 void nameChanged();
62 void x11DesktopNumberChanged();
63 /**
64 * Emitted just before the desktop gets destroyed.
65 */
66 void aboutToBeDestroyed();
67
68 private:
69 QString m_id;
70 QString m_name;
71 int m_x11DesktopNumber = 0;
72
73 };
74
75 /**
76 * @brief Two dimensional grid containing the ID of the virtual desktop at a specific position
77 * in the grid.
78 *
79 * The VirtualDesktopGrid represents a visual layout of the Virtual Desktops as they are in e.g.
80 * a Pager. This grid is used for getting a desktop next to a given desktop in any direction by
81 * making use of the layout information. This allows navigation like move to desktop on left.
82 */
83 class VirtualDesktopGrid
84 {
85 public:
86 VirtualDesktopGrid();
87 ~VirtualDesktopGrid();
88 void update(const QSize &size, Qt::Orientation orientation, const QVector<VirtualDesktop*> &desktops);
89 /**
90 * @returns The coords of desktop @a id in grid units.
91 */
92 QPoint gridCoords(uint id) const;
93 /**
94 * @returns The coords of desktop @a vd in grid units.
95 */
96 QPoint gridCoords(VirtualDesktop *vd) const;
97 /**
98 * @returns The desktop at the point @a coords or 0 if no desktop exists at that
99 * point. @a coords is to be in grid units.
100 */
101 VirtualDesktop *at(const QPoint &coords) const;
102 int width() const;
103 int height() const;
104 const QSize &size() const;
105 private:
106 QSize m_size;
107 QVector<QVector<VirtualDesktop*>> m_grid;
108 };
109
110 /**
111 * @brief Manages the number of available virtual desktops, the layout of those and which virtual
112 * desktop is the current one.
113 *
114 * This manager is responsible for Virtual Desktop handling inside KWin. It has a property for the
115 * count of available virtual desktops and a property for the currently active virtual desktop. All
116 * changes to the number of virtual desktops and the current virtual desktop need to go through this
117 * manager.
118 *
119 * On all changes a signal is emitted and interested parties should connect to the signal. The manager
120 * itself does not interact with other parts of the system. E.g. it does not hide/show windows of
121 * desktop changes. This is outside the scope of this manager.
122 *
123 * Internally the manager organizes the virtual desktops in a grid allowing to navigate over the
124 * virtual desktops. For this a set of convenient methods are available which allow to get the id
125 * of an adjacent desktop or to switch to an adjacent desktop. Interested parties should make use of
126 * these methods and not replicate the logic to switch to the next desktop.
127 */
128 class KWIN_EXPORT VirtualDesktopManager : public QObject
129 {
130 Q_OBJECT
131 /**
132 * The number of virtual desktops currently available.
133 * The ids of the virtual desktops are in the range [1, VirtualDesktopManager::maximum()].
134 */
135 Q_PROPERTY(uint count READ count WRITE setCount NOTIFY countChanged)
136 /**
137 * The id of the virtual desktop which is currently in use.
138 */
139 Q_PROPERTY(uint current READ current WRITE setCurrent NOTIFY currentChanged)
140 /**
141 * Whether navigation in the desktop layout wraps around at the borders.
142 */
143 Q_PROPERTY(bool navigationWrappingAround READ isNavigationWrappingAround WRITE setNavigationWrappingAround NOTIFY navigationWrappingAroundChanged)
144 public:
145 ~VirtualDesktopManager() override;
146 /**
147 * @internal, for X11 case
148 */
149 void setRootInfo(NETRootInfo *info);
150 /**
151 * @internal, for Wayland case
152 */
153 void setVirtualDesktopManagement(KWaylandServer::PlasmaVirtualDesktopManagementInterface *management);
154 /**
155 * @internal
156 */
157 void setConfig(KSharedConfig::Ptr config);
158 /**
159 * @returns Total number of desktops currently in existence.
160 * @see setCount
161 * @see countChanged
162 */
163 uint count() const;
164 /**
165 * @returns the number of rows the layout has.
166 * @see setRows
167 * @see rowsChanged
168 */
169 uint rows() const;
170 /**
171 * @returns The ID of the current desktop.
172 * @see setCurrent
173 * @see currentChanged
174 */
175 uint current() const;
176 /**
177 * @returns The current desktop
178 * @see setCurrent
179 * @see currentChanged
180 */
181 VirtualDesktop *currentDesktop() const;
182 /**
183 * Moves to the desktop through the algorithm described by Direction.
184 * @param wrap If @c true wraps around to the other side of the layout
185 * @see setCurrent
186 */
187 template <typename Direction>
188 void moveTo(bool wrap = false);
189
190 /**
191 * @returns @c true if navigation at borders of layout wraps around, @c false otherwise
192 * @see setNavigationWrappingAround
193 * @see navigationWrappingAroundChanged
194 */
195 bool isNavigationWrappingAround() const;
196
197 /**
198 * @returns The layout aware virtual desktop grid used by this manager.
199 */
200 const VirtualDesktopGrid &grid() const;
201
202 /**
203 * @returns The ID of the desktop above desktop @a id. Wraps around to the bottom of
204 * the layout if @a wrap is set. If @a id is not set use the current one.
205 */
206 uint above(uint id = 0, bool wrap = true) const;
207 /**
208 * @returns The desktop above desktop @a desktop. Wraps around to the bottom of
209 * the layout if @a wrap is set. If @a desktop is @c null use the current one.
210 */
211 VirtualDesktop *above(VirtualDesktop *desktop, bool wrap = true) const;
212 /**
213 * @returns The ID of the desktop to the right of desktop @a id. Wraps around to the
214 * left of the layout if @a wrap is set. If @a id is not set use the current one.
215 */
216 uint toRight(uint id = 0, bool wrap = true) const;
217 /**
218 * @returns The desktop to the right of desktop @a desktop. Wraps around to the
219 * left of the layout if @a wrap is set. If @a desktop is @c null use the current one.
220 */
221 VirtualDesktop *toRight(VirtualDesktop *desktop, bool wrap = true) const;
222 /**
223 * @returns The ID of the desktop below desktop @a id. Wraps around to the top of the
224 * layout if @a wrap is set. If @a id is not set use the current one.
225 */
226 uint below(uint id = 0, bool wrap = true) const;
227 /**
228 * @returns The desktop below desktop @a desktop. Wraps around to the top of the
229 * layout if @a wrap is set. If @a desktop is @c null use the current one.
230 */
231 VirtualDesktop *below(VirtualDesktop *desktop, bool wrap = true) const;
232 /**
233 * @returns The ID of the desktop to the left of desktop @a id. Wraps around to the
234 * right of the layout if @a wrap is set. If @a id is not set use the current one.
235 */
236 uint toLeft(uint id = 0, bool wrap = true) const;
237 /**
238 * @returns The desktop to the left of desktop @a desktop. Wraps around to the
239 * right of the layout if @a wrap is set. If @a desktop is @c null use the current one.
240 */
241 VirtualDesktop *toLeft(VirtualDesktop *desktop, bool wrap = true) const;
242 /**
243 * @returns The desktop after the desktop @a desktop. Wraps around to the first
244 * desktop if @a wrap is set. If @a desktop is @c null use the current desktop.
245 */
246 VirtualDesktop *next(VirtualDesktop *desktop = nullptr, bool wrap = true) const;
247 /**
248 * @returns The desktop in front of the desktop @a desktop. Wraps around to the
249 * last desktop if @a wrap is set. If @a desktop is @c null use the current desktop.
250 */
251 VirtualDesktop *previous(VirtualDesktop *desktop = nullptr, bool wrap = true) const;
252
253 void initShortcuts();
254
255 /**
256 * @returns all currently managed VirtualDesktops
257 */
desktops()258 QVector<VirtualDesktop*> desktops() const {
259 return m_desktops;
260 }
261
262 /**
263 * @returns The VirtualDesktop for the x11 @p id, if no such VirtualDesktop @c null is returned
264 */
265 VirtualDesktop *desktopForX11Id(uint id) const;
266
267 /**
268 * @returns The VirtualDesktop for the internal desktop string @p id, if no such VirtualDesktop @c null is returned
269 */
270 VirtualDesktop *desktopForId(const QString &id) const;
271
272 /**
273 * Create a new virtual desktop at the requested position.
274 * The difference with setCount is that setCount always adds new desktops at the end of the chain. The Id is automatically generated.
275 * @param position The position of the desktop. It should be in range [0, count].
276 * @param name The name for the new desktop, if empty the default name will be used.
277 * @returns the new VirtualDesktop, nullptr if we reached the maximum number of desktops
278 */
279 VirtualDesktop *createVirtualDesktop(uint position, const QString &name = QString());
280
281 /**
282 * Remove the virtual desktop identified by id, if it exists
283 * difference with setCount is that is possible to remove an arbitrary desktop,
284 * not only the last one.
285 * @param id the string id of the desktop to remove
286 */
287 void removeVirtualDesktop(const QString &id);
288
289 /**
290 * Updates the net root info for new number of desktops
291 */
292 void updateRootInfo();
293
294 /**
295 * @returns The maximum number of desktops that KWin supports.
296 */
297 static uint maximum();
298
299 public Q_SLOTS:
300 /**
301 * Set the number of available desktops to @a count. This function overrides any previous
302 * grid layout.
303 * There needs to be at least one virtual desktop and the new value is capped at the maximum
304 * number of desktops. A caller of this function cannot expect that the change has been applied.
305 * It is the callers responsibility to either check the numberOfDesktops or connect to the
306 * countChanged signal.
307 *
308 * In case the @ref current desktop is on a desktop higher than the new count, the current desktop
309 * is changed to be the new desktop with highest id. In that situation the signal desktopRemoved
310 * is emitted.
311 * @param count The new number of desktops to use
312 * @see count
313 * @see maximum
314 * @see countChanged
315 * @see desktopCreated
316 * @see desktopRemoved
317 */
318 void setCount(uint count);
319 /**
320 * Set the current desktop to @a current.
321 * @returns True on success, false otherwise.
322 * @see current
323 * @see currentChanged
324 * @see moveTo
325 */
326 bool setCurrent(uint current);
327 /**
328 * Set the current desktop to @a current.
329 * @returns True on success, false otherwise.
330 * @see current
331 * @see currentChanged
332 * @see moveTo
333 */
334 bool setCurrent(VirtualDesktop *current);
335 /**
336 * Updates the layout to a new number of rows. The number of columns will be calculated accordingly
337 */
338 void setRows(uint rows);
339 /**
340 * Called from within setCount() to ensure the desktop layout is still valid.
341 */
342 void updateLayout();
343 /**
344 * @param enabled wrapping around borders for navigation in desktop layout
345 * @see isNavigationWrappingAround
346 * @see navigationWrappingAroundChanged
347 */
348 void setNavigationWrappingAround(bool enabled);
349 /**
350 * Loads number of desktops and names from configuration file
351 */
352 void load();
353 /**
354 * Saves number of desktops and names to configuration file
355 */
356 void save();
357
358 Q_SIGNALS:
359 /**
360 * Signal emitted whenever the number of virtual desktops changes.
361 * @param previousCount The number of desktops prior to the change
362 * @param newCount The new current number of desktops
363 */
364 void countChanged(uint previousCount, uint newCount);
365
366 /**
367 * Signal when the number of rows in the layout changes
368 * @param rows number of rows
369 */
370 void rowsChanged(uint rows);
371
372 /**
373 * A new desktop has been created
374 * @param desktop the new just crated desktop
375 */
376 void desktopCreated(KWin::VirtualDesktop *desktop);
377
378 /**
379 * A desktop has been removed and is about to be deleted
380 * @param desktop the desktop that has been removed.
381 * It's guaranteed to stil la valid pointer when the signal arrives,
382 * but it's about to be deleted.
383 */
384 void desktopRemoved(KWin::VirtualDesktop *desktop);
385
386 /**
387 * Signal emitted whenever the current desktop changes.
388 * @param previousDesktop The virtual desktop changed from
389 * @param newDesktop The virtual desktop changed to
390 */
391 void currentChanged(uint previousDesktop, uint newDesktop);
392 /**
393 * Signal emitted whenever the desktop layout changes.
394 * @param columns The new number of columns in the layout
395 * @param rows The new number of rows in the layout
396 */
397 void layoutChanged(int columns, int rows);
398 /**
399 * Signal emitted whenever the navigationWrappingAround property changes.
400 */
401 void navigationWrappingAroundChanged();
402
403 private Q_SLOTS:
404 /**
405 * Common slot for all "Switch to Desktop n" shortcuts.
406 * This method uses the sender() method to access some data.
407 * DO NOT CALL DIRECTLY! ONLY TO BE USED FROM AN ACTION!
408 */
409 void slotSwitchTo();
410 /**
411 * Slot for switch to next desktop action.
412 */
413 void slotNext();
414 /**
415 * Slot for switch to previous desktop action.
416 */
417 void slotPrevious();
418 /**
419 * Slot for switch to right desktop action.
420 */
421 void slotRight();
422 /**
423 * Slot for switch to left desktop action.
424 */
425 void slotLeft();
426 /**
427 * Slot for switch to desktop above action.
428 */
429 void slotUp();
430 /**
431 * Slot for switch to desktop below action.
432 */
433 void slotDown();
434
435 private:
436 /**
437 * Generate a desktop layout from EWMH _NET_DESKTOP_LAYOUT property parameters.
438 */
439 void setNETDesktopLayout(Qt::Orientation orientation, uint width, uint height, int startingCorner);
440 /**
441 * @returns A default name for the given @p desktop
442 */
443 QString defaultName(int desktop) const;
444 /**
445 * Creates all the global keyboard shortcuts for "Switch To Desktop n" actions.
446 */
447 void initSwitchToShortcuts();
448 /**
449 * Creates an action and connects it to the @p slot in this Manager. This method is
450 * meant to be used for the case that an additional information needs to be stored in
451 * the action and the label.
452 * @param name The name of the action to be created
453 * @param label The localized name for the action to be created
454 * @param value An additional value added to the label and to the created action
455 * @param key The global shortcut for the action
456 * @param slot The slot to invoke when the action is triggered
457 */
458 QAction *addAction(const QString &name, const KLocalizedString &label, uint value, const QKeySequence &key, void (VirtualDesktopManager::*slot)());
459 /**
460 * Creates an action and connects it to the @p slot in this Manager.
461 * Overloaded method for the case that no additional value needs to be passed to the action and
462 * no global shortcut is defined by default.
463 * @param name The name of the action to be created
464 * @param label The localized name for the action to be created
465 * @param slot The slot to invoke when the action is triggered
466 */
467 QAction *addAction(const QString &name, const QString &label, void (VirtualDesktopManager::*slot)());
468
469 QVector<VirtualDesktop*> m_desktops;
470 QPointer<VirtualDesktop> m_current;
471 quint32 m_rows = 2;
472 bool m_navigationWrapsAround;
473 VirtualDesktopGrid m_grid;
474 // TODO: QPointer
475 NETRootInfo *m_rootInfo;
476 KWaylandServer::PlasmaVirtualDesktopManagementInterface *m_virtualDesktopManagement = nullptr;
477 KSharedConfig::Ptr m_config;
478
479 KWIN_SINGLETON_VARIABLE(VirtualDesktopManager, s_manager)
480 };
481
482 /**
483 * Function object to select the desktop above in the layout.
484 * Note: does not switch to the desktop!
485 */
486 class DesktopAbove
487 {
488 public:
DesktopAbove()489 DesktopAbove() {}
490 /**
491 * @param desktop The desktop from which the desktop above should be selected. If @c 0 the current desktop is used
492 * @param wrap Whether to wrap around if already topmost desktop
493 * @returns Id of the desktop above @p desktop
494 */
operator()495 uint operator() (uint desktop, bool wrap) {
496 return (*this)(VirtualDesktopManager::self()->desktopForX11Id(desktop), wrap)->x11DesktopNumber();
497 }
498 /**
499 * @param desktop The desktop from which the desktop above should be selected. If @c 0 the current desktop is used
500 * @param wrap Whether to wrap around if already topmost desktop
501 * @returns the desktop above @p desktop
502 */
operator()503 VirtualDesktop *operator() (VirtualDesktop *desktop, bool wrap) {
504 return VirtualDesktopManager::self()->above(desktop, wrap);
505 }
506 };
507
508 /**
509 * Function object to select the desktop below in the layout.
510 * Note: does not switch to the desktop!
511 */
512 class DesktopBelow
513 {
514 public:
DesktopBelow()515 DesktopBelow() {}
516 /**
517 * @param desktop The desktop from which the desktop below should be selected. If @c 0 the current desktop is used
518 * @param wrap Whether to wrap around if already lowest desktop
519 * @returns Id of the desktop below @p desktop
520 */
operator()521 uint operator() (uint desktop, bool wrap) {
522 return (*this)(VirtualDesktopManager::self()->desktopForX11Id(desktop), wrap)->x11DesktopNumber();
523 }
524 /**
525 * @param desktop The desktop from which the desktop below should be selected. If @c 0 the current desktop is used
526 * @param wrap Whether to wrap around if already lowest desktop
527 * @returns the desktop below @p desktop
528 */
operator()529 VirtualDesktop *operator() (VirtualDesktop *desktop, bool wrap) {
530 return VirtualDesktopManager::self()->below(desktop, wrap);
531 }
532 };
533
534 /**
535 * Function object to select the desktop to the left in the layout.
536 * Note: does not switch to the desktop!
537 */
538 class DesktopLeft
539 {
540 public:
DesktopLeft()541 DesktopLeft() {}
542 /**
543 * @param desktop The desktop from which the desktop on the left should be selected. If @c 0 the current desktop is used
544 * @param wrap Whether to wrap around if already leftmost desktop
545 * @returns Id of the desktop left of @p desktop
546 */
operator()547 uint operator() (uint desktop, bool wrap) {
548 return (*this)(VirtualDesktopManager::self()->desktopForX11Id(desktop), wrap)->x11DesktopNumber();
549 }
550 /**
551 * @param desktop The desktop from which the desktop on the left should be selected. If @c 0 the current desktop is used
552 * @param wrap Whether to wrap around if already leftmost desktop
553 * @returns the desktop left of @p desktop
554 */
operator()555 VirtualDesktop *operator() (VirtualDesktop *desktop, bool wrap) {
556 return VirtualDesktopManager::self()->toLeft(desktop, wrap);
557 }
558 };
559
560 /**
561 * Function object to select the desktop to the right in the layout.
562 * Note: does not switch to the desktop!
563 */
564 class DesktopRight
565 {
566 public:
DesktopRight()567 DesktopRight() {}
568 /**
569 * @param desktop The desktop from which the desktop on the right should be selected. If @c 0 the current desktop is used
570 * @param wrap Whether to wrap around if already rightmost desktop
571 * @returns Id of the desktop right of @p desktop
572 */
operator()573 uint operator() (uint desktop, bool wrap) {
574 return (*this)(VirtualDesktopManager::self()->desktopForX11Id(desktop), wrap)->x11DesktopNumber();
575 }
576 /**
577 * @param desktop The desktop from which the desktop on the right should be selected. If @c 0 the current desktop is used
578 * @param wrap Whether to wrap around if already rightmost desktop
579 * @returns the desktop right of @p desktop
580 */
operator()581 VirtualDesktop *operator() (VirtualDesktop *desktop, bool wrap) {
582 return VirtualDesktopManager::self()->toRight(desktop, wrap);
583 }
584 };
585
586 /**
587 * Function object to select the next desktop in the layout.
588 * Note: does not switch to the desktop!
589 */
590 class DesktopNext
591 {
592 public:
DesktopNext()593 DesktopNext() {}
594 /**
595 * @param desktop The desktop from which the next desktop should be selected. If @c 0 the current desktop is used
596 * @param wrap Whether to wrap around if already last desktop
597 * @returns Id of the next desktop
598 */
operator()599 uint operator() (uint desktop, bool wrap) {
600 return (*this)(VirtualDesktopManager::self()->desktopForX11Id(desktop), wrap)->x11DesktopNumber();
601 }
602 /**
603 * @param desktop The desktop from which the next desktop should be selected. If @c 0 the current desktop is used
604 * @param wrap Whether to wrap around if already last desktop
605 * @returns the next desktop
606 */
operator()607 VirtualDesktop *operator() (VirtualDesktop *desktop, bool wrap) {
608 return VirtualDesktopManager::self()->next(desktop, wrap);
609 }
610 };
611
612 /**
613 * Function object to select the previous desktop in the layout.
614 * Note: does not switch to the desktop!
615 */
616 class DesktopPrevious
617 {
618 public:
DesktopPrevious()619 DesktopPrevious() {}
620 /**
621 * @param desktop The desktop from which the previous desktop should be selected. If @c 0 the current desktop is used
622 * @param wrap Whether to wrap around if already first desktop
623 * @returns Id of the previous desktop
624 */
operator()625 uint operator() (uint desktop, bool wrap) {
626 return (*this)(VirtualDesktopManager::self()->desktopForX11Id(desktop), wrap)->x11DesktopNumber();
627 }
628 /**
629 * @param desktop The desktop from which the previous desktop should be selected. If @c 0 the current desktop is used
630 * @param wrap Whether to wrap around if already first desktop
631 * @returns the previous desktop
632 */
operator()633 VirtualDesktop *operator() (VirtualDesktop *desktop, bool wrap) {
634 return VirtualDesktopManager::self()->previous(desktop, wrap);
635 }
636 };
637
638 /**
639 * Helper function to get the ID of a virtual desktop in the direction from
640 * the given @p desktop. If @c 0 the current desktop is used as a starting point.
641 * @param desktop The desktop from which the desktop in given Direction should be selected.
642 * @param wrap Whether desktop navigation wraps around at the borders of the layout
643 * @returns The next desktop in specified direction
644 */
645 template <typename Direction>
646 uint getDesktop(int desktop = 0, bool wrap = true);
647
648 template <typename Direction>
getDesktop(int d,bool wrap)649 uint getDesktop(int d, bool wrap)
650 {
651 Direction direction;
652 return direction(d, wrap);
653 }
654
655 inline
width()656 int VirtualDesktopGrid::width() const
657 {
658 return m_size.width();
659 }
660
661 inline
height()662 int VirtualDesktopGrid::height() const
663 {
664 return m_size.height();
665 }
666
667 inline
size()668 const QSize &VirtualDesktopGrid::size() const
669 {
670 return m_size;
671 }
672
673 inline
maximum()674 uint VirtualDesktopManager::maximum()
675 {
676 return 20;
677 }
678
679 inline
count()680 uint VirtualDesktopManager::count() const
681 {
682 return m_desktops.count();
683 }
684
685 inline
isNavigationWrappingAround()686 bool VirtualDesktopManager::isNavigationWrappingAround() const
687 {
688 return m_navigationWrapsAround;
689 }
690
691 inline
setConfig(KSharedConfig::Ptr config)692 void VirtualDesktopManager::setConfig(KSharedConfig::Ptr config)
693 {
694 m_config = std::move(config);
695 }
696
697 inline
grid()698 const VirtualDesktopGrid &VirtualDesktopManager::grid() const
699 {
700 return m_grid;
701 }
702
703 template <typename Direction>
moveTo(bool wrap)704 void VirtualDesktopManager::moveTo(bool wrap)
705 {
706 Direction functor;
707 setCurrent(functor(nullptr, wrap));
708 }
709
710 } // namespace KWin
711 #endif
712