File indexing completed on 2024-11-10 13:22:56
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)