File indexing completed on 2024-04-21 15:05:42

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