File indexing completed on 2024-04-14 03:57:03
0001 /* 0002 This file is part of the KDE libraries 0003 SPDX-FileCopyrightText: 1999 Matthias Ettrich <ettrich@kde.org> 0004 SPDX-FileCopyrightText: 2007 Lubos Lunak <l.lunak@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.1-or-later 0007 */ 0008 0009 #ifndef KX11EXTRAS_H 0010 #define KX11EXTRAS_H 0011 0012 #include <QObject> 0013 #include <QWindow> 0014 0015 #include <kwindowsystem_export.h> 0016 0017 #include "netwm_def.h" 0018 0019 class NETWinInfo; 0020 class NETEventFilter; 0021 0022 /** 0023 * A collection of functions to obtain information from and manipulate 0024 * X11 windows. These are generally not applicable to other window systems 0025 * 0026 * @since 5.101 0027 */ 0028 class KWINDOWSYSTEM_EXPORT KX11Extras : public QObject 0029 { 0030 Q_OBJECT 0031 0032 /** 0033 * @brief Whether desktop compositing is active 0034 */ 0035 Q_PROPERTY(bool compositingActive READ compositingActive NOTIFY compositingChanged) 0036 0037 public: 0038 static KX11Extras *self(); 0039 0040 /** 0041 * Returns the list of all toplevel windows currently managed by the 0042 * window manager in the order of creation. Please do not rely on 0043 * indexes of this list: Whenever you enter Qt's event loop in your 0044 * application, it may happen that entries are removed or added. 0045 * Your module should perhaps work on a copy of this list and verify a 0046 * window with hasWId() before any operations. 0047 * 0048 * Iteration over this list can be done easily with 0049 * \code 0050 * QList<WId> windows = KWindowSystem::windows(); 0051 * for (auto it = windows.cbegin(), end = windows.cend(); it != end; ++it) { 0052 * ... do something here, (*it) is the current WId. 0053 * } 0054 * \endcode 0055 * @return the list of all toplevel windows 0056 */ 0057 static QList<WId> windows(); 0058 0059 /** 0060 * Test to see if @p id still managed at present. 0061 * @param id the window id to test 0062 * @return true if the window id is still managed 0063 **/ 0064 static bool hasWId(WId id); 0065 0066 /** 0067 * Returns the list of all toplevel windows currently managed by the 0068 * window manager in the current stacking order (from lower to 0069 * higher). May be useful for pagers. 0070 * @return the list of all toplevel windows in stacking order 0071 */ 0072 static QList<WId> stackingOrder(); 0073 0074 /** 0075 * Returns the currently active window, or 0 if no window is active. 0076 * @return the window id of the active window, or 0 if no window is 0077 * active 0078 **/ 0079 static WId activeWindow(); 0080 0081 /** 0082 * Requests that window @p win is activated. 0083 * 0084 * There are two ways how to activate a window, by calling 0085 * activateWindow() and forceActiveWindow(). Generally, 0086 * applications shouldn't make attempts to explicitly activate 0087 * their windows, and instead let the user to activate them. 0088 * In the special cases where this may be needed, applications 0089 * should use activateWindow(). Window manager may consider whether 0090 * this request wouldn't result in focus stealing, which 0091 * would be obtrusive, and may refuse the request. 0092 * 0093 * The usage of forceActiveWindow() is meant only for pagers 0094 * and similar tools, which represent direct user actions 0095 * related to window manipulation. 0096 * Except for rare cases, this request will be always honored, 0097 * and normal applications are forbidden to use it. 0098 * 0099 * In case of problems, consult the KWin README in the kdebase 0100 * package (kdebase/kwin/README), or ask on the kwin@kde.org 0101 * mailing list. 0102 * 0103 * @param win the id of the window to make active 0104 * @param time X server timestamp of the user activity that 0105 * caused this request 0106 */ 0107 static void activateWindow(WId win, long time = 0); 0108 0109 /** 0110 * Sets window @p win to be the active window. Note that this 0111 * should be called only in special cases, applications 0112 * shouldn't force themselves or other windows to be the active 0113 * window. Generally, this call should used only by pagers 0114 * and similar tools. See the explanation in description 0115 * of activateWindow(). 0116 * 0117 * @param win the id of the window to make active 0118 * @param time X server timestamp of the user activity that 0119 * caused this request 0120 */ 0121 static void forceActiveWindow(WId win, long time = 0); 0122 0123 /** 0124 * Sets window @p win to be the active window. Note that this 0125 * should be called only in special cases, applications 0126 * shouldn't force themselves or other windows to be the active 0127 * window. Generally, this call should used only by pagers 0128 * and similar tools. See the explanation in the description 0129 * of activateWindow(). 0130 * 0131 * @param win the window to make active 0132 * @param time X server timestamp of the user activity that 0133 * caused this request 0134 * @since 6.0 0135 */ 0136 Q_INVOKABLE static void forceActiveWindow(QWindow *window, long time = 0); 0137 0138 /** 0139 * Returns true if a compositing manager is running (i.e. ARGB windows 0140 * are supported, effects will be provided, etc.). 0141 */ 0142 static bool compositingActive(); 0143 0144 /** 0145 * Returns the current virtual desktop. 0146 * @return the current virtual desktop 0147 **/ 0148 static int currentDesktop(); 0149 0150 /** 0151 * Returns the number of virtual desktops. 0152 * @return the number of virtual desktops 0153 **/ 0154 static int numberOfDesktops(); 0155 0156 /** 0157 * Convenience function to set the current desktop to @p desktop. 0158 * See NETRootInfo. 0159 * @param desktop the number of the new desktop 0160 */ 0161 static void setCurrentDesktop(int desktop); 0162 0163 /** 0164 * Sets window @p win to be present on all virtual desktops if @p 0165 * is true. Otherwise the window lives only on one single desktop. 0166 * 0167 * @param win the id of the window 0168 * @param b true to show the window on all desktops, false 0169 * otherwise 0170 */ 0171 static void setOnAllDesktops(WId win, bool b); 0172 0173 /** 0174 * Moves window @p win to desktop @p desktop. 0175 * 0176 * @param win the id of the window 0177 * @param desktop the number of the new desktop 0178 */ 0179 static void setOnDesktop(WId win, int desktop); 0180 0181 /** 0182 * Moves window @p win to activities @p activities. 0183 * 0184 * @param win the id of the window 0185 * @param activities the list of activity UUIDs 0186 * 0187 * @see KWindowInfo::activities 0188 */ 0189 static void setOnActivities(WId win, const QStringList &activities); 0190 0191 /** 0192 * Returns an icon for window @p win. 0193 * 0194 * If @p width and @p height are specified, the best icon for the requested 0195 * size is returned. 0196 * 0197 * If @p scale is true, the icon is smooth-scaled to have exactly 0198 * the requested size. 0199 * 0200 * @param win the id of the window 0201 * @param width the desired width, or -1 0202 * @param height the desired height, or -1 0203 * @param scale if true the icon will be scaled to the desired size. Otherwise the 0204 * icon will not be modified. 0205 * @return the icon of the window 0206 */ 0207 static QPixmap icon(WId win, int width = -1, int height = -1, bool scale = false); 0208 0209 /** 0210 * Masks specifying from which sources to read an icon. They are tried from the best 0211 * until an icon is found. 0212 * @li NETWM from property from the window manager specification 0213 * @li WMHints from WMHints property 0214 * @li ClassHint load icon after getting name from the classhint 0215 * @li XApp load the standard X icon (last fallback) 0216 */ 0217 enum IconSource { 0218 NETWM = 1, //!< read from property from the window manager specification 0219 WMHints = 2, //!< read from WMHints property 0220 ClassHint = 4, //!< load icon after getting name from the classhint 0221 XApp = 8, //!< load the standard X icon (last fallback) 0222 }; 0223 /** 0224 * @overload 0225 * 0226 * Overloaded variant that allows specifying from which sources the icon should be read. 0227 * You should usually prefer the simpler variant which tries all possibilities to get 0228 * an icon. 0229 * 0230 * @param win the id of the window 0231 * @param width the desired width, or -1 0232 * @param height the desired height, or -1 0233 * @param scale if true the icon will be scaled to the desired size. Otherwise the 0234 * icon will not be modified. 0235 * @param flags OR-ed flags from the IconSource enum 0236 */ 0237 static QPixmap icon(WId win, int width, int height, bool scale, int flags); 0238 0239 /** 0240 * @overload 0241 * 0242 * Overloaded variant that allows passing in the NETWinInfo to use for reading the 0243 * information. This variant is only useful on the X11 platform, other platforms do not 0244 * use NETWinInfo and delegate to the variant without NETWinInfo. Though if compiled with 0245 * X11 support the X11 variant is used on other platforms if info is not @c nullptr. 0246 * This can be used by applications using e.g. platform wayland but also connecting to an 0247 * XServer. 0248 * 0249 * The NETWinInfo must be constructed with property NET::WMIcon in order to use the 0250 * IconSource flag NETWM. NET::WM2IconPixmap for IconSource flag WMHints and 0251 * NET::WM2WindowClass for IconSource flag ClassHint. 0252 * 0253 * @param win the id of the window 0254 * @param width the desired width, or -1 0255 * @param height the desired height, or -1 0256 * @param scale if true the icon will be scaled to the desired size. Otherwise the 0257 * icon will not be modified. 0258 * @param flags OR-ed flags from the IconSource enum 0259 * @param into the NETWinInfo to use for reading properties. 0260 **/ 0261 static QPixmap icon(WId win, int width, int height, bool scale, int flags, NETWinInfo *info); 0262 0263 /** 0264 * Minimizes the window with id @p win. 0265 * On X11 this follows the protocol described in ICCCM section 4.1.4. 0266 * 0267 * @param win The window to minimize 0268 * @see unminimizeWindow() 0269 */ 0270 static void minimizeWindow(WId win); 0271 /** 0272 * Unminimizes the window with id @p win. 0273 * On X11 this follows the protocol described in ICCCM section 4.1.4. 0274 * 0275 * @param win The window to unminimize 0276 * @see minimizeWindow() 0277 **/ 0278 static void unminimizeWindow(WId win); 0279 0280 /** 0281 * Returns the workarea for the specified desktop, or the current 0282 * work area if no desktop has been specified. 0283 * @param desktop the number of the desktop to check, -1 for the 0284 * current desktop 0285 * @return the size and position of the desktop 0286 **/ 0287 static QRect workArea(int desktop = -1); 0288 0289 /** 0290 * Returns the workarea for the specified desktop, or the current 0291 * work area if no desktop has been specified. Excludes struts of 0292 * clients in the exclude List. 0293 * 0294 * @param excludes the list of clients whose struts will be excluded 0295 * @param desktop the number of the desktop to check, -1 for the 0296 * current desktop 0297 * @return the size and position of the desktop 0298 **/ 0299 static QRect workArea(const QList<WId> &excludes, int desktop = -1); 0300 0301 /** 0302 * Returns the name of the specified desktop. 0303 * @param desktop the number of the desktop 0304 * @return the name of the desktop 0305 **/ 0306 static QString desktopName(int desktop); 0307 0308 /** 0309 * Sets the name of the specified desktop. 0310 * @param desktop the number of the desktop 0311 * @param name the new name for the desktop 0312 **/ 0313 static void setDesktopName(int desktop, const QString &name); 0314 0315 /** 0316 * Function that reads and returns the contents of the given text 0317 * property (WM_NAME, WM_ICON_NAME,...). 0318 */ 0319 static QString readNameProperty(WId window, unsigned long atom); 0320 0321 /** 0322 * Returns true if viewports are mapped to virtual desktops. 0323 */ 0324 static bool mapViewport(); 0325 0326 /** 0327 * Sets the strut of window @p win to @p left_width 0328 * ranging from @p left_start to @p left_end on the left edge, 0329 * and simiarly for the other edges. For not reserving a strut, pass 0 as the width. 0330 * E.g. to reserve 10x10 square in the topleft corner, use e.g. 0331 * setExtendedStrut( w, 10, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0 ). 0332 * 0333 * @param win the id of the window 0334 * @param left_width width of the strut at the left edge 0335 * @param left_start starting y coordinate of the strut at the left edge 0336 * @param left_end ending y coordinate of the strut at the left edge 0337 * @param right_width width of the strut at the right edge 0338 * @param right_start starting y coordinate of the strut at the right edge 0339 * @param right_end ending y coordinate of the strut at the right edge 0340 * @param top_width width of the strut at the top edge 0341 * @param top_start starting x coordinate of the strut at the top edge 0342 * @param top_end ending x coordinate of the strut at the top edge 0343 * @param bottom_width width of the strut at the bottom edge 0344 * @param bottom_start starting x coordinate of the strut at the bottom edge 0345 * @param bottom_end ending x coordinate of the strut at the bottom edge 0346 */ 0347 static void setExtendedStrut(WId win, 0348 qreal left_width, 0349 qreal left_start, 0350 qreal left_end, 0351 qreal right_width, 0352 qreal right_start, 0353 qreal right_end, 0354 qreal top_width, 0355 qreal top_start, 0356 qreal top_end, 0357 qreal bottom_width, 0358 qreal bottom_start, 0359 qreal bottom_end); 0360 /** 0361 * Convenience function for setExtendedStrut() that automatically makes struts 0362 * as wide/high as the screen width/height. 0363 * Sets the strut of window @p win to @p left, @p right, @p top, @p bottom. 0364 * 0365 * @param win the id of the window 0366 * @param left the left strut 0367 * @param right the right strut 0368 * @param top the top strut 0369 * @param bottom the bottom strut 0370 */ 0371 static void setStrut(WId win, qreal left, qreal right, qreal top, qreal bottom); 0372 0373 /** 0374 * Sets the type of window @p win to @p windowType. 0375 * 0376 * @param win the id of the window 0377 * @param windowType the type of the window (see NET::WindowType) 0378 * 0379 * @since 6.0 0380 */ 0381 static void setType(WId win, NET::WindowType windowType); 0382 0383 /** 0384 * Clears the state of window @p win from @p state. 0385 * 0386 * Possible values are or'ed combinations of NET::Modal, 0387 * NET::Sticky, NET::MaxVert, NET::MaxHoriz, NET::Shaded, 0388 * NET::SkipTaskbar, NET::SkipPager, NET::Hidden, 0389 * NET::FullScreen, NET::KeepAbove, NET::KeepBelow, 0390 * NET::SkipSwitcher 0391 * 0392 * @param win the id of the window 0393 * @param state the flags that will be cleared 0394 * 0395 * @since 6.0 0396 */ 0397 static void clearState(WId win, NET::States state); 0398 0399 /** 0400 * Sets the state of window @p win to @p state. 0401 * 0402 * Possible values are or'ed combinations of NET::Modal, 0403 * NET::Sticky, NET::MaxVert, NET::MaxHoriz, NET::Shaded, 0404 * NET::SkipTaskbar, NET::SkipPager, NET::Hidden, 0405 * NET::FullScreen, NET::KeepAbove, NET::KeepBelow, 0406 * NET::SkipSwitcher 0407 * 0408 * @param win the id of the window 0409 * @param state the new flags that will be set 0410 * 0411 * @since 6.0 0412 */ 0413 static void setState(WId win, NET::States state); 0414 0415 Q_SIGNALS: 0416 0417 /** 0418 * Switched to another virtual desktop. 0419 * @param desktop the number of the new desktop 0420 */ 0421 void currentDesktopChanged(int desktop); 0422 0423 /** 0424 * A window has been added. 0425 * @param id the id of the window 0426 */ 0427 void windowAdded(WId id); 0428 0429 /** 0430 * A window has been removed. 0431 * @param id the id of the window that has been removed 0432 */ 0433 void windowRemoved(WId id); 0434 0435 /** 0436 * Hint that \<Window> is active (= has focus) now. 0437 * @param id the id of the window that is active 0438 */ 0439 void activeWindowChanged(WId id); 0440 0441 /** 0442 * Desktops have been renamed. 0443 */ 0444 void desktopNamesChanged(); 0445 0446 /** 0447 * The number of desktops changed. 0448 * @param num the new number of desktops 0449 */ 0450 void numberOfDesktopsChanged(int num); 0451 0452 /** 0453 * The workarea has changed. 0454 */ 0455 void workAreaChanged(); 0456 0457 /** 0458 * Something changed with the struts, may or may not have changed 0459 * the work area. Usually just using the workAreaChanged() signal 0460 * is sufficient. 0461 */ 0462 void strutChanged(); 0463 0464 /** 0465 * Emitted when the stacking order of the window changed. The new order 0466 * can be obtained with stackingOrder(). 0467 */ 0468 void stackingOrderChanged(); 0469 0470 /** 0471 * The window changed. 0472 * 0473 * Carries the NET::Properties and NET::Properties2 that were changed. 0474 * 0475 * @param id the id of the window 0476 * @param properties the properties that were modified 0477 * @param properties2 the properties2 that were modified 0478 */ 0479 void windowChanged(WId id, NET::Properties properties, NET::Properties2 properties2); 0480 0481 /** 0482 * Compositing was enabled or disabled. 0483 * 0484 * Note that this signal may be emitted before any compositing plugins 0485 * have been initialized in the window manager. 0486 * 0487 * If you need to check if a specific compositing plugin such as the 0488 * blur effect is enabled, you should track that separately rather 0489 * than test for it in a slot connected to this signal. 0490 */ 0491 void compositingChanged(bool enabled); 0492 0493 protected: 0494 void connectNotify(const QMetaMethod &signal) override; 0495 0496 private: 0497 friend class KWindowInfo; 0498 friend class KWindowSystemPrivateX11; 0499 friend class NETEventFilter; 0500 friend class MainThreadInstantiator; 0501 0502 enum FilterInfo { 0503 INFO_BASIC = 1, // desktop info, not per-window 0504 INFO_WINDOWS = 2, // also per-window info 0505 }; 0506 0507 KWINDOWSYSTEM_NO_EXPORT void init(FilterInfo info); 0508 KWINDOWSYSTEM_NO_EXPORT QPoint desktopToViewport(int desktop, bool absolute); 0509 KWINDOWSYSTEM_NO_EXPORT int viewportToDesktop(const QPoint &pos); 0510 0511 KWINDOWSYSTEM_NO_EXPORT QPoint constrainViewportRelativePosition(const QPoint &pos); 0512 0513 // used in xcb/kwindowsystem.cpp 0514 static bool showingDesktop(); 0515 static void setShowingDesktop(bool showing); 0516 0517 /** 0518 * @internal 0519 * Returns mapped virtual desktop for the given window geometry. 0520 */ 0521 KWINDOWSYSTEM_NO_EXPORT static int viewportWindowToDesktop(const QRect &r); 0522 0523 KWINDOWSYSTEM_NO_EXPORT NETEventFilter *s_d_func() 0524 { 0525 return d.get(); 0526 } 0527 std::unique_ptr<NETEventFilter> d; 0528 }; 0529 0530 #endif