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