File indexing completed on 2024-02-18 16:20:24

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