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

source code of kwindowsystem/src/kwindowinfo.h