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 * This class provides information about a given X11 window. It provides the information
26 * for the current state when a KWindowInfo instance gets created.
27 * The instance does not get updated when the
28 * window changes. To get update about window changes connect to the
29 * @link KX11Extras::windowChanged windowChanged@endlink signal of KX11Extras
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 xserver and avoid excess roundtrips.
37 *
38 * KWindowInfo does nothing when running outside of X11.
39 *
40 * Example usage of this class illustrated by monitoring a QWidget for change of the
41 * demands attention window state:
42 *
43 * @code
44 * QWidget *widget = new QWidget(nullptr);
45 * widget->show(); // ensures native window gets created
46 * connect(KX11Extras::self(), &KX11Extras::KWindowSystem::windowChanged,
47 * [window](WId id, NET::Properties properties, NET::Properties2 properties2) {
48 * if (widget->winId() != winId) {
49 * return; // not our window
50 * }
51 * if (properties & NET::WMState) {
52 * // let's check whether our window is demanding attention
53 * KWindowInfo info(widget->winId(), NET::WMState);
54 * qDebug() << "Has demands attention: " << info.hasState(NET::DemandsAttention);
55 * }
56 * });
57 * @endcode
58 */
59class KWINDOWSYSTEM_EXPORT KWindowInfo
60{
61public:
62 /**
63 * Reads all the info about the given window.
64 *
65 * Only the information requested through the @p properties and @p properties2
66 * parameters are fetched. Refer to the methods you are interested in to see
67 * which flags to pass.
68 *
69 * @param window The platform specific window identifier
70 * @param properties Bitmask of NET::Property
71 * @param properties2 Bitmask of NET::Property2
72 */
73 KWindowInfo(WId window, NET::Properties properties, NET::Properties2 properties2 = NET::Properties2());
74 ~KWindowInfo();
75 /**
76 * Returns false if this window info is not valid.
77 *
78 * In case the window does not exist @c false is returned.
79 *
80 * @param withdrawn_is_valid if true, windows in the withdrawn state
81 * (i.e. not managed) are also considered. This is usually not the case.
82 */
83 bool valid(bool withdrawn_is_valid = false) const;
84 /**
85 * Returns the window identifier.
86 */
87 WId win() const;
88 /**
89 * Returns the window's state flags.
90 *
91 * Requires NET::WMState passed as properties parameter to the constructor.
92 *
93 * @code
94 * QWidget *window = new QWidget(nullptr);
95 * window->show();
96 * KWindowInfo info(window->winId(), NET::WMState);
97 * if (info.valid())
98 * info.state();
99 * @endcode
100 *
101 * @see NET::State
102 */
103 NET::States state() const;
104 /**
105 * Returns true if the window has the given state flag set.
106 *
107 * Requires NET::WMState passed as properties parameter to the constructor.
108 * @code
109 * QWidget *window = new QWidget(nullptr);
110 * window->show();
111 * KWindowInfo info(window->winId(), NET::WMState);
112 * if (info.valid())
113 * info.hasState(NET::DemandsAttention);
114 * @endcode
115 *
116 * @see NET::State
117 */
118 bool hasState(NET::States s) const;
119 /**
120 * Returns true if the window is minimized.
121 *
122 * Note that it is true only if the window is truly minimized,
123 * not shaded or on another virtual desktops,
124 * which makes it different from mappingState() == NET::Iconic
125 * or QWidget::isMinimized().
126 * Requires NET::WMState and NET::XAWMState passed as properties parameter to the constructor.
127 *
128 * @code
129 * QWidget *window = new QWidget(nullptr);
130 * window->show();
131 * KWindowInfo info(window->winId(), NET::WMState | NET::XAWMState);
132 * if (info.valid())
133 * info.isMinimized();
134 * @endcode
135 */
136 bool isMinimized() const;
137 /**
138 * Returns the mapping state of the window.
139 *
140 * Note that it's very likely that you don't want to use this function,
141 * and use isOnDesktop(), isMinimized() etc. instead.
142 * Requires NET::XAWMState passed as properties parameter to the constructor.
143 *
144 * @code
145 * QWidget *window = new QWidget(nullptr);
146 * window->show();
147 * KWindowInfo info(window->winId(), NET::XAWMState);
148 * if (info.valid())
149 * info.mappingState();
150 * @endcode
151 *
152 * @see NET::MappingState
153 * @see isOnDesktop()
154 * @see isMinimzed()
155 */
156 NET::MappingState mappingState() const;
157 /**
158 * Returns the window extended (partial) strut.
159 *
160 * Requires NET::WM2ExtendedStrut passed as properties2 parameter to the constructor.
161 *
162 * @code
163 * QWidget *window = new QWidget(nullptr);
164 * window->show();
165 * KWindowInfo info(window->winId(), 0, NET::WM2ExtendedStrut);
166 * if (info.valid())
167 * info.extendedStrut();
168 * @endcode
169 */
170 NETExtendedStrut extendedStrut() const;
171 /**
172 * Returns the window type of this window.
173 *
174 * The argument should be all window types your application supports.
175 * Requires NET::WMWindowType passed as properties parameter to the constructor.
176 *
177 * @code
178 * QWidget *window = new QWidget(nullptr);
179 * window->show();
180 * KWindowInfo info(window->winId(), NET::WMWindowType);
181 * if (info.valid())
182 * info.windowType(NET::NormalMask | NET::DialogMask);
183 * @endcode
184 *
185 * @see NET::WindowType
186 * @see NET::WindowTypeMask
187 */
188 NET::WindowType windowType(NET::WindowTypes supported_types) const;
189 /**
190 * Returns the visible name of the window.
191 *
192 * The visible name differs from the name by including possible <2> appended
193 * when there are two or more windows with the same name.
194 * Requires NET::WMVisibleName passed as properties parameter to the constructor.
195 *
196 * @code
197 * QWidget *window = new QWidget(nullptr);
198 * window->show();
199 * KWindowInfo info(window->winId(), NET::WMVisibleName);
200 * if (info.valid())
201 * info.visibleName();
202 * @endcode
203 *
204 * @see name()
205 */
206 QString visibleName() const;
207 /**
208 * Returns a visible name with state.
209 *
210 * This is a simple convenience function that returns the
211 * visible name but with parentheses around minimized windows.
212 * Requires NET::WMVisibleName, NET::WMState and NET::XAWMState passed
213 * as properties parameter to the constructor.
214 * @return the window name with state
215 *
216 * @code
217 * QWidget *window = new QWidget(nullptr);
218 * window->show();
219 * KWindowInfo info(window->winId(), NET::WMVisibleName | NET::WMState | NET::XAWMState);
220 * if (info.valid())
221 * info.visibleNameWithState();
222 * @endcode
223 *
224 * @see visibleName()
225 */
226 QString visibleNameWithState() const;
227 /**
228 * Returns the name of the window, as specified by the application.
229 *
230 * The difference to visibleName() is that this is the name provided by
231 * the application without any modifications by the window manager.
232 * You should often use visibleName() instead.
233 * Requires NET::WMName passed as properties parameter to the constructor.
234 *
235 * @code
236 * QWidget *window = new QWidget(nullptr);
237 * window->show();
238 * KWindowInfo info(window->winId(), NET::WMName);
239 * if (info.valid())
240 * info.name();
241 * @endcode
242 *
243 * @see visibleName()
244 */
245 QString name() const;
246 /**
247 * Returns the visible name of the window that should be shown in a taskbar.
248 *
249 * Note that this has nothing to do with normal icons but with an "iconic"
250 * representation of the window.
251 * Requires NET::WMVisibleIconName passed as properties parameter to the constructor.
252 *
253 * @code
254 * QWidget *window = new QWidget(nullptr);
255 * window->show();
256 * KWindowInfo info(window->winId(), NET::WMVisibleIconName);
257 * if (info.valid())
258 * info.visibleIconName();
259 * @endcode
260 */
261 QString visibleIconName() const;
262 /**
263 * Returns a visible icon name with state.
264 *
265 * This is a simple convenience function that returns the
266 * visible iconic name but with parentheses around minimized windows.
267 * Note that this has nothing to do with normal icons.
268 * Requires NET::WMVisibleIconName, NET::WMState and NET::XAWMState passed
269 * as properties parameter to the constructor.
270 * @return the window iconic name with state
271 *
272 * @code
273 * QWidget *window = new QWidget(nullptr);
274 * window->show();
275 * KWindowInfo info(window->winId(), NET::WMVisibleIconName | NET::WMState | NET::XAWMState);
276 * if (info.valid())
277 * info.visibleIconNameWithState();
278 * @endcode
279 *
280 * @see visibleIconName()
281 */
282 QString visibleIconNameWithState() const;
283 /**
284 * Returns the name of the window that should be shown in taskbar.
285 *
286 * Note that this has nothing to do with normal icons but with an "iconic"
287 * representation of the window.
288 * Requires NET::WMIconName passed as properties parameter to the constructor.
289 *
290 * @code
291 * QWidget *window = new QWidget(nullptr);
292 * window->show();
293 * KWindowInfo info(window->winId(), NET::WMIconName);
294 * if (info.valid())
295 * info.iconName();
296 * @endcode
297 */
298 QString iconName() const;
299 /**
300 * Returns true if the window is on the currently active virtual desktop.
301 *
302 * Requires NET::WMDesktop passed as properties parameter to the constructor.
303 *
304 * @code
305 * QWidget *window = new QWidget(nullptr);
306 * window->show();
307 * KWindowInfo info(window->winId(), NET::WMDesktop);
308 * if (info.valid())
309 * info.isOnCurrentDesktop();
310 * @endcode
311 */
312 bool isOnCurrentDesktop() const;
313 /**
314 * Returns true if the window is on the given virtual desktop.
315 *
316 * Requires NET::WMDesktop passed as properties parameter to the constructor.
317 *
318 * @code
319 * QWidget *window = new QWidget(nullptr);
320 * window->show();
321 * KWindowInfo info(window->winId(), NET::WMDesktop);
322 * if (info.valid())
323 * info.isOnDesktop(KWindowSystem::currentDesktop());
324 * @endcode
325 */
326 bool isOnDesktop(int desktop) const;
327 /**
328 * Returns true if the window is on all desktops.
329 *
330 * A window is on all desktops if desktop() returns NET::OnAllDesktops.
331 * Requires NET::WMDesktop passed as properties parameter to the constructor.
332 *
333 * @code
334 * QWidget *window = new QWidget(nullptr);
335 * window->show();
336 * KWindowInfo info(window->winId(), NET::WMDesktop);
337 * if (info.valid())
338 * info.onAllDesktops();
339 * @endcode
340 *
341 * @see desktop()
342 */
343 bool onAllDesktops() const;
344 /**
345 * Returns the virtual desktop this window is on.
346 *
347 * If the window is on all desktops NET::OnAllDesktops is returned.
348 * You should prefer using isOnDesktop().
349 * Requires NET::WMDesktop passed as properties parameter to the constructor.
350 *
351 * @code
352 * QWidget *window = new QWidget(nullptr);
353 * window->show();
354 * KWindowInfo info(window->winId(), NET::WMDesktop);
355 * if (info.valid())
356 * info.desktop();
357 * @endcode
358 *
359 * @see isOnDesktop()
360 */
361 int desktop() const;
362 /**
363 * Returns the list of activity UUIDs this window belongs to.
364 *
365 * The Plasma workspace allows the user to separate her work into
366 * different activities, by assigning windows, documents etc. to
367 * the specific ones. An activity is an abstract concept whose meaning
368 * can differ from one user to another. Typical examples of activities
369 * are "developing a KDE project", "studying the 19th century art",
370 * "composing music", "lazing on a Sunday afternoon" etc.
371 *
372 * If the list is empty, or contains a null UUID, the window is on
373 * all activities.
374 *
375 * Requires NET::WM2Activities passed as properties parameter to the constructor.
376 *
377 * @code
378 * QWidget *window = new QWidget(nullptr);
379 * window->show();
380 * KWindowInfo info(window->winId(), 0, NET::WM2Activities);
381 * if (info.valid())
382 * info.desktop();
383 * @endcode
384 *
385 * @note Activities are only supported on Plasma Workspace on X11
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 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 /**
604 * Copy constructor.
605 */
606 KWindowInfo(const KWindowInfo &);
607 /**
608 * Assignment operator.
609 */
610 KWindowInfo &operator=(const KWindowInfo &);
611
612private:
613 bool KWINDOWSYSTEM_NO_EXPORT icccmCompliantMappingState() const;
614 bool KWINDOWSYSTEM_NO_EXPORT allowedActionsSupported() const;
615
616 QExplicitlySharedDataPointer<KWindowInfoPrivate> d;
617};
618
619#endif // multiple inclusion guard
620

source code of kwindowsystem/src/kwindowinfo.h