File indexing completed on 2024-12-08 04:57:59
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 1999, 2000 Matthias Ettrich <ettrich@kde.org> 0006 SPDX-FileCopyrightText: 2003 Lubos Lunak <l.lunak@kde.org> 0007 SPDX-FileCopyrightText: 2009 Lucas Murray <lmurray@undefinedfire.com> 0008 SPDX-FileCopyrightText: 2019 Vlad Zahorodnii <vlad.zahorodnii@kde.org> 0009 SPDX-FileCopyrightText: 2022 Natalie Clarius <natalie_clarius@yahoo.de> 0010 0011 SPDX-License-Identifier: GPL-2.0-or-later 0012 */ 0013 0014 #pragma once 0015 0016 // kwin 0017 #include "options.h" 0018 #include "sm.h" 0019 #include "utils/common.h" 0020 // Qt 0021 #include <QList> 0022 #include <QStringList> 0023 #include <QTimer> 0024 // std 0025 #include <functional> 0026 #include <memory> 0027 0028 class KConfig; 0029 class KConfigGroup; 0030 class KStartupInfo; 0031 class KStartupInfoData; 0032 class KStartupInfoId; 0033 0034 namespace KWin 0035 { 0036 0037 namespace Decoration 0038 { 0039 class DecorationBridge; 0040 } 0041 0042 namespace Xcb 0043 { 0044 class Tree; 0045 class Window; 0046 } 0047 0048 namespace TabBox 0049 { 0050 class TabBox; 0051 } 0052 0053 class Window; 0054 class Output; 0055 class Compositor; 0056 class Group; 0057 class InternalWindow; 0058 class KillWindow; 0059 class ShortcutDialog; 0060 class UserActionsMenu; 0061 class VirtualDesktop; 0062 class X11Window; 0063 class X11EventFilter; 0064 class FocusChain; 0065 class ApplicationMenu; 0066 class PlacementTracker; 0067 enum class Predicate; 0068 class Outline; 0069 class RuleBook; 0070 class ScreenEdges; 0071 #if KWIN_BUILD_ACTIVITIES 0072 class Activities; 0073 #endif 0074 class PlaceholderInputEventFilter; 0075 class PlaceholderOutput; 0076 class Placement; 0077 class OutputConfiguration; 0078 class TileManager; 0079 class OutputConfigurationStore; 0080 class LidSwitchTracker; 0081 class DpmsInputEventFilter; 0082 class OrientationSensor; 0083 0084 class KWIN_EXPORT Workspace : public QObject 0085 { 0086 Q_OBJECT 0087 public: 0088 explicit Workspace(); 0089 ~Workspace() override; 0090 0091 static Workspace *self() 0092 { 0093 return _self; 0094 } 0095 0096 bool workspaceEvent(xcb_generic_event_t *); 0097 0098 bool hasWindow(const Window *); 0099 0100 /** 0101 * @brief Finds the first Client matching the condition expressed by passed in @p func. 0102 * 0103 * Internally findClient uses the std::find_if algorithm and that determines how the function 0104 * needs to be implemented. An example usage for finding a Client with a matching windowId 0105 * @code 0106 * xcb_window_t w; // our test window 0107 * X11Window *client = findClient([w](const X11Window *c) -> bool { 0108 * return c->window() == w; 0109 * }); 0110 * @endcode 0111 * 0112 * For the standard cases of matching the window id with one of the Client's windows use 0113 * the simplified overload method findClient(Predicate, xcb_window_t). Above example 0114 * can be simplified to: 0115 * @code 0116 * xcb_window_t w; // our test window 0117 * X11Window *client = findClient(Predicate::WindowMatch, w); 0118 * @endcode 0119 * 0120 * @param func Unary function that accepts a X11Window *as argument and 0121 * returns a value convertible to bool. The value returned indicates whether the 0122 * X11Window *is considered a match in the context of this function. 0123 * The function shall not modify its argument. 0124 * This can either be a function pointer or a function object. 0125 * @return KWin::X11Window *The found Client or @c null 0126 * @see findClient(Predicate, xcb_window_t) 0127 */ 0128 X11Window *findClient(std::function<bool(const X11Window *)> func) const; 0129 /** 0130 * @brief Finds the Client matching the given match @p predicate for the given window. 0131 * 0132 * @param predicate Which window should be compared 0133 * @param w The window id to test against 0134 * @return KWin::X11Window *The found Client or @c null 0135 * @see findClient(std::function<bool (const X11Window *)>) 0136 */ 0137 X11Window *findClient(Predicate predicate, xcb_window_t w) const; 0138 void forEachClient(std::function<void(X11Window *)> func); 0139 X11Window *findUnmanaged(std::function<bool(const X11Window *)> func) const; 0140 /** 0141 * @brief Finds the Unmanaged with the given window id. 0142 * 0143 * @param w The window id to search for 0144 * @return KWin::Unmanaged* Found Unmanaged or @c null if there is no Unmanaged with given Id. 0145 */ 0146 X11Window *findUnmanaged(xcb_window_t w) const; 0147 0148 Window *findWindow(const QUuid &internalId) const; 0149 Window *findWindow(std::function<bool(const Window *)> func) const; 0150 void forEachWindow(std::function<void(Window *)> func); 0151 0152 /** 0153 * @brief Finds a Window for the internal window @p w. 0154 * 0155 * Internal window means a window created by KWin itself. On X11 this is an Unmanaged 0156 * and mapped by the window id, on Wayland a XdgShellClient mapped on the internal window id. 0157 * 0158 * @returns Window 0159 */ 0160 Window *findInternal(QWindow *w) const; 0161 0162 QRectF clientArea(clientAreaOption, const Output *output, const VirtualDesktop *desktop) const; 0163 QRectF clientArea(clientAreaOption, const Window *window) const; 0164 QRectF clientArea(clientAreaOption, const Window *window, const Output *output) const; 0165 QRectF clientArea(clientAreaOption, const Window *window, const QPointF &pos) const; 0166 0167 /** 0168 * Returns the geometry of this Workspace, i.e. the bounding rectangle of all outputs. 0169 */ 0170 QRect geometry() const; 0171 StrutRects restrictedMoveArea(const VirtualDesktop *desktop, StrutAreas areas = StrutAreaAll) const; 0172 0173 bool initializing() const; 0174 0175 Output *xineramaIndexToOutput(int index) const; 0176 0177 void setOutputOrder(const QList<Output *> &order); 0178 QList<Output *> outputOrder() const; 0179 0180 Output *activeOutput() const; 0181 void setActiveOutput(Output *output); 0182 void setActiveOutput(const QPointF &pos); 0183 void setActiveCursorOutput(Output *output); 0184 void setActiveCursorOutput(const QPointF &pos); 0185 0186 /** 0187 * Returns the active window, i.e. the window that has the focus (or None 0188 * if no window has the focus) 0189 */ 0190 Window *activeWindow() const; 0191 /** 0192 * Window that was activated, but it's not yet really activeWindow(), because 0193 * we didn't process yet the matching FocusIn event. Used mostly in focus 0194 * stealing prevention code. 0195 */ 0196 Window *mostRecentlyActivatedWindow() const; 0197 0198 Window *windowUnderMouse(Output *output) const; 0199 0200 void activateWindow(Window *window, bool force = false); 0201 bool requestFocus(Window *window, bool force = false); 0202 enum ActivityFlag { 0203 ActivityFocus = 1 << 0, // focus the window 0204 ActivityFocusForce = 1 << 1 | ActivityFocus, // focus even if Dock etc. 0205 ActivityRaise = 1 << 2 // raise the window 0206 }; 0207 Q_DECLARE_FLAGS(ActivityFlags, ActivityFlag) 0208 bool takeActivity(Window *window, ActivityFlags flags); 0209 bool restoreFocus(); 0210 void gotFocusIn(const Window *window); 0211 void setShouldGetFocus(Window *window); 0212 bool activateNextWindow(Window *window); 0213 bool focusChangeEnabled() 0214 { 0215 return block_focus == 0; 0216 } 0217 0218 /** 0219 * Indicates that the given @a window is being moved or resized by the user. 0220 */ 0221 void setMoveResizeWindow(Window *window); 0222 0223 QRectF adjustClientArea(Window *window, const QRectF &area) const; 0224 QPointF adjustWindowPosition(Window *window, QPointF pos, bool unrestricted, double snapAdjust = 1.0); 0225 QRectF adjustWindowSize(Window *window, QRectF moveResizeGeom, Gravity gravity); 0226 void raiseWindow(Window *window, bool nogroup = false); 0227 void lowerWindow(Window *window, bool nogroup = false); 0228 void raiseWindowRequest(Window *window, NET::RequestSource src = NET::FromApplication, xcb_timestamp_t timestamp = 0); 0229 void lowerWindowRequest(X11Window *window, NET::RequestSource src, xcb_timestamp_t timestamp); 0230 void lowerWindowRequest(Window *window); 0231 void restackWindowUnderActive(Window *window); 0232 void restack(Window *window, Window *under, bool force = false); 0233 void raiseOrLowerWindow(Window *window); 0234 void resetUpdateToolWindowsTimer(); 0235 void restoreSessionStackingOrder(X11Window *window); 0236 void updateStackingOrder(bool propagate_new_windows = false); 0237 void forceRestacking(); 0238 0239 void constrain(Window *below, Window *above); 0240 void unconstrain(Window *below, Window *above); 0241 0242 void windowHidden(Window *); 0243 void windowAttentionChanged(Window *, bool set); 0244 0245 /** 0246 * @returns List of all windows (either X11 or Wayland) currently managed by Workspace 0247 */ 0248 const QList<Window *> windows() const 0249 { 0250 return m_windows; 0251 } 0252 0253 void stackScreenEdgesUnderOverrideRedirect(); 0254 0255 SessionManager *sessionManager() const; 0256 0257 /** 0258 * @returns the TileManager associated to a given output 0259 */ 0260 TileManager *tileManager(Output *output); 0261 0262 public: 0263 QPoint cascadeOffset(const Window *c) const; 0264 0265 private: 0266 QTimer *m_quickTileCombineTimer; 0267 QuickTileMode m_lastTilingMode; 0268 0269 //------------------------------------------------- 0270 // Unsorted 0271 0272 public: 0273 // True when performing Workspace::updateClientArea(). 0274 // The calls below are valid only in that case. 0275 bool inUpdateClientArea() const; 0276 StrutRects previousRestrictedMoveArea(const VirtualDesktop *desktop, StrutAreas areas = StrutAreaAll) const; 0277 QHash<const Output *, QRect> previousScreenSizes() const; 0278 0279 /** 0280 * Returns the list of windows sorted in stacking order, with topmost window 0281 * at the last position 0282 */ 0283 const QList<Window *> &stackingOrder() const; 0284 QList<Window *> unconstrainedStackingOrder() const; 0285 QList<X11Window *> ensureStackingOrder(const QList<X11Window *> &windows) const; 0286 QList<Window *> ensureStackingOrder(const QList<Window *> &windows) const; 0287 0288 Window *topWindowOnDesktop(VirtualDesktop *desktop, Output *output = nullptr, bool unconstrained = false, 0289 bool only_normal = true) const; 0290 Window *findDesktop(bool topmost, VirtualDesktop *desktop) const; 0291 void sendWindowToDesktops(Window *window, const QList<VirtualDesktop *> &desktops, bool dont_activate); 0292 void windowToPreviousDesktop(Window *window); 0293 void windowToNextDesktop(Window *window); 0294 void sendWindowToOutput(Window *window, Output *output); 0295 0296 void addManualOverlay(xcb_window_t id) 0297 { 0298 manual_overlays << id; 0299 } 0300 void removeManualOverlay(xcb_window_t id) 0301 { 0302 manual_overlays.removeOne(id); 0303 } 0304 0305 /** 0306 * Shows the menu operations menu for the window and makes it active if 0307 * it's not already. 0308 */ 0309 void showWindowMenu(const QRect &pos, Window *cl); 0310 UserActionsMenu *userActionsMenu() const 0311 { 0312 return m_userActionsMenu; 0313 } 0314 0315 void showApplicationMenu(const QRect &pos, Window *window, int actionId); 0316 0317 void updateMinimizedOfTransients(Window *); 0318 void updateOnAllDesktopsOfTransients(Window *); 0319 void checkTransients(xcb_window_t w); 0320 0321 SessionInfo *takeSessionInfo(X11Window *); 0322 0323 // D-Bus interface 0324 QString supportInformation() const; 0325 0326 enum Direction { 0327 DirectionNorth, 0328 DirectionEast, 0329 DirectionSouth, 0330 DirectionWest, 0331 DirectionPrev, 0332 DirectionNext 0333 }; 0334 Output *findOutput(Output *reference, Direction direction, bool wrapAround = false) const; 0335 void switchToOutput(Output *output); 0336 0337 QList<Output *> outputs() const; 0338 Output *outputAt(const QPointF &pos) const; 0339 0340 /** 0341 * Set "Show Desktop" status 0342 * 0343 * @param showing @c true to show the desktop, @c false to restore the window positions 0344 * @param animated @c true if the "Show Desktop Animation" should be played, otherwise @c false 0345 */ 0346 void setShowingDesktop(bool showing, bool animated = true); 0347 bool showingDesktop() const; 0348 0349 void removeX11Window(X11Window *); // Only called from X11Window::destroyWindow() or X11Window::releaseWindow() 0350 void setActiveWindow(Window *window); 0351 Group *findGroup(xcb_window_t leader) const; 0352 void addGroup(Group *group); 0353 void removeGroup(Group *group); 0354 Group *findClientLeaderGroup(const X11Window *c) const; 0355 int unconstainedStackingOrderIndex(const X11Window *c) const; 0356 0357 void removeUnmanaged(X11Window *); 0358 void removeDeleted(Window *); 0359 void addDeleted(Window *); 0360 0361 bool checkStartupNotification(xcb_window_t w, KStartupInfoId &id, KStartupInfoData &data); 0362 0363 void focusToNull(); // SELI TODO: Public? 0364 0365 void windowShortcutUpdated(Window *window); 0366 bool shortcutAvailable(const QKeySequence &cut, Window *ignore = nullptr) const; 0367 bool globalShortcutsDisabled() const; 0368 void disableGlobalShortcutsForClient(bool disable); 0369 0370 void setWasUserInteraction(); 0371 bool wasUserInteraction() const; 0372 0373 qreal packPositionLeft(const Window *window, qreal oldX, bool leftEdge) const; 0374 qreal packPositionRight(const Window *window, qreal oldX, bool rightEdge) const; 0375 qreal packPositionUp(const Window *window, qreal oldY, bool topEdge) const; 0376 qreal packPositionDown(const Window *window, qreal oldY, bool bottomEdge) const; 0377 0378 void cancelDelayFocus(); 0379 void requestDelayFocus(Window *); 0380 0381 /** 0382 * updates the mouse position to track whether a focus follow mouse focus change was caused by 0383 * an actual mouse move 0384 * is esp. called on enter/motion events of inactive windows 0385 * since an active window doesn't receive mouse events, it must also be invoked if a (potentially) 0386 * active window might be moved/resize away from the cursor (causing a leave event) 0387 */ 0388 void updateFocusMousePosition(const QPointF &pos); 0389 QPointF focusMousePosition() const; 0390 0391 /** 0392 * Returns a window that is currently being moved or resized by the user. 0393 * 0394 * If none of windows is being moved or resized, @c null will be returned. 0395 */ 0396 Window *moveResizeWindow() 0397 { 0398 return m_moveResizeWindow; 0399 } 0400 0401 void quickTileWindow(QuickTileMode mode); 0402 void switchWindow(Direction direction); 0403 0404 ShortcutDialog *shortcutDialog() const 0405 { 0406 return m_windowKeysDialog; 0407 } 0408 0409 void addInternalWindow(InternalWindow *window); 0410 void removeInternalWindow(InternalWindow *window); 0411 0412 /** 0413 * @internal 0414 * Used by session management 0415 */ 0416 void setInitialDesktop(int desktop); 0417 0418 bool inShouldGetFocus(Window *w) const 0419 { 0420 return should_get_focus.contains(w); 0421 } 0422 Window *lastActiveWindow() const 0423 { 0424 return m_lastActiveWindow; 0425 } 0426 FocusChain *focusChain() const; 0427 ApplicationMenu *applicationMenu() const; 0428 Decoration::DecorationBridge *decorationBridge() const; 0429 Outline *outline() const; 0430 Placement *placement() const; 0431 RuleBook *rulebook() const; 0432 ScreenEdges *screenEdges() const; 0433 #if KWIN_BUILD_TABBOX 0434 TabBox::TabBox *tabbox() const; 0435 #endif 0436 #if KWIN_BUILD_ACTIVITIES 0437 Activities *activities() const; 0438 #endif 0439 0440 /** 0441 * Apply the requested output configuration. Note that you must use this function 0442 * instead of Platform::applyOutputChanges(). 0443 */ 0444 bool applyOutputConfiguration(const OutputConfiguration &config, const QList<Output *> &outputOrder = {}); 0445 0446 public Q_SLOTS: 0447 void performWindowOperation(KWin::Window *window, Options::WindowOperation op); 0448 // Keybindings 0449 // void slotSwitchToWindow( int ); 0450 void slotWindowToDesktop(VirtualDesktop *desktop); 0451 0452 // void slotWindowToListPosition( int ); 0453 void slotSwitchToScreen(Output *output); 0454 void slotWindowToScreen(Output *output); 0455 void slotSwitchToLeftScreen(); 0456 void slotSwitchToRightScreen(); 0457 void slotSwitchToAboveScreen(); 0458 void slotSwitchToBelowScreen(); 0459 void slotSwitchToPrevScreen(); 0460 void slotSwitchToNextScreen(); 0461 void slotWindowToLeftScreen(); 0462 void slotWindowToRightScreen(); 0463 void slotWindowToAboveScreen(); 0464 void slotWindowToBelowScreen(); 0465 void slotWindowToNextScreen(); 0466 void slotWindowToPrevScreen(); 0467 0468 void slotToggleShowDesktop(); 0469 0470 void slotWindowMaximize(); 0471 void slotWindowMaximizeVertical(); 0472 void slotWindowMaximizeHorizontal(); 0473 void slotWindowMinimize(); 0474 void slotWindowShade(); 0475 void slotWindowRaise(); 0476 void slotWindowLower(); 0477 void slotWindowRaiseOrLower(); 0478 void slotActivateAttentionWindow(); 0479 0480 void slotWindowCenter(); 0481 0482 void slotWindowMoveLeft(); 0483 void slotWindowMoveRight(); 0484 void slotWindowMoveUp(); 0485 void slotWindowMoveDown(); 0486 void slotWindowExpandHorizontal(); 0487 void slotWindowExpandVertical(); 0488 void slotWindowShrinkHorizontal(); 0489 void slotWindowShrinkVertical(); 0490 0491 void slotIncreaseWindowOpacity(); 0492 void slotLowerWindowOpacity(); 0493 0494 void slotWindowOperations(); 0495 void slotWindowClose(); 0496 void slotWindowMove(); 0497 void slotWindowResize(); 0498 void slotWindowAbove(); 0499 void slotWindowBelow(); 0500 void slotWindowOnAllDesktops(); 0501 void slotWindowFullScreen(); 0502 void slotWindowNoBorder(); 0503 0504 void slotWindowToNextDesktop(); 0505 void slotWindowToPreviousDesktop(); 0506 void slotWindowToDesktopRight(); 0507 void slotWindowToDesktopLeft(); 0508 void slotWindowToDesktopUp(); 0509 void slotWindowToDesktopDown(); 0510 0511 void reconfigure(); 0512 void slotReconfigure(); 0513 0514 void slotKillWindow(); 0515 0516 void slotSetupWindowShortcut(); 0517 void setupWindowShortcutDone(bool); 0518 0519 void updateClientArea(); 0520 0521 private Q_SLOTS: 0522 void desktopResized(); 0523 void selectWmInputEventMask(); 0524 void slotUpdateToolWindows(); 0525 void delayFocus(); 0526 void slotReloadConfig(); 0527 void updateCurrentActivity(const QString &new_activity); 0528 // virtual desktop handling 0529 void slotCurrentDesktopChanged(VirtualDesktop *previousDesktop, VirtualDesktop *newDesktop); 0530 void slotCurrentDesktopChanging(VirtualDesktop *currentDesktop, QPointF delta); 0531 void slotCurrentDesktopChangingCancelled(); 0532 void slotDesktopAdded(VirtualDesktop *desktop); 0533 void slotDesktopRemoved(VirtualDesktop *desktop); 0534 void slotOutputBackendOutputsQueried(); 0535 0536 Q_SIGNALS: 0537 /** 0538 * Emitted after the Workspace has setup the complete initialization process. 0539 * This can be used to connect to for performing post-workspace initialization. 0540 */ 0541 void workspaceInitialized(); 0542 void geometryChanged(); 0543 0544 // Signals required for the scripting interface 0545 void currentActivityChanged(); 0546 void currentDesktopChanged(KWin::VirtualDesktop *previousDesktop, KWin::Window *); 0547 void currentDesktopChanging(KWin::VirtualDesktop *currentDesktop, QPointF delta, KWin::Window *); // for realtime animations 0548 void currentDesktopChangingCancelled(); 0549 void windowAdded(KWin::Window *); 0550 void windowRemoved(KWin::Window *); 0551 void windowActivated(KWin::Window *); 0552 void windowMinimizedChanged(KWin::Window *); 0553 void groupAdded(KWin::Group *); 0554 void deletedRemoved(KWin::Window *); 0555 void configChanged(); 0556 void showingDesktopChanged(bool showing, bool animated); 0557 void outputOrderChanged(); 0558 void outputAdded(KWin::Output *); 0559 void outputRemoved(KWin::Output *); 0560 void outputsChanged(); 0561 /** 0562 * This signal is emitted when the stacking order changed, i.e. a window is risen 0563 * or lowered 0564 */ 0565 void stackingOrderChanged(); 0566 0567 private: 0568 void init(); 0569 void initializeX11(); 0570 void cleanupX11(); 0571 void initShortcuts(); 0572 template<typename Slot> 0573 void initShortcut(const QString &actionName, const QString &description, const QKeySequence &shortcut, Slot slot); 0574 template<typename T, typename Slot> 0575 void initShortcut(const QString &actionName, const QString &description, const QKeySequence &shortcut, T *receiver, Slot slot); 0576 void setupWindowShortcut(Window *window); 0577 bool switchWindow(Window *window, Direction direction, QPoint curPos, VirtualDesktop *desktop); 0578 0579 void propagateWindows(bool propagate_new_windows); // Called only from updateStackingOrder 0580 QList<Window *> constrainedStackingOrder(); 0581 void raiseWindowWithinApplication(Window *window); 0582 void lowerWindowWithinApplication(Window *window); 0583 bool allowFullClientRaising(const Window *window, xcb_timestamp_t timestamp); 0584 void blockStackingUpdates(bool block); 0585 void updateToolWindows(bool also_hide); 0586 void fixPositionAfterCrash(xcb_window_t w, const xcb_get_geometry_reply_t *geom); 0587 void saveOldScreenSizes(); 0588 void addToStack(Window *window); 0589 void removeFromStack(Window *window); 0590 0591 /// This is the right way to create a new X11 window 0592 X11Window *createX11Window(xcb_window_t windowId, bool is_mapped); 0593 void addX11Window(X11Window *c); 0594 void setupWindowConnections(Window *window); 0595 X11Window *createUnmanaged(xcb_window_t windowId); 0596 void addUnmanaged(X11Window *c); 0597 0598 void addWaylandWindow(Window *window); 0599 void removeWaylandWindow(Window *window); 0600 0601 //--------------------------------------------------------------------- 0602 0603 void closeActivePopup(); 0604 void updateWindowVisibilityOnDesktopChange(VirtualDesktop *newDesktop); 0605 void activateWindowOnNewDesktop(VirtualDesktop *desktop); 0606 Window *findWindowToActivateOnDesktop(VirtualDesktop *desktop); 0607 void removeWindow(Window *window); 0608 QString getPlacementTrackerHash(); 0609 0610 void updateOutputConfiguration(); 0611 void updateOutputs(const QList<Output *> &outputOrder = {}); 0612 void createDpmsFilter(); 0613 void maybeDestroyDpmsFilter(); 0614 0615 bool breaksShowingDesktop(Window *window) const; 0616 0617 struct Constraint 0618 { 0619 Window *below; 0620 Window *above; 0621 // All constraints above our "below" window 0622 QList<Constraint *> parents; 0623 // All constraints below our "above" window 0624 QList<Constraint *> children; 0625 // Used to prevent cycles. 0626 bool enqueued = false; 0627 }; 0628 0629 QList<Constraint *> m_constraints; 0630 QWidget *active_popup; 0631 Window *m_activePopupWindow; 0632 0633 int m_initialDesktop; 0634 void updateXStackingOrder(); 0635 void updateTabbox(); 0636 0637 QList<Output *> m_outputs; 0638 Output *m_activeOutput = nullptr; 0639 Output *m_activeCursorOutput = nullptr; 0640 QList<Output *> m_outputOrder; 0641 0642 Window *m_activeWindow; 0643 Window *m_lastActiveWindow; 0644 Window *m_moveResizeWindow; 0645 0646 // Delay(ed) window focus timer and window 0647 QTimer *delayFocusTimer; 0648 Window *m_delayFocusWindow; 0649 QPointF focusMousePos; 0650 0651 QList<Window *> m_windows; 0652 QList<Window *> deleted; 0653 0654 QList<Window *> unconstrained_stacking_order; // Topmost last 0655 QList<Window *> stacking_order; // Topmost last 0656 QList<xcb_window_t> manual_overlays; // Topmost last 0657 bool force_restacking; 0658 QList<Window *> should_get_focus; // Last is most recent 0659 QList<Window *> attention_chain; 0660 0661 bool showing_desktop; 0662 0663 QList<Group *> groups; 0664 0665 bool was_user_interaction; 0666 std::unique_ptr<X11EventFilter> m_wasUserInteractionFilter; 0667 0668 int block_focus; 0669 0670 /** 0671 * Holds the menu containing the user actions which is shown 0672 * on e.g. right click the window decoration. 0673 */ 0674 UserActionsMenu *m_userActionsMenu; 0675 0676 void modalActionsSwitch(bool enabled); 0677 0678 ShortcutDialog *m_windowKeysDialog = nullptr; 0679 Window *m_windowKeysWindow = nullptr; 0680 bool m_globalShortcutsDisabledForWindow = false; 0681 0682 // Timer to collect requests for 'reconfigure' 0683 QTimer reconfigureTimer; 0684 0685 QTimer updateToolWindowsTimer; 0686 0687 static Workspace *_self; 0688 0689 std::unique_ptr<KStartupInfo> m_startup; 0690 0691 QHash<const VirtualDesktop *, QRectF> m_workAreas; 0692 QHash<const VirtualDesktop *, StrutRects> m_restrictedAreas; 0693 QHash<const VirtualDesktop *, QHash<const Output *, QRectF>> m_screenAreas; 0694 QRect m_geometry; 0695 0696 QHash<const Output *, QRect> m_oldScreenGeometries; 0697 QHash<const VirtualDesktop *, StrutRects> m_oldRestrictedAreas; 0698 bool m_inUpdateClientArea = false; 0699 0700 int m_setActiveWindowRecursion = 0; 0701 int m_blockStackingUpdates = 0; // When > 0, stacking updates are temporarily disabled 0702 bool m_blockedPropagatingNewWindows; // Propagate also new windows after enabling stacking updates? 0703 std::unique_ptr<Xcb::Window> m_nullFocus; 0704 friend class StackingUpdatesBlocker; 0705 0706 std::unique_ptr<KillWindow> m_windowKiller; 0707 std::unique_ptr<X11EventFilter> m_movingClientFilter; 0708 std::unique_ptr<X11EventFilter> m_syncAlarmFilter; 0709 0710 SessionManager *m_sessionManager; 0711 std::unique_ptr<FocusChain> m_focusChain; 0712 std::unique_ptr<ApplicationMenu> m_applicationMenu; 0713 std::unique_ptr<Decoration::DecorationBridge> m_decorationBridge; 0714 std::unique_ptr<Outline> m_outline; 0715 std::unique_ptr<Placement> m_placement; 0716 std::unique_ptr<RuleBook> m_rulebook; 0717 std::unique_ptr<ScreenEdges> m_screenEdges; 0718 #if KWIN_BUILD_TABBOX 0719 std::unique_ptr<TabBox::TabBox> m_tabbox; 0720 #endif 0721 #if KWIN_BUILD_ACTIVITIES 0722 std::unique_ptr<Activities> m_activities; 0723 #endif 0724 std::unique_ptr<PlacementTracker> m_placementTracker; 0725 0726 PlaceholderOutput *m_placeholderOutput = nullptr; 0727 std::unique_ptr<PlaceholderInputEventFilter> m_placeholderFilter; 0728 std::map<Output *, std::unique_ptr<TileManager>> m_tileManagers; 0729 std::unique_ptr<OutputConfigurationStore> m_outputConfigStore; 0730 std::unique_ptr<LidSwitchTracker> m_lidSwitchTracker; 0731 std::unique_ptr<OrientationSensor> m_orientationSensor; 0732 std::unique_ptr<DpmsInputEventFilter> m_dpmsFilter; 0733 0734 private: 0735 friend bool performTransiencyCheck(); 0736 friend Workspace *workspace(); 0737 }; 0738 0739 /** 0740 * Helper for Workspace::blockStackingUpdates() being called in pairs (True/false) 0741 */ 0742 class StackingUpdatesBlocker 0743 { 0744 public: 0745 explicit StackingUpdatesBlocker(Workspace *w) 0746 : ws(w) 0747 { 0748 ws->blockStackingUpdates(true); 0749 } 0750 ~StackingUpdatesBlocker() 0751 { 0752 ws->blockStackingUpdates(false); 0753 } 0754 0755 private: 0756 Workspace *ws; 0757 }; 0758 0759 //--------------------------------------------------------- 0760 // Unsorted 0761 0762 inline QList<Output *> Workspace::outputs() const 0763 { 0764 return m_outputs; 0765 } 0766 0767 inline Window *Workspace::activeWindow() const 0768 { 0769 return m_activeWindow; 0770 } 0771 0772 inline Window *Workspace::mostRecentlyActivatedWindow() const 0773 { 0774 return should_get_focus.count() > 0 ? should_get_focus.last() : m_activeWindow; 0775 } 0776 0777 inline void Workspace::addGroup(Group *group) 0778 { 0779 Q_EMIT groupAdded(group); 0780 groups.append(group); 0781 } 0782 0783 inline void Workspace::removeGroup(Group *group) 0784 { 0785 groups.removeAll(group); 0786 } 0787 0788 inline const QList<Window *> &Workspace::stackingOrder() const 0789 { 0790 // TODO: Q_ASSERT( block_stacking_updates == 0 ); 0791 return stacking_order; 0792 } 0793 0794 inline bool Workspace::wasUserInteraction() const 0795 { 0796 return was_user_interaction; 0797 } 0798 0799 inline SessionManager *Workspace::sessionManager() const 0800 { 0801 return m_sessionManager; 0802 } 0803 0804 inline bool Workspace::showingDesktop() const 0805 { 0806 return showing_desktop; 0807 } 0808 0809 inline bool Workspace::globalShortcutsDisabled() const 0810 { 0811 return m_globalShortcutsDisabledForWindow; 0812 } 0813 0814 inline void Workspace::forceRestacking() 0815 { 0816 force_restacking = true; 0817 StackingUpdatesBlocker blocker(this); // Do restacking if not blocked 0818 } 0819 0820 inline void Workspace::updateFocusMousePosition(const QPointF &pos) 0821 { 0822 focusMousePos = pos; 0823 } 0824 0825 inline QPointF Workspace::focusMousePosition() const 0826 { 0827 return focusMousePos; 0828 } 0829 0830 inline Workspace *workspace() 0831 { 0832 return Workspace::_self; 0833 } 0834 0835 } // namespace 0836 Q_DECLARE_OPERATORS_FOR_FLAGS(KWin::Workspace::ActivityFlags)