1 /*
2     This file is part of the KDE libraries
3     SPDX-FileCopyrightText: 1999 Matthias Ettrich <ettrich@kde.org>
4     SPDX-FileCopyrightText: 2007 Lubos Lunak <l.lunak@kde.org>
5 
6     SPDX-License-Identifier: LGPL-2.1-or-later
7 */
8 /*
9  * kwindowinfo.h. Part of the KDE project.
10  */
11 
12 #ifndef KWINDOWINFO_H
13 #define KWINDOWINFO_H
14 
15 #include <QExplicitlySharedDataPointer>
16 #include <QStringList>
17 #include <QWidgetList> //For WId
18 #include <kwindowsystem_export.h>
19 
20 #include <netwm_def.h>
21 
22 class KWindowInfoPrivate;
23 
24 /**
25  * This class provides information about a given window in the platform specific
26  * windowing system. It provides the information for the current state when a
27  * KWindowInfo instance gets created. The instance does not get updated when the
28  * window changes. To get update about window changes connect to the
29  * @link KWindowSystem::windowChanged windowChanged@endlink signal of KWindowSystem
30  * and create a new KWindowInfo instance to reflect the current state.
31  *
32  * KWindowInfo does not encapsulate all information about the window. One needs to
33  * request which information is required by passing the appropriate NET::Property and
34  * NET::Property2 flags to the constructor. Please refer to the documentation of the
35  * methods to see which flags are required. This is done to limit the interaction with
36  * the underlying windowing system as fetching the information can cause several context
37  * switches and roundtrips to a server instance (e.g. when using the X11 platform).
38  *
39  * Please note that KWindowInfo is an abstraction of the underlying windowing system
40  * inspired by the X11 platform. Thus not all concepts apply to all platforms and some
41  * methods might return a default value for some platforms.
42  *
43  * Example usage of this class illustrated by monitoring a QWidget for change of the
44  * demands attention window state:
45  *
46  * @code
47  * QWidget *widget = new QWidget(nullptr);
48  * widget->show(); // ensures native window gets created
49  * connect(KWindowSystem::self(), static_cast<void (KWindowSystem::*)(WId, unsigned int)>(&KWindowSystem::windowChanged),
50  *        [window](WId winId, unsigned int properties) {
51  *     if (widget->winId() != winId) {
52  *         return; // not our window
53  *     }
54  *     if (properties & NET::WMState) {
55  *         // let's check whether our window is demanding attention
56  *         KWindowInfo info(widget->winId(), NET::WMState);
57  *         qDebug() << "Has demands attention: " << info.hasState(NET::DemandsAttention);
58  *     }
59  * });
60  * @endcode
61  */
62 class KWINDOWSYSTEM_EXPORT KWindowInfo
63 {
64 public:
65     /**
66      * Reads all the info about the given window.
67      *
68      * Only the information requested through the @p properties and @p properties2
69      * parameters are fetched. Refer to the methods you are interested in to see
70      * which flags to pass.
71      *
72      * @param window The platform specific window identifier
73      * @param properties Bitmask of NET::Property
74      * @param properties2 Bitmask of NET::Property2
75      */
76     KWindowInfo(WId window, NET::Properties properties, NET::Properties2 properties2 = NET::Properties2());
77     ~KWindowInfo();
78     /**
79      * Returns false if this window info is not valid.
80      *
81      * In case the window does not exist @c false is returned. Also if there is no
82      * appropriate implementation for KWindowInfo on the current windowing
83      * system platform this method returns @c false. In that case all methods return a
84      * default value and thus it is recommended to check whether valid returns @c true.
85      *
86      * @param withdrawn_is_valid if true, windows in the withdrawn state
87      *        (i.e. not managed) are also considered. This is usually not the case.
88      */
89     bool valid(bool withdrawn_is_valid = false) const;
90     /**
91      * Returns the window identifier.
92      */
93     WId win() const;
94     /**
95      * Returns the window's state flags.
96      *
97      * Requires NET::WMState passed as properties parameter to the constructor.
98      *
99      * @code
100      * QWidget *window = new QWidget(nullptr);
101      * window->show();
102      * KWindowInfo info(window->winId(), NET::WMState);
103      * if (info.valid())
104      *     info.state();
105      * @endcode
106      *
107      * @see NET::State
108      */
109     NET::States state() const;
110     /**
111      * Returns true if the window has the given state flag set.
112      *
113      * Requires NET::WMState passed as properties parameter to the constructor.
114      * @code
115      * QWidget *window = new QWidget(nullptr);
116      * window->show();
117      * KWindowInfo info(window->winId(), NET::WMState);
118      * if (info.valid())
119      *     info.hasState(NET::DemandsAttention);
120      * @endcode
121      *
122      * @see NET::State
123      */
124     bool hasState(NET::States s) const;
125     /**
126      * Returns true if the window is minimized.
127      *
128      * Note that it is true only if the window is truly minimized,
129      * not shaded or on another virtual desktops,
130      * which makes it different from mappingState() == NET::Iconic
131      * or QWidget::isMinimized().
132      * Requires NET::WMState and NET::XAWMState passed as properties parameter to the constructor.
133      *
134      * @code
135      * QWidget *window = new QWidget(nullptr);
136      * window->show();
137      * KWindowInfo info(window->winId(), NET::WMState | NET::XAWMState);
138      * if (info.valid())
139      *     info.isMinimized();
140      * @endcode
141      */
142     bool isMinimized() const;
143     /**
144      * Returns the mapping state of the window.
145      *
146      * Note that it's very likely that you don't want to use this function,
147      * and use isOnDesktop(), isMinimized() etc. instead.
148      * Requires NET::XAWMState passed as properties parameter to the constructor.
149      *
150      * @code
151      * QWidget *window = new QWidget(nullptr);
152      * window->show();
153      * KWindowInfo info(window->winId(), NET::XAWMState);
154      * if (info.valid())
155      *     info.mappingState();
156      * @endcode
157      *
158      * @see NET::MappingState
159      * @see isOnDesktop()
160      * @see isMinimzed()
161      */
162     NET::MappingState mappingState() const;
163     /**
164      * Returns the window extended (partial) strut.
165      *
166      * Requires NET::WM2ExtendedStrut passed as properties2 parameter to the constructor.
167      *
168      * @code
169      * QWidget *window = new QWidget(nullptr);
170      * window->show();
171      * KWindowInfo info(window->winId(), 0, NET::WM2ExtendedStrut);
172      * if (info.valid())
173      *     info.extendedStrut();
174      * @endcode
175      */
176     NETExtendedStrut extendedStrut() const;
177     /**
178      * Returns the window type of this window.
179      *
180      * The argument should be all window types your application supports.
181      * Requires NET::WMWindowType passed as properties parameter to the constructor.
182      *
183      * @code
184      * QWidget *window = new QWidget(nullptr);
185      * window->show();
186      * KWindowInfo info(window->winId(), NET::WMWindowType);
187      * if (info.valid())
188      *     info.windowType(NET::NormalMask | NET::DialogMask);
189      * @endcode
190      *
191      * @see NET::WindowType
192      * @see NET::WindowTypeMask
193      */
194     NET::WindowType windowType(NET::WindowTypes supported_types) const;
195     /**
196      * Returns the visible name of the window.
197      *
198      * The visible name differs from the name by including possible <2> appended
199      * when there are two or more windows with the same name.
200      * Requires NET::WMVisibleName passed as properties parameter to the constructor.
201      *
202      * @code
203      * QWidget *window = new QWidget(nullptr);
204      * window->show();
205      * KWindowInfo info(window->winId(), NET::WMVisibleName);
206      * if (info.valid())
207      *     info.visibleName();
208      * @endcode
209      *
210      * @see name()
211      */
212     QString visibleName() const;
213     /**
214      * Returns a visible name with state.
215      *
216      * This is a simple convenience function that returns the
217      * visible name but with parentheses around minimized windows.
218      * Requires NET::WMVisibleName, NET::WMState and NET::XAWMState passed
219      * as properties parameter to the constructor.
220      * @return the window name with state
221      *
222      * @code
223      * QWidget *window = new QWidget(nullptr);
224      * window->show();
225      * KWindowInfo info(window->winId(), NET::WMVisibleName | NET::WMState | NET::XAWMState);
226      * if (info.valid())
227      *     info.visibleNameWithState();
228      * @endcode
229      *
230      * @see visibleName()
231      */
232     QString visibleNameWithState() const;
233     /**
234      * Returns the name of the window, as specified by the application.
235      *
236      * The difference to visibleName() is that this is the name provided by
237      * the application without any modifications by the window manager.
238      * You should often use visibleName() instead.
239      * Requires NET::WMName passed as properties parameter to the constructor.
240      *
241      * @code
242      * QWidget *window = new QWidget(nullptr);
243      * window->show();
244      * KWindowInfo info(window->winId(), NET::WMName);
245      * if (info.valid())
246      *     info.name();
247      * @endcode
248      *
249      * @see visibleName()
250      */
251     QString name() const;
252     /**
253      * Returns the visible name of the window that should be shown in a taskbar.
254      *
255      * Note that this has nothing to do with normal icons but with an "iconic"
256      * representation of the window.
257      * Requires NET::WMVisibleIconName passed as properties parameter to the constructor.
258      *
259      * @code
260      * QWidget *window = new QWidget(nullptr);
261      * window->show();
262      * KWindowInfo info(window->winId(), NET::WMVisibleIconName);
263      * if (info.valid())
264      *     info.visibleIconName();
265      * @endcode
266      */
267     QString visibleIconName() const;
268     /**
269      * Returns a visible icon name with state.
270      *
271      * This is a simple convenience function that returns the
272      * visible iconic name but with parentheses around minimized windows.
273      * Note that this has nothing to do with normal icons.
274      * Requires NET::WMVisibleIconName, NET::WMState and NET::XAWMState passed
275      * as properties parameter to the constructor.
276      * @return the window iconic name with state
277      *
278      * @code
279      * QWidget *window = new QWidget(nullptr);
280      * window->show();
281      * KWindowInfo info(window->winId(), NET::WMVisibleIconName | NET::WMState | NET::XAWMState);
282      * if (info.valid())
283      *     info.visibleIconNameWithState();
284      * @endcode
285      *
286      * @see visibleIconName()
287      */
288     QString visibleIconNameWithState() const;
289     /**
290      * Returns the name of the window that should be shown in taskbar.
291      *
292      * Note that this has nothing to do with normal icons but with an "iconic"
293      * representation of the window.
294      * Requires NET::WMIconName passed as properties parameter to the constructor.
295      *
296      * @code
297      * QWidget *window = new QWidget(nullptr);
298      * window->show();
299      * KWindowInfo info(window->winId(), NET::WMIconName);
300      * if (info.valid())
301      *     info.iconName();
302      * @endcode
303      */
304     QString iconName() const;
305     /**
306      * Returns true if the window is on the currently active virtual desktop.
307      *
308      * Requires NET::WMDesktop passed as properties parameter to the constructor.
309      *
310      * @code
311      * QWidget *window = new QWidget(nullptr);
312      * window->show();
313      * KWindowInfo info(window->winId(), NET::WMDesktop);
314      * if (info.valid())
315      *     info.isOnCurrentDesktop();
316      * @endcode
317      */
318     bool isOnCurrentDesktop() const;
319     /**
320      * Returns true if the window is on the given virtual desktop.
321      *
322      * Requires NET::WMDesktop passed as properties parameter to the constructor.
323      *
324      * @code
325      * QWidget *window = new QWidget(nullptr);
326      * window->show();
327      * KWindowInfo info(window->winId(), NET::WMDesktop);
328      * if (info.valid())
329      *     info.isOnDesktop(KWindowSystem::currentDesktop());
330      * @endcode
331      */
332     bool isOnDesktop(int desktop) const;
333     /**
334      * Returns true if the window is on all desktops.
335      *
336      * A window is on all desktops if desktop() returns NET::OnAllDesktops.
337      * Requires NET::WMDesktop passed as properties parameter to the constructor.
338      *
339      * @code
340      * QWidget *window = new QWidget(nullptr);
341      * window->show();
342      * KWindowInfo info(window->winId(), NET::WMDesktop);
343      * if (info.valid())
344      *     info.onAllDesktops();
345      * @endcode
346      *
347      * @see desktop()
348      */
349     bool onAllDesktops() const;
350     /**
351      * Returns the virtual desktop this window is on.
352      *
353      * If the window is on all desktops NET::OnAllDesktops is returned.
354      * You should prefer using isOnDesktop().
355      * Requires NET::WMDesktop passed as properties parameter to the constructor.
356      *
357      * @code
358      * QWidget *window = new QWidget(nullptr);
359      * window->show();
360      * KWindowInfo info(window->winId(), NET::WMDesktop);
361      * if (info.valid())
362      *     info.desktop();
363      * @endcode
364      *
365      * @see isOnDesktop()
366      */
367     int desktop() const;
368     /**
369      * Returns the list of activity UUIDs this window belongs to.
370      *
371      * The Plasma workspace allows the user to separate her work into
372      * different activities, by assigning windows, documents etc. to
373      * the specific ones. An activity is an abstract concept whose meaning
374      * can differ from one user to another. Typical examples of activities
375      * are "developing a KDE project", "studying the 19th century art",
376      * "composing music", "lazing on a Sunday afternoon" etc.
377      *
378      * If the list is empty, or contains a null UUID, the window is on
379      * all activities.
380      *
381      * Requires NET::WM2Activities passed as properties parameter to the constructor.
382      *
383      * @code
384      * QWidget *window = new QWidget(nullptr);
385      * window->show();
386      * KWindowInfo info(window->winId(), 0, NET::WM2Activities);
387      * if (info.valid())
388      *     info.desktop();
389      * @endcode
390      *
391      * @note Activities are only supported on Plasma Workspace on X11
392      *
393      * @since 5.0
394      */
395     QStringList activities() const;
396     /**
397      * Returns the position and size of the window contents.
398      *
399      * Requires NET::WMGeometry passed as properties parameter to the constructor.
400      *
401      * @code
402      * QWidget *window = new QWidget(nullptr);
403      * window->show();
404      * KWindowInfo info(window->winId(), NET::WMGeometry);
405      * if (info.valid())
406      *     info.geometry();
407      * @endcode
408      */
409     QRect geometry() const;
410     /**
411      * Returns the frame geometry of the window, i.e. including the window decoration.
412      *
413      * Requires NET::WMFrameExtents passed as properties parameter to the constructor.
414      *
415      * @code
416      * QWidget *window = new QWidget(nullptr);
417      * window->show();
418      * KWindowInfo info(window->winId(), NET::WMFrameExtents);
419      * if (info.valid())
420      *     info.frameGeometry();
421      * @endcode
422      */
423     QRect frameGeometry() const;
424     /**
425      * Returns the window identifier of the main window this window belongs to.
426      *
427      * On platform X11 this is the value of the WM_TRANSIENT_FOR property.
428      *
429      * Requires NET::WM2TransientFor passed as properties2 parameter to the constructor.
430      *
431      * @code
432      * QWidget *window = new QWidget(nullptr);
433      * window->show();
434      * KWindowInfo info(window->winId(), 0, NET::WM2TransientFor);
435      * if (info.valid())
436      *     info.transientFor();
437      * @endcode
438      */
439     WId transientFor() const;
440     /**
441      * Returns the leader window for the group the window is in, if any.
442      *
443      * Requires NET::WM2GroupLeader passed as properties2 parameter to the constructor.
444      *
445      * @code
446      * QWidget *window = new QWidget(nullptr);
447      * window->show();
448      * KWindowInfo info(window->winId(), 0, NET::WM2GroupLeader);
449      * if (info.valid())
450      *     info.groupLeader();
451      * @endcode
452      */
453     WId groupLeader() const;
454 
455     /**
456      * Returns the class component of the window class for the window.
457      *
458      * On platform X11 this is part of the WM_CLASS property.
459      * Requires NET::WM2WindowClass passed as properties2 parameter to the constructor.
460      *
461      * @code
462      * QWidget *window = new QWidget(nullptr);
463      * window->show();
464      * KWindowInfo info(window->winId(), 0, NET::WM2WindowClass);
465      * if (info.valid())
466      *     info.windowClassClass();
467      * @endcode
468      */
469     QByteArray windowClassClass() const;
470 
471     /**
472      * Returns the name component of the window class for the window.
473      *
474      * On platform X11 this is part of the WM_CLASS property.
475      * Requires NET::WM2WindowClass passed as properties2 parameter to the constructor.
476      *
477      * @code
478      * QWidget *window = new QWidget(nullptr);
479      * window->show();
480      * KWindowInfo info(window->winId(), 0, NET::WM2WindowClass);
481      * if (info.valid())
482      *     info.windowClassName();
483      * @endcode
484      */
485     QByteArray windowClassName() const;
486 
487     /**
488      * Returns the window role for the window.
489      *
490      * On platform X11 this is the value of the WM_WINDOW_ROLE property.
491      * Requires NET::WM2WindowRole passed as properties2 parameter to the constructor.
492      *
493      * @code
494      * QWidget *window = new QWidget(nullptr);
495      * window->show();
496      * KWindowInfo info(window->winId(), 0, NET::WM2WindowRole);
497      * if (info.valid())
498      *     info.windowRole();
499      * @endcode
500      */
501     QByteArray windowRole() const;
502 
503     /**
504      * Returns the client machine for the window.
505      *
506      * On platform X11 this is the value of the WM_CLIENT_MACHINE property.
507      * Requires NET::WM2ClientMachine passed as properties2 parameter to the constructor.
508      *
509      * @code
510      * QWidget *window = new QWidget(nullptr);
511      * window->show();
512      * KWindowInfo info(window->winId(), 0, NET::WM2ClientMachine);
513      * if (info.valid())
514      *     info.clientMachine();
515      * @endcode
516      */
517     QByteArray clientMachine() const;
518 
519     /**
520      * Returns true if the given action is currently supported for the window.
521      *
522      * On platform X11 the supported actions are set by the window manager and
523      * can differ depending on the window manager.
524      * Requires NET::WM2AllowedActions passed as properties2 parameter to the constructor.
525      *
526      * @code
527      * QWidget *window = new QWidget(nullptr);
528      * window->show();
529      * KWindowInfo info(window->winId(), 0, NET::WM2AllowedActions);
530      * if (info.valid())
531      *     info.actionSupported(NET::ActionClose);
532      * @endcode
533      */
534     bool actionSupported(NET::Action action) const;
535 
536     /**
537      * Returns the desktop file name of the window's application if present.
538      *
539      * This is either the base name without full path and without file extension of the
540      * desktop file for the window's application (e.g. "org.kde.foo").
541      *
542      * If the application's desktop file name is not at a standard location it should be
543      * the full path to the desktop file name (e.g. "/opt/kde/share/org.kde.foo.desktop").
544      *
545      * Requires NET::WM2DesktopFileName passed as properties2 parameter to the constructor.
546      *
547      * @code
548      * QWidget *window = new QWidget(nullptr);
549      * window->show();
550      * KWindowInfo info(window->winId(), 0, NET::WM2DesktopFileName);
551      * if (info.valid())
552      *     info.desktopFileName();
553      * @endcode
554      *
555      * @since 5.29
556      **/
557     QByteArray desktopFileName() const;
558 
559     /**
560      * Returns the process ID of the window's application if present.
561      *
562      * Requires NET::WMPid passed as properties parameter to the constructor.
563      *
564      * @code
565      * QWidget *window = new QWidget(nullptr);
566      * window->show();
567      * KWindowInfo info(window->winId(), NET::WMPid);
568      * if (info.valid())
569      *     info.pid();
570      * @endcode
571      *
572      * @since 5.29
573      */
574     int pid() const;
575 
576     /**
577      * Returns service name of a window's application menu if present.
578      *
579      * Requires NET::WMPid passed as properties parameter to the constructor.
580      *
581      * @since 5.69
582      */
583     QByteArray applicationMenuServiceName() const;
584 
585     /**
586      * Returns object path of a window's application menu if present.
587      *
588      * Requires NET::WMPid passed as properties parameter to the constructor.
589      *
590      * @since 5.69
591      */
592     QByteArray applicationMenuObjectPath() const;
593 
594     /**
595      * Copy constructor.
596      */
597     KWindowInfo(const KWindowInfo &);
598     /**
599      * Assignment operator.
600      */
601     KWindowInfo &operator=(const KWindowInfo &);
602 
603 private:
604     QExplicitlySharedDataPointer<KWindowInfoPrivate> d;
605 };
606 
607 #endif // multiple inclusion guard
608