File indexing completed on 2024-04-21 03:59:28

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  * kwindowinfo.h. Part of the KDE project.
0010  */
0011 
0012 #ifndef KWINDOWINFO_H
0013 #define KWINDOWINFO_H
0014 
0015 #include <QExplicitlySharedDataPointer>
0016 #include <QStringList>
0017 #include <QWidgetList> //For WId
0018 #include <kwindowsystem_export.h>
0019 
0020 #include <netwm_def.h>
0021 
0022 class KWindowInfoPrivate;
0023 
0024 /**
0025  * This class provides information about a given X11 window. It provides the information
0026  * for the current state when a KWindowInfo instance gets created.
0027  * The instance does not get updated when the
0028  * window changes. To get update about window changes connect to the
0029  * @link KX11Extras::windowChanged windowChanged@endlink signal of KX11Extras
0030  * and create a new KWindowInfo instance to reflect the current state.
0031  *
0032  * KWindowInfo does not encapsulate all information about the window. One needs to
0033  * request which information is required by passing the appropriate NET::Property and
0034  * NET::Property2 flags to the constructor. Please refer to the documentation of the
0035  * methods to see which flags are required. This is done to limit the interaction with
0036  * the xserver and avoid excess roundtrips.
0037  *
0038  * KWindowInfo does nothing when running outside of X11.
0039  *
0040  * Example usage of this class illustrated by monitoring a QWidget for change of the
0041  * demands attention window state:
0042  *
0043  * @code
0044  * QWidget *widget = new QWidget(nullptr);
0045  * widget->show(); // ensures native window gets created
0046  * connect(KX11Extras::self(), &KX11Extras::KWindowSystem::windowChanged,
0047  *        [window](WId id, NET::Properties properties, NET::Properties2 properties2) {
0048  *     if (widget->winId() != winId) {
0049  *         return; // not our window
0050  *     }
0051  *     if (properties & NET::WMState) {
0052  *         // let's check whether our window is demanding attention
0053  *         KWindowInfo info(widget->winId(), NET::WMState);
0054  *         qDebug() << "Has demands attention: " << info.hasState(NET::DemandsAttention);
0055  *     }
0056  * });
0057  * @endcode
0058  */
0059 class KWINDOWSYSTEM_EXPORT KWindowInfo
0060 {
0061 public:
0062     /**
0063      * Reads all the info about the given window.
0064      *
0065      * Only the information requested through the @p properties and @p properties2
0066      * parameters are fetched. Refer to the methods you are interested in to see
0067      * which flags to pass.
0068      *
0069      * @param window The platform specific window identifier
0070      * @param properties Bitmask of NET::Property
0071      * @param properties2 Bitmask of NET::Property2
0072      */
0073     KWindowInfo(WId window, NET::Properties properties, NET::Properties2 properties2 = NET::Properties2());
0074     ~KWindowInfo();
0075     /**
0076      * Returns false if this window info is not valid.
0077      *
0078      * In case the window does not exist @c false is returned.
0079      *
0080      * @param withdrawn_is_valid if true, windows in the withdrawn state
0081      *        (i.e. not managed) are also considered. This is usually not the case.
0082      */
0083     bool valid(bool withdrawn_is_valid = false) const;
0084     /**
0085      * Returns the window identifier.
0086      */
0087     WId win() const;
0088     /**
0089      * Returns the window's state flags.
0090      *
0091      * Requires NET::WMState passed as properties parameter to the constructor.
0092      *
0093      * @code
0094      * QWidget *window = new QWidget(nullptr);
0095      * window->show();
0096      * KWindowInfo info(window->winId(), NET::WMState);
0097      * if (info.valid())
0098      *     info.state();
0099      * @endcode
0100      *
0101      * @see NET::State
0102      */
0103     NET::States state() const;
0104     /**
0105      * Returns true if the window has the given state flag set.
0106      *
0107      * Requires NET::WMState passed as properties parameter to the constructor.
0108      * @code
0109      * QWidget *window = new QWidget(nullptr);
0110      * window->show();
0111      * KWindowInfo info(window->winId(), NET::WMState);
0112      * if (info.valid())
0113      *     info.hasState(NET::DemandsAttention);
0114      * @endcode
0115      *
0116      * @see NET::State
0117      */
0118     bool hasState(NET::States s) const;
0119     /**
0120      * Returns true if the window is minimized.
0121      *
0122      * Note that it is true only if the window is truly minimized,
0123      * not shaded or on another virtual desktops,
0124      * which makes it different from mappingState() == NET::Iconic
0125      * or QWidget::isMinimized().
0126      * Requires NET::WMState and NET::XAWMState passed as properties parameter to the constructor.
0127      *
0128      * @code
0129      * QWidget *window = new QWidget(nullptr);
0130      * window->show();
0131      * KWindowInfo info(window->winId(), NET::WMState | NET::XAWMState);
0132      * if (info.valid())
0133      *     info.isMinimized();
0134      * @endcode
0135      */
0136     bool isMinimized() const;
0137     /**
0138      * Returns the mapping state of the window.
0139      *
0140      * Note that it's very likely that you don't want to use this function,
0141      * and use isOnDesktop(), isMinimized() etc. instead.
0142      * Requires NET::XAWMState passed as properties parameter to the constructor.
0143      *
0144      * @code
0145      * QWidget *window = new QWidget(nullptr);
0146      * window->show();
0147      * KWindowInfo info(window->winId(), NET::XAWMState);
0148      * if (info.valid())
0149      *     info.mappingState();
0150      * @endcode
0151      *
0152      * @see NET::MappingState
0153      * @see isOnDesktop()
0154      * @see isMinimzed()
0155      */
0156     NET::MappingState mappingState() const;
0157     /**
0158      * Returns the window extended (partial) strut.
0159      *
0160      * Requires NET::WM2ExtendedStrut passed as properties2 parameter to the constructor.
0161      *
0162      * @code
0163      * QWidget *window = new QWidget(nullptr);
0164      * window->show();
0165      * KWindowInfo info(window->winId(), 0, NET::WM2ExtendedStrut);
0166      * if (info.valid())
0167      *     info.extendedStrut();
0168      * @endcode
0169      */
0170     NETExtendedStrut extendedStrut() const;
0171     /**
0172      * Returns the window type of this window.
0173      *
0174      * The argument should be all window types your application supports.
0175      * Requires NET::WMWindowType passed as properties parameter to the constructor.
0176      *
0177      * @code
0178      * QWidget *window = new QWidget(nullptr);
0179      * window->show();
0180      * KWindowInfo info(window->winId(), NET::WMWindowType);
0181      * if (info.valid())
0182      *     info.windowType(NET::NormalMask | NET::DialogMask);
0183      * @endcode
0184      *
0185      * @see NET::WindowType
0186      * @see NET::WindowTypeMask
0187      */
0188     NET::WindowType windowType(NET::WindowTypes supported_types) const;
0189     /**
0190      * Returns the visible name of the window.
0191      *
0192      * The visible name differs from the name by including possible <2> appended
0193      * when there are two or more windows with the same name.
0194      * Requires NET::WMVisibleName passed as properties parameter to the constructor.
0195      *
0196      * @code
0197      * QWidget *window = new QWidget(nullptr);
0198      * window->show();
0199      * KWindowInfo info(window->winId(), NET::WMVisibleName);
0200      * if (info.valid())
0201      *     info.visibleName();
0202      * @endcode
0203      *
0204      * @see name()
0205      */
0206     QString visibleName() const;
0207     /**
0208      * Returns a visible name with state.
0209      *
0210      * This is a simple convenience function that returns the
0211      * visible name but with parentheses around minimized windows.
0212      * Requires NET::WMVisibleName, NET::WMState and NET::XAWMState passed
0213      * as properties parameter to the constructor.
0214      * @return the window name with state
0215      *
0216      * @code
0217      * QWidget *window = new QWidget(nullptr);
0218      * window->show();
0219      * KWindowInfo info(window->winId(), NET::WMVisibleName | NET::WMState | NET::XAWMState);
0220      * if (info.valid())
0221      *     info.visibleNameWithState();
0222      * @endcode
0223      *
0224      * @see visibleName()
0225      */
0226     QString visibleNameWithState() const;
0227     /**
0228      * Returns the name of the window, as specified by the application.
0229      *
0230      * The difference to visibleName() is that this is the name provided by
0231      * the application without any modifications by the window manager.
0232      * You should often use visibleName() instead.
0233      * Requires NET::WMName passed as properties parameter to the constructor.
0234      *
0235      * @code
0236      * QWidget *window = new QWidget(nullptr);
0237      * window->show();
0238      * KWindowInfo info(window->winId(), NET::WMName);
0239      * if (info.valid())
0240      *     info.name();
0241      * @endcode
0242      *
0243      * @see visibleName()
0244      */
0245     QString name() const;
0246     /**
0247      * Returns the visible name of the window that should be shown in a taskbar.
0248      *
0249      * Note that this has nothing to do with normal icons but with an "iconic"
0250      * representation of the window.
0251      * Requires NET::WMVisibleIconName passed as properties parameter to the constructor.
0252      *
0253      * @code
0254      * QWidget *window = new QWidget(nullptr);
0255      * window->show();
0256      * KWindowInfo info(window->winId(), NET::WMVisibleIconName);
0257      * if (info.valid())
0258      *     info.visibleIconName();
0259      * @endcode
0260      */
0261     QString visibleIconName() const;
0262     /**
0263      * Returns a visible icon name with state.
0264      *
0265      * This is a simple convenience function that returns the
0266      * visible iconic name but with parentheses around minimized windows.
0267      * Note that this has nothing to do with normal icons.
0268      * Requires NET::WMVisibleIconName, NET::WMState and NET::XAWMState passed
0269      * as properties parameter to the constructor.
0270      * @return the window iconic name with state
0271      *
0272      * @code
0273      * QWidget *window = new QWidget(nullptr);
0274      * window->show();
0275      * KWindowInfo info(window->winId(), NET::WMVisibleIconName | NET::WMState | NET::XAWMState);
0276      * if (info.valid())
0277      *     info.visibleIconNameWithState();
0278      * @endcode
0279      *
0280      * @see visibleIconName()
0281      */
0282     QString visibleIconNameWithState() const;
0283     /**
0284      * Returns the name of the window that should be shown in taskbar.
0285      *
0286      * Note that this has nothing to do with normal icons but with an "iconic"
0287      * representation of the window.
0288      * Requires NET::WMIconName passed as properties parameter to the constructor.
0289      *
0290      * @code
0291      * QWidget *window = new QWidget(nullptr);
0292      * window->show();
0293      * KWindowInfo info(window->winId(), NET::WMIconName);
0294      * if (info.valid())
0295      *     info.iconName();
0296      * @endcode
0297      */
0298     QString iconName() const;
0299     /**
0300      * Returns true if the window is on the currently active virtual desktop.
0301      *
0302      * Requires NET::WMDesktop passed as properties parameter to the constructor.
0303      *
0304      * @code
0305      * QWidget *window = new QWidget(nullptr);
0306      * window->show();
0307      * KWindowInfo info(window->winId(), NET::WMDesktop);
0308      * if (info.valid())
0309      *     info.isOnCurrentDesktop();
0310      * @endcode
0311      */
0312     bool isOnCurrentDesktop() const;
0313     /**
0314      * Returns true if the window is on the given virtual desktop.
0315      *
0316      * Requires NET::WMDesktop passed as properties parameter to the constructor.
0317      *
0318      * @code
0319      * QWidget *window = new QWidget(nullptr);
0320      * window->show();
0321      * KWindowInfo info(window->winId(), NET::WMDesktop);
0322      * if (info.valid())
0323      *     info.isOnDesktop(KWindowSystem::currentDesktop());
0324      * @endcode
0325      */
0326     bool isOnDesktop(int desktop) const;
0327     /**
0328      * Returns true if the window is on all desktops.
0329      *
0330      * A window is on all desktops if desktop() returns NET::OnAllDesktops.
0331      * Requires NET::WMDesktop passed as properties parameter to the constructor.
0332      *
0333      * @code
0334      * QWidget *window = new QWidget(nullptr);
0335      * window->show();
0336      * KWindowInfo info(window->winId(), NET::WMDesktop);
0337      * if (info.valid())
0338      *     info.onAllDesktops();
0339      * @endcode
0340      *
0341      * @see desktop()
0342      */
0343     bool onAllDesktops() const;
0344     /**
0345      * Returns the virtual desktop this window is on.
0346      *
0347      * If the window is on all desktops NET::OnAllDesktops is returned.
0348      * You should prefer using isOnDesktop().
0349      * Requires NET::WMDesktop passed as properties parameter to the constructor.
0350      *
0351      * @code
0352      * QWidget *window = new QWidget(nullptr);
0353      * window->show();
0354      * KWindowInfo info(window->winId(), NET::WMDesktop);
0355      * if (info.valid())
0356      *     info.desktop();
0357      * @endcode
0358      *
0359      * @see isOnDesktop()
0360      */
0361     int desktop() const;
0362     /**
0363      * Returns the list of activity UUIDs this window belongs to.
0364      *
0365      * The Plasma workspace allows the user to separate her work into
0366      * different activities, by assigning windows, documents etc. to
0367      * the specific ones. An activity is an abstract concept whose meaning
0368      * can differ from one user to another. Typical examples of activities
0369      * are "developing a KDE project", "studying the 19th century art",
0370      * "composing music", "lazing on a Sunday afternoon" etc.
0371      *
0372      * If the list is empty, or contains a null UUID, the window is on
0373      * all activities.
0374      *
0375      * Requires NET::WM2Activities passed as properties parameter to the constructor.
0376      *
0377      * @code
0378      * QWidget *window = new QWidget(nullptr);
0379      * window->show();
0380      * KWindowInfo info(window->winId(), 0, NET::WM2Activities);
0381      * if (info.valid())
0382      *     info.desktop();
0383      * @endcode
0384      *
0385      * @note Activities are only supported on Plasma Workspace on X11
0386      *
0387      * @since 5.0
0388      */
0389     QStringList activities() const;
0390     /**
0391      * Returns the position and size of the window contents.
0392      *
0393      * Requires NET::WMGeometry passed as properties parameter to the constructor.
0394      *
0395      * @code
0396      * QWidget *window = new QWidget(nullptr);
0397      * window->show();
0398      * KWindowInfo info(window->winId(), NET::WMGeometry);
0399      * if (info.valid())
0400      *     info.geometry();
0401      * @endcode
0402      */
0403     QRect geometry() const;
0404     /**
0405      * Returns the frame geometry of the window, i.e. including the window decoration.
0406      *
0407      * Requires NET::WMFrameExtents passed as properties parameter to the constructor.
0408      *
0409      * @code
0410      * QWidget *window = new QWidget(nullptr);
0411      * window->show();
0412      * KWindowInfo info(window->winId(), NET::WMFrameExtents);
0413      * if (info.valid())
0414      *     info.frameGeometry();
0415      * @endcode
0416      */
0417     QRect frameGeometry() const;
0418     /**
0419      * Returns the window identifier of the main window this window belongs to.
0420      *
0421      * This is the value of the WM_TRANSIENT_FOR X11 property.
0422      *
0423      * Requires NET::WM2TransientFor passed as properties2 parameter to the constructor.
0424      *
0425      * @code
0426      * QWidget *window = new QWidget(nullptr);
0427      * window->show();
0428      * KWindowInfo info(window->winId(), 0, NET::WM2TransientFor);
0429      * if (info.valid())
0430      *     info.transientFor();
0431      * @endcode
0432      */
0433     WId transientFor() const;
0434     /**
0435      * Returns the leader window for the group the window is in, if any.
0436      *
0437      * Requires NET::WM2GroupLeader passed as properties2 parameter to the constructor.
0438      *
0439      * @code
0440      * QWidget *window = new QWidget(nullptr);
0441      * window->show();
0442      * KWindowInfo info(window->winId(), 0, NET::WM2GroupLeader);
0443      * if (info.valid())
0444      *     info.groupLeader();
0445      * @endcode
0446      */
0447     WId groupLeader() const;
0448 
0449     /**
0450      * Returns the class component of the WM_CLASS X11 property for the window.
0451      *
0452      * Requires NET::WM2WindowClass passed as properties2 parameter to the constructor.
0453      *
0454      * @code
0455      * QWidget *window = new QWidget(nullptr);
0456      * window->show();
0457      * KWindowInfo info(window->winId(), 0, NET::WM2WindowClass);
0458      * if (info.valid())
0459      *     info.windowClassClass();
0460      * @endcode
0461      */
0462     QByteArray windowClassClass() const;
0463 
0464     /**
0465      * Returns the name component of the WM_CLASS X11 property for the window.
0466      *
0467      * Requires NET::WM2WindowClass passed as properties2 parameter to the constructor.
0468      *
0469      * @code
0470      * QWidget *window = new QWidget(nullptr);
0471      * window->show();
0472      * KWindowInfo info(window->winId(), 0, NET::WM2WindowClass);
0473      * if (info.valid())
0474      *     info.windowClassName();
0475      * @endcode
0476      */
0477     QByteArray windowClassName() const;
0478 
0479     /**
0480      * Returns the WM_WINDOW_ROLE X11 property for the window.
0481      *
0482      * Requires NET::WM2WindowRole passed as properties2 parameter to the constructor.
0483      *
0484      * @code
0485      * QWidget *window = new QWidget(nullptr);
0486      * window->show();
0487      * KWindowInfo info(window->winId(), 0, NET::WM2WindowRole);
0488      * if (info.valid())
0489      *     info.windowRole();
0490      * @endcode
0491      */
0492     QByteArray windowRole() const;
0493 
0494     /**
0495      * Returns the WM_CLIENT_MACHINE property for the window.
0496      *
0497      * Requires NET::WM2ClientMachine passed as properties2 parameter to the constructor.
0498      *
0499      * @code
0500      * QWidget *window = new QWidget(nullptr);
0501      * window->show();
0502      * KWindowInfo info(window->winId(), 0, NET::WM2ClientMachine);
0503      * if (info.valid())
0504      *     info.clientMachine();
0505      * @endcode
0506      */
0507     QByteArray clientMachine() const;
0508 
0509     /**
0510      * Returns true if the given action is currently supported for the window.
0511      *
0512      * The supported actions are set by the window manager and
0513      * can differ depending on the window manager.
0514      * Requires NET::WM2AllowedActions passed as properties2 parameter to the constructor.
0515      *
0516      * @code
0517      * QWidget *window = new QWidget(nullptr);
0518      * window->show();
0519      * KWindowInfo info(window->winId(), 0, NET::WM2AllowedActions);
0520      * if (info.valid())
0521      *     info.actionSupported(NET::ActionClose);
0522      * @endcode
0523      */
0524     bool actionSupported(NET::Action action) const;
0525 
0526     /**
0527      * Returns the desktop file name of the window's application if present.
0528      *
0529      * This is either the base name without full path and without file extension of the
0530      * desktop file for the window's application (e.g. "org.kde.foo").
0531      *
0532      * If the application's desktop file name is not at a standard location it should be
0533      * the full path to the desktop file name (e.g. "/opt/kde/share/org.kde.foo.desktop").
0534      *
0535      * Requires NET::WM2DesktopFileName passed as properties2 parameter to the constructor.
0536      *
0537      * @code
0538      * QWidget *window = new QWidget(nullptr);
0539      * window->show();
0540      * KWindowInfo info(window->winId(), 0, NET::WM2DesktopFileName);
0541      * if (info.valid())
0542      *     info.desktopFileName();
0543      * @endcode
0544      *
0545      * @since 5.29
0546      **/
0547     QByteArray desktopFileName() const;
0548 
0549     /**
0550      * Returns the GTK application id of the window if present.
0551      *
0552      * This is comparable to desktopFileName.
0553      *
0554      * Requires NET::WM2GTKApplicationId passed as properties2 parameter to the constructor.
0555      *
0556      * @code
0557      * QWidget *window = new QWidget(nullptr);
0558      * window->show();
0559      * KWindowInfo info(window->winId(), 0, NET::WM2GTKApplicationId);
0560      * if (info.valid())
0561      *     info.gtkApplicationId();
0562      * @endcode
0563      *
0564      * @since 5.91
0565      **/
0566     QByteArray gtkApplicationId() const;
0567 
0568     /**
0569      * Returns the process ID of the window's application if present.
0570      *
0571      * Requires NET::WMPid passed as properties parameter to the constructor.
0572      *
0573      * @code
0574      * QWidget *window = new QWidget(nullptr);
0575      * window->show();
0576      * KWindowInfo info(window->winId(), NET::WMPid);
0577      * if (info.valid())
0578      *     info.pid();
0579      * @endcode
0580      *
0581      * @since 5.29
0582      */
0583     int pid() const;
0584 
0585     /**
0586      * Returns service name of a window's application menu if present.
0587      *
0588      * Requires NET::WMPid passed as properties parameter to the constructor.
0589      *
0590      * @since 5.69
0591      */
0592     QByteArray applicationMenuServiceName() const;
0593 
0594     /**
0595      * Returns object path of a window's application menu if present.
0596      *
0597      * Requires NET::WMPid passed as properties parameter to the constructor.
0598      *
0599      * @since 5.69
0600      */
0601     QByteArray applicationMenuObjectPath() const;
0602 
0603     /**
0604      * Copy constructor.
0605      */
0606     KWindowInfo(const KWindowInfo &);
0607     /**
0608      * Assignment operator.
0609      */
0610     KWindowInfo &operator=(const KWindowInfo &);
0611 
0612 private:
0613     bool KWINDOWSYSTEM_NO_EXPORT icccmCompliantMappingState() const;
0614     bool KWINDOWSYSTEM_NO_EXPORT allowedActionsSupported() const;
0615 
0616     QExplicitlySharedDataPointer<KWindowInfoPrivate> d;
0617 };
0618 
0619 #endif // multiple inclusion guard