1 | /******************************************************************** |
2 | KWin - the KDE window manager |
3 | This file is part of the KDE project. |
4 | |
5 | Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org> |
6 | Copyright (C) 2003 Lubos Lunak <l.lunak@kde.org> |
7 | Copyright (C) 2009 Lucas Murray <lmurray@undefinedfire.com> |
8 | |
9 | This program is free software; you can redistribute it and/or modify |
10 | it under the terms of the GNU General Public License as published by |
11 | the Free Software Foundation; either version 2 of the License, or |
12 | (at your option) any later version. |
13 | |
14 | This program is distributed in the hope that it will be useful, |
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | GNU General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU General Public License |
20 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
21 | *********************************************************************/ |
22 | |
23 | #ifndef KWIN_WORKSPACE_H |
24 | #define KWIN_WORKSPACE_H |
25 | |
26 | // kwin |
27 | #include <kdecoration.h> |
28 | #include "sm.h" |
29 | #include "utils.h" |
30 | // Qt |
31 | #include <QTimer> |
32 | #include <QVector> |
33 | // X |
34 | #include <X11/Xlib.h> |
35 | |
36 | // TODO: Cleanup the order of things in this .h file |
37 | |
38 | class QStringList; |
39 | class KConfig; |
40 | class KActionCollection; |
41 | class KShortcut; |
42 | class KStartupInfo; |
43 | class KStartupInfoId; |
44 | class KStartupInfoData; |
45 | |
46 | namespace KWin |
47 | { |
48 | |
49 | namespace Xcb |
50 | { |
51 | class Window; |
52 | } |
53 | |
54 | class Client; |
55 | class KillWindow; |
56 | class ShortcutDialog; |
57 | class ; |
58 | class Compositor; |
59 | |
60 | class Workspace : public QObject, public KDecorationDefines |
61 | { |
62 | Q_OBJECT |
63 | public: |
64 | explicit Workspace(bool restore = false); |
65 | virtual ~Workspace(); |
66 | |
67 | static Workspace* self() { |
68 | return _self; |
69 | } |
70 | |
71 | bool workspaceEvent(XEvent*); |
72 | bool workspaceEvent(QEvent*); |
73 | |
74 | bool hasClient(const Client*); |
75 | |
76 | template<typename T> Client* findClient(T predicate) const; |
77 | template<typename T1, typename T2> void forEachClient(T1 procedure, T2 predicate); |
78 | template<typename T> void forEachClient(T procedure); |
79 | template<typename T> Unmanaged* findUnmanaged(T predicate) const; |
80 | template<typename T1, typename T2> void forEachUnmanaged(T1 procedure, T2 predicate); |
81 | template<typename T> void forEachUnmanaged(T procedure); |
82 | |
83 | QRect clientArea(clientAreaOption, const QPoint& p, int desktop) const; |
84 | QRect clientArea(clientAreaOption, const Client* c) const; |
85 | QRect clientArea(clientAreaOption, int screen, int desktop) const; |
86 | |
87 | QRegion restrictedMoveArea(int desktop, StrutAreas areas = StrutAreaAll) const; |
88 | |
89 | bool initializing() const; |
90 | |
91 | /** |
92 | * Returns the active client, i.e. the client that has the focus (or None |
93 | * if no client has the focus) |
94 | */ |
95 | Client* activeClient() const; |
96 | /** |
97 | * Client that was activated, but it's not yet really activeClient(), because |
98 | * we didn't process yet the matching FocusIn event. Used mostly in focus |
99 | * stealing prevention code. |
100 | */ |
101 | Client* mostRecentlyActivatedClient() const; |
102 | |
103 | Client* clientUnderMouse(int screen) const; |
104 | |
105 | void activateClient(Client*, bool force = false); |
106 | void requestFocus(Client* c, bool force = false); |
107 | void takeActivity(Client* c, int flags, bool handled); // Flags are ActivityFlags |
108 | void handleTakeActivity(Client* c, xcb_timestamp_t timestamp, int flags); // Flags are ActivityFlags |
109 | bool allowClientActivation(const Client* c, xcb_timestamp_t time = -1U, bool focus_in = false, |
110 | bool ignore_desktop = false); |
111 | void restoreFocus(); |
112 | void gotFocusIn(const Client*); |
113 | void setShouldGetFocus(Client*); |
114 | bool activateNextClient(Client* c); |
115 | bool focusChangeEnabled() { |
116 | return block_focus == 0; |
117 | } |
118 | |
119 | /** |
120 | * Indicates that the client c is being moved around by the user. |
121 | */ |
122 | void setClientIsMoving(Client* c); |
123 | |
124 | QPoint adjustClientPosition(Client* c, QPoint pos, bool unrestricted, double snapAdjust = 1.0); |
125 | QRect adjustClientSize(Client* c, QRect moveResizeGeom, int mode); |
126 | void raiseClient(Client* c, bool nogroup = false); |
127 | void lowerClient(Client* c, bool nogroup = false); |
128 | void raiseClientRequest(Client* c, NET::RequestSource src, xcb_timestamp_t timestamp); |
129 | void lowerClientRequest(Client* c, NET::RequestSource src, xcb_timestamp_t timestamp); |
130 | void restackClientUnderActive(Client*); |
131 | void restack(Client *c, Client *under); |
132 | void updateClientLayer(Client* c); |
133 | void raiseOrLowerClient(Client*); |
134 | void resetUpdateToolWindowsTimer(); |
135 | void restoreSessionStackingOrder(Client* c); |
136 | void updateStackingOrder(bool propagate_new_clients = false); |
137 | void forceRestacking(); |
138 | |
139 | void clientHidden(Client*); |
140 | void clientAttentionChanged(Client* c, bool set); |
141 | |
142 | /** |
143 | * @return List of clients currently managed by Workspace |
144 | **/ |
145 | const ClientList &clientList() const { |
146 | return clients; |
147 | } |
148 | /** |
149 | * @return List of unmanaged "clients" currently registered in Workspace |
150 | **/ |
151 | const UnmanagedList &unmanagedList() const { |
152 | return unmanaged; |
153 | } |
154 | /** |
155 | * @return List of desktop "clients" currently managed by Workspace |
156 | **/ |
157 | const ClientList &desktopList() const { |
158 | return desktops; |
159 | } |
160 | /** |
161 | * @return List of deleted "clients" currently managed by Workspace |
162 | **/ |
163 | const DeletedList &deletedList() const { |
164 | return deleted; |
165 | } |
166 | |
167 | #ifdef KWIN_BUILD_SCREENEDGES |
168 | void stackScreenEdgesUnderOverrideRedirect(); |
169 | #endif |
170 | |
171 | public: |
172 | QPoint cascadeOffset(const Client *c) const; |
173 | |
174 | private: |
175 | Compositor *m_compositor; |
176 | |
177 | //------------------------------------------------- |
178 | // Unsorted |
179 | |
180 | public: |
181 | bool isOnCurrentHead(); |
182 | // True when performing Workspace::updateClientArea(). |
183 | // The calls below are valid only in that case. |
184 | bool inUpdateClientArea() const; |
185 | QRegion previousRestrictedMoveArea(int desktop, StrutAreas areas = StrutAreaAll) const; |
186 | QVector< QRect > previousScreenSizes() const; |
187 | int oldDisplayWidth() const; |
188 | int oldDisplayHeight() const; |
189 | |
190 | KActionCollection* actionCollection() const { |
191 | return keys; |
192 | } |
193 | KActionCollection* disableShortcutsKeys() const { |
194 | return disable_shortcuts_keys; |
195 | } |
196 | KActionCollection* clientKeys() const { |
197 | return client_keys; |
198 | } |
199 | |
200 | /** |
201 | * Returns the list of clients sorted in stacking order, with topmost client |
202 | * at the last position |
203 | */ |
204 | const ToplevelList& stackingOrder() const; |
205 | ToplevelList xStackingOrder() const; |
206 | ClientList ensureStackingOrder(const ClientList& clients) const; |
207 | |
208 | Client* topClientOnDesktop(int desktop, int screen, bool unconstrained = false, |
209 | bool only_normal = true) const; |
210 | Client* findDesktop(bool topmost, int desktop) const; |
211 | void sendClientToDesktop(Client* c, int desktop, bool dont_activate); |
212 | void windowToPreviousDesktop(Client* c); |
213 | void windowToNextDesktop(Client* c); |
214 | void sendClientToScreen(Client* c, int screen); |
215 | |
216 | /** |
217 | * Shows the menu operations menu for the client and makes it active if |
218 | * it's not already. |
219 | */ |
220 | void (const QRect& pos, Client* cl); |
221 | const UserActionsMenu *() const { |
222 | return m_userActionsMenu; |
223 | } |
224 | |
225 | void updateMinimizedOfTransients(Client*); |
226 | void updateOnAllDesktopsOfTransients(Client*); |
227 | void checkTransients(xcb_window_t w); |
228 | |
229 | void performWindowOperation(Client* c, WindowOperation op); |
230 | |
231 | void storeSession(KConfig* config, SMSavePhase phase); |
232 | void storeClient(KConfigGroup &cg, int num, Client *c); |
233 | void storeSubSession(const QString &name, QSet<QByteArray> sessionIds); |
234 | void loadSubSessionInfo(const QString &name); |
235 | |
236 | SessionInfo* takeSessionInfo(Client*); |
237 | |
238 | // D-Bus interface |
239 | bool waitForCompositingSetup(); |
240 | QString supportInformation() const; |
241 | |
242 | void setCurrentScreen(int new_screen); |
243 | |
244 | void setShowingDesktop(bool showing); |
245 | void resetShowingDesktop(bool keep_hidden); |
246 | bool showingDesktop() const; |
247 | |
248 | void sendPingToWindow(xcb_window_t w, xcb_timestamp_t timestamp); // Called from Client::pingWindow() |
249 | void sendTakeActivity(Client* c, xcb_timestamp_t timestamp, long flags); // Called from Client::takeActivity() |
250 | |
251 | void removeClient(Client*); // Only called from Client::destroyClient() or Client::releaseWindow() |
252 | void setActiveClient(Client*); |
253 | Group* findGroup(xcb_window_t leader) const; |
254 | void addGroup(Group* group); |
255 | void removeGroup(Group* group); |
256 | Group* findClientLeaderGroup(const Client* c) const; |
257 | |
258 | void removeUnmanaged(Unmanaged*); // Only called from Unmanaged::release() |
259 | void removeDeleted(Deleted*); |
260 | void addDeleted(Deleted*, Toplevel*); |
261 | |
262 | bool checkStartupNotification(xcb_window_t w, KStartupInfoId& id, KStartupInfoData& data); |
263 | |
264 | void focusToNull(); // SELI TODO: Public? |
265 | |
266 | bool forcedGlobalMouseGrab() const; |
267 | void clientShortcutUpdated(Client* c); |
268 | bool shortcutAvailable(const KShortcut& cut, Client* ignore = NULL) const; |
269 | bool globalShortcutsDisabled() const; |
270 | void disableGlobalShortcutsForClient(bool disable); |
271 | |
272 | void sessionSaveStarted(); |
273 | void sessionSaveDone(); |
274 | void setWasUserInteraction(); |
275 | bool wasUserInteraction() const; |
276 | bool sessionSaving() const; |
277 | |
278 | int packPositionLeft(const Client* cl, int oldx, bool left_edge) const; |
279 | int packPositionRight(const Client* cl, int oldx, bool right_edge) const; |
280 | int packPositionUp(const Client* cl, int oldy, bool top_edge) const; |
281 | int packPositionDown(const Client* cl, int oldy, bool bottom_edge) const; |
282 | |
283 | void cancelDelayFocus(); |
284 | void requestDelayFocus(Client*); |
285 | void updateFocusMousePosition(const QPoint& pos); |
286 | QPoint focusMousePosition() const; |
287 | |
288 | Client* getMovingClient() { |
289 | return movingClient; |
290 | } |
291 | |
292 | /** |
293 | * @returns Whether we have a Compositor and it is active (Scene created) |
294 | **/ |
295 | bool compositing() const; |
296 | |
297 | public slots: |
298 | // Keybindings |
299 | //void slotSwitchToWindow( int ); |
300 | void slotWindowToDesktop(); |
301 | |
302 | //void slotWindowToListPosition( int ); |
303 | void slotSwitchToScreen(); |
304 | void slotWindowToScreen(); |
305 | void slotSwitchToNextScreen(); |
306 | void slotWindowToNextScreen(); |
307 | void slotSwitchToPrevScreen(); |
308 | void slotWindowToPrevScreen(); |
309 | void slotToggleShowDesktop(); |
310 | |
311 | void slotWindowMaximize(); |
312 | void slotWindowMaximizeVertical(); |
313 | void slotWindowMaximizeHorizontal(); |
314 | void slotWindowMinimize(); |
315 | void slotWindowShade(); |
316 | void slotWindowRaise(); |
317 | void slotWindowLower(); |
318 | void slotWindowRaiseOrLower(); |
319 | void slotActivateAttentionWindow(); |
320 | void slotWindowPackLeft(); |
321 | void slotWindowPackRight(); |
322 | void slotWindowPackUp(); |
323 | void slotWindowPackDown(); |
324 | void slotWindowGrowHorizontal(); |
325 | void slotWindowGrowVertical(); |
326 | void slotWindowShrinkHorizontal(); |
327 | void slotWindowShrinkVertical(); |
328 | void slotWindowQuickTileLeft(); |
329 | void slotWindowQuickTileRight(); |
330 | void slotWindowQuickTileTopLeft(); |
331 | void slotWindowQuickTileTopRight(); |
332 | void slotWindowQuickTileBottomLeft(); |
333 | void slotWindowQuickTileBottomRight(); |
334 | |
335 | void slotSwitchWindowUp(); |
336 | void slotSwitchWindowDown(); |
337 | void slotSwitchWindowRight(); |
338 | void slotSwitchWindowLeft(); |
339 | |
340 | void slotIncreaseWindowOpacity(); |
341 | void slotLowerWindowOpacity(); |
342 | |
343 | void slotWindowOperations(); |
344 | void slotWindowClose(); |
345 | void slotWindowMove(); |
346 | void slotWindowResize(); |
347 | void slotWindowAbove(); |
348 | void slotWindowBelow(); |
349 | void slotWindowOnAllDesktops(); |
350 | void slotWindowFullScreen(); |
351 | void slotWindowNoBorder(); |
352 | |
353 | void slotWindowToNextDesktop(); |
354 | void slotWindowToPreviousDesktop(); |
355 | void slotWindowToDesktopRight(); |
356 | void slotWindowToDesktopLeft(); |
357 | void slotWindowToDesktopUp(); |
358 | void slotWindowToDesktopDown(); |
359 | |
360 | void slotSettingsChanged(int category); |
361 | |
362 | void reconfigure(); |
363 | void slotReconfigure(); |
364 | |
365 | void slotKillWindow(); |
366 | |
367 | void slotSetupWindowShortcut(); |
368 | void setupWindowShortcutDone(bool); |
369 | void slotToggleCompositing(); |
370 | void slotInvertScreen(); |
371 | |
372 | void updateClientArea(); |
373 | |
374 | void slotActivateNextTab(); // Slot to move left the active Client. |
375 | void slotActivatePrevTab(); // Slot to move right the active Client. |
376 | void slotUntab(); // Slot to remove the active client from its group. |
377 | |
378 | private slots: |
379 | void desktopResized(); |
380 | void slotUpdateToolWindows(); |
381 | void delayFocus(); |
382 | void slotBlockShortcuts(int data); |
383 | void slotReloadConfig(); |
384 | void updateCurrentActivity(const QString &new_activity); |
385 | // virtual desktop handling |
386 | void moveClientsFromRemovedDesktops(); |
387 | void slotDesktopCountChanged(uint previousCount, uint newCount); |
388 | void slotCurrentDesktopChanged(uint oldDesktop, uint newDesktop); |
389 | |
390 | Q_SIGNALS: |
391 | /** |
392 | * Emitted after the Workspace has setup the complete initialization process. |
393 | * This can be used to connect to for performing post-workspace initialization. |
394 | **/ |
395 | void workspaceInitialized(); |
396 | |
397 | //Signals required for the scripting interface |
398 | signals: |
399 | void desktopPresenceChanged(KWin::Client*, int); |
400 | void currentDesktopChanged(int, KWin::Client*); |
401 | void clientAdded(KWin::Client*); |
402 | void clientRemoved(KWin::Client*); |
403 | void clientActivated(KWin::Client*); |
404 | void clientDemandsAttentionChanged(KWin::Client*, bool); |
405 | void groupAdded(KWin::Group*); |
406 | void unmanagedAdded(KWin::Unmanaged*); |
407 | void deletedRemoved(KWin::Deleted*); |
408 | void propertyNotify(long a); |
409 | void configChanged(); |
410 | void reinitializeCompositing(); |
411 | /** |
412 | * This signels is emitted when ever the stacking order is change, ie. a window is risen |
413 | * or lowered |
414 | */ |
415 | void stackingOrderChanged(); |
416 | |
417 | private: |
418 | void init(); |
419 | void initShortcuts(); |
420 | void setupWindowShortcut(Client* c); |
421 | enum Direction { |
422 | DirectionNorth, |
423 | DirectionEast, |
424 | DirectionSouth, |
425 | DirectionWest |
426 | }; |
427 | void switchWindow(Direction direction); |
428 | |
429 | void propagateClients(bool propagate_new_clients); // Called only from updateStackingOrder |
430 | ToplevelList constrainedStackingOrder(); |
431 | void raiseClientWithinApplication(Client* c); |
432 | void lowerClientWithinApplication(Client* c); |
433 | bool allowFullClientRaising(const Client* c, xcb_timestamp_t timestamp); |
434 | bool keepTransientAbove(const Client* mainwindow, const Client* transient); |
435 | void blockStackingUpdates(bool block); |
436 | void updateToolWindows(bool also_hide); |
437 | void fixPositionAfterCrash(xcb_window_t w, const xcb_get_geometry_reply_t *geom); |
438 | void saveOldScreenSizes(); |
439 | |
440 | /// This is the right way to create a new client |
441 | Client* createClient(xcb_window_t w, bool is_mapped); |
442 | void addClient(Client* c); |
443 | Unmanaged* createUnmanaged(xcb_window_t w); |
444 | void addUnmanaged(Unmanaged* c); |
445 | |
446 | xcb_window_t findSpecialEventWindow(XEvent* e); |
447 | |
448 | //--------------------------------------------------------------------- |
449 | |
450 | void (); |
451 | void updateClientArea(bool force); |
452 | void resetClientAreas(uint desktopCount); |
453 | void updateClientVisibilityOnDesktopChange(uint oldDesktop, uint newDesktop); |
454 | void activateClientOnNewDesktop(uint desktop); |
455 | Client *findClientToActivateOnDesktop(uint desktop); |
456 | |
457 | QWidget* ; |
458 | Client* ; |
459 | |
460 | void loadSessionInfo(); |
461 | void addSessionInfo(KConfigGroup &cg); |
462 | |
463 | QList<SessionInfo*> session; |
464 | static const char* windowTypeToTxt(NET::WindowType type); |
465 | static NET::WindowType txtToWindowType(const char* txt); |
466 | static bool sessionInfoWindowTypeMatch(Client* c, SessionInfo* info); |
467 | |
468 | Client* active_client; |
469 | Client* last_active_client; |
470 | Client* most_recently_raised; // Used ONLY by raiseOrLowerClient() |
471 | Client* movingClient; |
472 | Client* pending_take_activity; |
473 | |
474 | // Delay(ed) window focus timer and client |
475 | QTimer* delayFocusTimer; |
476 | Client* delayfocus_client; |
477 | QPoint focusMousePos; |
478 | |
479 | ClientList clients; |
480 | ClientList desktops; |
481 | UnmanagedList unmanaged; |
482 | DeletedList deleted; |
483 | |
484 | ToplevelList unconstrained_stacking_order; // Topmost last |
485 | ToplevelList stacking_order; // Topmost last |
486 | bool force_restacking; |
487 | mutable ToplevelList x_stacking; // From XQueryTree() |
488 | mutable bool x_stacking_dirty; |
489 | ClientList should_get_focus; // Last is most recent |
490 | ClientList attention_chain; |
491 | |
492 | bool showing_desktop; |
493 | ClientList showing_desktop_clients; |
494 | int block_showing_desktop; |
495 | |
496 | GroupList groups; |
497 | |
498 | bool was_user_interaction; |
499 | bool session_saving; |
500 | int session_active_client; |
501 | int session_desktop; |
502 | |
503 | int block_focus; |
504 | |
505 | /** |
506 | * Holds the menu containing the user actions which is shown |
507 | * on e.g. right click the window decoration. |
508 | **/ |
509 | UserActionsMenu *; |
510 | |
511 | void modalActionsSwitch(bool enabled); |
512 | |
513 | KActionCollection* keys; |
514 | KActionCollection* client_keys; |
515 | KActionCollection* disable_shortcuts_keys; |
516 | ShortcutDialog* client_keys_dialog; |
517 | Client* client_keys_client; |
518 | bool global_shortcuts_disabled_for_client; |
519 | |
520 | // Timer to collect requests for 'reconfigure' |
521 | QTimer reconfigureTimer; |
522 | |
523 | QTimer updateToolWindowsTimer; |
524 | |
525 | static Workspace* _self; |
526 | |
527 | bool workspaceInit; |
528 | |
529 | KStartupInfo* startup; |
530 | |
531 | QVector<QRect> workarea; // Array of workareas for virtual desktops |
532 | // Array of restricted areas that window cannot be moved into |
533 | QVector<StrutRects> restrictedmovearea; |
534 | // Array of the previous restricted areas that window cannot be moved into |
535 | QVector<StrutRects> oldrestrictedmovearea; |
536 | QVector< QVector<QRect> > screenarea; // Array of workareas per xinerama screen for all virtual desktops |
537 | QVector< QRect > oldscreensizes; // array of previous sizes of xinerama screens |
538 | QSize olddisplaysize; // previous sizes od displayWidth()/displayHeight() |
539 | |
540 | int set_active_client_recursion; |
541 | int block_stacking_updates; // When > 0, stacking updates are temporarily disabled |
542 | bool blocked_propagating_new_clients; // Propagate also new clients after enabling stacking updates? |
543 | QScopedPointer<Xcb::Window> m_nullFocus; |
544 | bool forced_global_mouse_grab; |
545 | friend class StackingUpdatesBlocker; |
546 | |
547 | QScopedPointer<KillWindow> m_windowKiller; |
548 | |
549 | private: |
550 | friend bool performTransiencyCheck(); |
551 | friend Workspace *workspace(); |
552 | }; |
553 | |
554 | /** |
555 | * Helper for Workspace::blockStackingUpdates() being called in pairs (True/false) |
556 | */ |
557 | class StackingUpdatesBlocker |
558 | { |
559 | public: |
560 | explicit StackingUpdatesBlocker(Workspace* w) |
561 | : ws(w) { |
562 | ws->blockStackingUpdates(true); |
563 | } |
564 | ~StackingUpdatesBlocker() { |
565 | ws->blockStackingUpdates(false); |
566 | } |
567 | |
568 | private: |
569 | Workspace* ws; |
570 | }; |
571 | |
572 | class ColorMapper : public QObject |
573 | { |
574 | Q_OBJECT |
575 | public: |
576 | ColorMapper(QObject *parent); |
577 | virtual ~ColorMapper(); |
578 | public Q_SLOTS: |
579 | void update(); |
580 | private: |
581 | xcb_colormap_t m_default; |
582 | xcb_colormap_t m_installed; |
583 | }; |
584 | |
585 | //--------------------------------------------------------- |
586 | // Unsorted |
587 | |
588 | inline bool Workspace::initializing() const |
589 | { |
590 | return workspaceInit; |
591 | } |
592 | |
593 | inline Client* Workspace::activeClient() const |
594 | { |
595 | return active_client; |
596 | } |
597 | |
598 | inline Client* Workspace::mostRecentlyActivatedClient() const |
599 | { |
600 | return should_get_focus.count() > 0 ? should_get_focus.last() : active_client; |
601 | } |
602 | |
603 | inline void Workspace::addGroup(Group* group) |
604 | { |
605 | emit groupAdded(group); |
606 | groups.append(group); |
607 | } |
608 | |
609 | inline void Workspace::removeGroup(Group* group) |
610 | { |
611 | groups.removeAll(group); |
612 | } |
613 | |
614 | inline const ToplevelList& Workspace::stackingOrder() const |
615 | { |
616 | // TODO: Q_ASSERT( block_stacking_updates == 0 ); |
617 | return stacking_order; |
618 | } |
619 | |
620 | inline void Workspace::setWasUserInteraction() |
621 | { |
622 | was_user_interaction = true; |
623 | } |
624 | |
625 | inline bool Workspace::wasUserInteraction() const |
626 | { |
627 | return was_user_interaction; |
628 | } |
629 | |
630 | inline void Workspace::sessionSaveStarted() |
631 | { |
632 | session_saving = true; |
633 | } |
634 | |
635 | inline bool Workspace::sessionSaving() const |
636 | { |
637 | return session_saving; |
638 | } |
639 | |
640 | inline bool Workspace::forcedGlobalMouseGrab() const |
641 | { |
642 | return forced_global_mouse_grab; |
643 | } |
644 | |
645 | inline bool Workspace::showingDesktop() const |
646 | { |
647 | return showing_desktop; |
648 | } |
649 | |
650 | inline bool Workspace::globalShortcutsDisabled() const |
651 | { |
652 | return global_shortcuts_disabled_for_client; |
653 | } |
654 | |
655 | inline void Workspace::forceRestacking() |
656 | { |
657 | force_restacking = true; |
658 | StackingUpdatesBlocker blocker(this); // Do restacking if not blocked |
659 | } |
660 | |
661 | inline void Workspace::updateFocusMousePosition(const QPoint& pos) |
662 | { |
663 | focusMousePos = pos; |
664 | } |
665 | |
666 | inline QPoint Workspace::focusMousePosition() const |
667 | { |
668 | return focusMousePos; |
669 | } |
670 | |
671 | template< typename T > |
672 | inline Client* Workspace::findClient(T predicate) const |
673 | { |
674 | if (Client* ret = findClientInList(clients, predicate)) |
675 | return ret; |
676 | if (Client* ret = findClientInList(desktops, predicate)) |
677 | return ret; |
678 | return NULL; |
679 | } |
680 | |
681 | template< typename T1, typename T2 > |
682 | inline void Workspace::forEachClient(T1 procedure, T2 predicate) |
683 | { |
684 | for (ClientList::ConstIterator it = clients.constBegin(); it != clients.constEnd(); ++it) |
685 | if (predicate(const_cast<const Client*>(*it))) |
686 | procedure(*it); |
687 | for (ClientList::ConstIterator it = desktops.constBegin(); it != desktops.constEnd(); ++it) |
688 | if (predicate(const_cast<const Client*>(*it))) |
689 | procedure(*it); |
690 | } |
691 | |
692 | template< typename T > |
693 | inline void Workspace::forEachClient(T procedure) |
694 | { |
695 | return forEachClient(procedure, TruePredicate()); |
696 | } |
697 | |
698 | template< typename T > |
699 | inline Unmanaged* Workspace::findUnmanaged(T predicate) const |
700 | { |
701 | return findUnmanagedInList(unmanaged, predicate); |
702 | } |
703 | |
704 | template< typename T1, typename T2 > |
705 | inline void Workspace::forEachUnmanaged(T1 procedure, T2 predicate) |
706 | { |
707 | for (UnmanagedList::ConstIterator it = unmanaged.constBegin(); it != unmanaged.constEnd(); ++it) |
708 | if (predicate(const_cast<const Unmanaged*>(*it))) |
709 | procedure(*it); |
710 | } |
711 | |
712 | template< typename T > |
713 | inline void Workspace::forEachUnmanaged(T procedure) |
714 | { |
715 | return forEachUnmanaged(procedure, TruePredicate()); |
716 | } |
717 | |
718 | KWIN_COMPARE_PREDICATE(ClientMatchPredicate, Client, const Client*, cl == value); |
719 | |
720 | inline bool Workspace::hasClient(const Client* c) |
721 | { |
722 | return findClient(ClientMatchPredicate(c)); |
723 | } |
724 | |
725 | inline Workspace *workspace() |
726 | { |
727 | return Workspace::_self; |
728 | } |
729 | |
730 | } // namespace |
731 | |
732 | #endif |
733 | |