7#include "kwindowinfo.h"
8#include "kwindowsystem.h"
9#include "kwindowsystem_debug.h"
10#include "kx11extras.h"
13#include <config-kwindowsystem.h>
15#include "private/qtx11extras_p.h"
19#include "kxerrorhandler_p.h"
28 static bool s_checked =
false;
29 static bool s_haveXRes =
false;
31 auto cookie = xcb_res_query_version(QX11Info::connection(), XCB_RES_MAJOR_VERSION, XCB_RES_MINOR_VERSION);
32 UniqueCPointer<xcb_res_query_version_reply_t> reply(xcb_res_query_version_reply(QX11Info::connection(), cookie,
nullptr));
33 s_haveXRes = reply !=
nullptr;
39class Q_DECL_HIDDEN KWindowInfoPrivate :
public QSharedData
46 std::unique_ptr<NETWinInfo> m_info;
50 QRect m_frame_geometry;
56 : d(new KWindowInfoPrivate)
59 d->properties = properties;
60 d->properties2 = properties2;
62 if (!KWindowSystem::isPlatformX11()) {
66 KXErrorHandler handler;
67 if (properties & NET::WMVisibleIconName) {
68 properties |= NET::WMIconName | NET::WMVisibleName;
70 if (properties & NET::WMVisibleName) {
71 properties |= NET::WMName;
73 if (properties2 & NET::WM2ExtendedStrut) {
74 properties |= NET::WMStrut;
76 if (properties & NET::WMWindowType) {
77 properties2 |= NET::WM2TransientFor;
80 properties |= NET::WMGeometry;
82 properties |= NET::XAWMState;
83 d->m_info.reset(
new NETWinInfo(QX11Info::connection(), d->window, QX11Info::appRootWindow(), properties, properties2));
84 if (properties & NET::WMName) {
85 if (d->m_info->name() && d->m_info->name()[0] !=
'\0') {
91 if (properties & NET::WMIconName) {
92 if (d->m_info->iconName() && d->m_info->iconName()[0] !=
'\0') {
98 if (properties & (NET::WMGeometry | NET::WMFrameExtents)) {
101 d->m_info->kdeGeometry(frame, geom);
105 d->m_valid = !handler.error(
false);
108 xcb_res_client_id_spec_t specs;
109 specs.client =
win();
110 specs.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID;
111 auto cookie = xcb_res_query_client_ids(QX11Info::connection(), 1, &specs);
113 UniqueCPointer<xcb_res_query_client_ids_reply_t> reply(xcb_res_query_client_ids_reply(QX11Info::connection(), cookie,
nullptr));
114 if (reply && xcb_res_query_client_ids_ids_length(reply.get()) > 0) {
115 uint32_t
pid = *xcb_res_client_id_value_value((xcb_res_query_client_ids_ids_iterator(reply.get()).data));
126KWindowInfo::~KWindowInfo()
140 if (!KWindowSystem::isPlatformX11()) {
159 if (!KWindowSystem::isPlatformX11()) { \
160 qCWarning(LOG_KWINDOWSYSTEM) << "KWindowInfo is only functional when running on X11"; \
167#if !defined(KDE_NO_WARNING_OUTPUT)
168 if (!(d->m_info->passedProperties() & NET::WMState)) {
169 qWarning() <<
"Pass NET::WMState to KWindowInfo";
172 return d->m_info->state();
178 return (
state() & s) == s;
181bool KWindowInfo::icccmCompliantMappingState()
const
184 static enum { noidea, yes, no } wm_is_1_2_compliant = noidea;
185 if (wm_is_1_2_compliant == noidea) {
187 wm_is_1_2_compliant = info.isSupported(
NET::Hidden) ? yes : no;
189 return wm_is_1_2_compliant == yes;
205 return icccmCompliantMappingState() ? false :
true;
211#if !defined(KDE_NO_WARNING_OUTPUT)
212 if (!(d->m_info->passedProperties() & NET::XAWMState)) {
213 qWarning() <<
"Pass NET::XAWMState to KWindowInfo";
216 return d->m_info->mappingState();
222#if !defined(KDE_NO_WARNING_OUTPUT)
223 if (!(d->m_info->passedProperties2() & NET::WM2ExtendedStrut)) {
224 qWarning() <<
"Pass NET::WM2ExtendedStrut to KWindowInfo";
235 ext.left_end = XDisplayHeight(QX11Info::display(), DefaultScreen(QX11Info::display()));
237 if (str.
right != 0) {
240 ext.right_end = XDisplayHeight(QX11Info::display(), DefaultScreen(QX11Info::display()));
245 ext.top_end = XDisplayWidth(QX11Info::display(), DefaultScreen(QX11Info::display()));
249 ext.bottom_start = 0;
250 ext.bottom_end = XDisplayWidth(QX11Info::display(), DefaultScreen(QX11Info::display()));
259#if !defined(KDE_NO_WARNING_OUTPUT)
260 if (!(d->m_info->passedProperties() & NET::WMWindowType)) {
261 qWarning() <<
"Pass NET::WMWindowType to KWindowInfo";
264 if (!d->m_info->hasWindowType()) {
275 return d->m_info->windowType(supported_types);
281#if !defined(KDE_NO_WARNING_OUTPUT)
282 if (!(d->m_info->passedProperties() & NET::WMVisibleName)) {
283 qWarning() <<
"Pass NET::WMVisibleName to KWindowInfo";
286 return d->m_info->visibleName() && d->m_info->visibleName()[0] !=
'\0' ?
QString::fromUtf8(d->m_info->visibleName()) :
name();
303#if !defined(KDE_NO_WARNING_OUTPUT)
304 if (!(d->m_info->passedProperties() & NET::WMName)) {
305 qWarning() <<
"Pass NET::WMName to KWindowInfo";
314#if !defined(KDE_NO_WARNING_OUTPUT)
315 if (!(d->m_info->passedProperties() & NET::WMVisibleIconName)) {
316 qWarning() <<
"Pass NET::WMVisibleIconName to KWindowInfo";
319 if (d->m_info->visibleIconName() && d->m_info->visibleIconName()[0] !=
'\0') {
322 if (d->m_info->iconName() && d->m_info->iconName()[0] !=
'\0') {
325 if (!d->m_iconic_name.isEmpty()) {
326 return d->m_iconic_name;
345#if !defined(KDE_NO_WARNING_OUTPUT)
346 if (!(d->m_info->passedProperties() & NET::WMIconName)) {
347 qWarning() <<
"Pass NET::WMIconName to KWindowInfo";
350 if (d->m_info->iconName() && d->m_info->iconName()[0] !=
'\0') {
353 if (!d->m_iconic_name.isEmpty()) {
354 return d->m_iconic_name;
368#if !defined(KDE_NO_WARNING_OUTPUT)
369 if (!(d->m_info->passedProperties() & NET::WMDesktop)) {
370 qWarning() <<
"Pass NET::WMDesktop to KWindowInfo";
377 return KX11Extras::viewportWindowToDesktop(d->m_geometry) ==
desktop;
379 return d->m_info->desktop() ==
desktop || d->m_info->desktop() == NET::OnAllDesktops;
385#if !defined(KDE_NO_WARNING_OUTPUT)
386 if (!(d->m_info->passedProperties() & NET::WMDesktop)) {
387 qWarning() <<
"Pass NET::WMDesktop to KWindowInfo";
391 if (d->m_info->passedProperties() & NET::WMState) {
397 return d->m_info->desktop() == NET::OnAllDesktops;
403#if !defined(KDE_NO_WARNING_OUTPUT)
404 if (!(d->m_info->passedProperties() & NET::WMDesktop)) {
405 qWarning() <<
"Pass NET::WMDesktop to KWindowInfo";
410 return NET::OnAllDesktops;
412 return KX11Extras::viewportWindowToDesktop(d->m_geometry);
414 return d->m_info->desktop();
420#if !defined(KDE_NO_WARNING_OUTPUT)
421 if (!(d->m_info->passedProperties2() & NET::WM2Activities)) {
422 qWarning() <<
"Pass NET::WM2Activities to KWindowInfo";
434#if !defined(KDE_NO_WARNING_OUTPUT)
435 if (!(d->m_info->passedProperties() & NET::WMGeometry)) {
436 qWarning() <<
"Pass NET::WMGeometry to KWindowInfo";
439 return d->m_geometry;
445#if !defined(KDE_NO_WARNING_OUTPUT)
446 if (!(d->m_info->passedProperties() & NET::WMFrameExtents)) {
447 qWarning() <<
"Pass NET::WMFrameExtents to KWindowInfo";
450 return d->m_frame_geometry;
456#if !defined(KDE_NO_WARNING_OUTPUT)
457 if (!(d->m_info->passedProperties2() & NET::WM2TransientFor)) {
458 qWarning() <<
"Pass NET::WM2TransientFor to KWindowInfo";
461 return d->m_info->transientFor();
467#if !defined(KDE_NO_WARNING_OUTPUT)
468 if (!(d->m_info->passedProperties2() & NET::WM2GroupLeader)) {
469 qWarning() <<
"Pass NET::WM2GroupLeader to KWindowInfo";
472 return d->m_info->groupLeader();
478#if !defined(KDE_NO_WARNING_OUTPUT)
479 if (!(d->m_info->passedProperties2() & NET::WM2WindowClass)) {
480 qWarning() <<
"Pass NET::WM2WindowClass to KWindowInfo";
483 return d->m_info->windowClassClass();
489#if !defined(KDE_NO_WARNING_OUTPUT)
490 if (!(d->m_info->passedProperties2() & NET::WM2WindowClass)) {
491 qWarning() <<
"Pass NET::WM2WindowClass to KWindowInfo";
494 return d->m_info->windowClassName();
500#if !defined(KDE_NO_WARNING_OUTPUT)
501 if (!(d->m_info->passedProperties2() & NET::WM2WindowRole)) {
502 qWarning() <<
"Pass NET::WM2WindowRole to KWindowInfo";
505 return d->m_info->windowRole();
511#if !defined(KDE_NO_WARNING_OUTPUT)
512 if (!(d->m_info->passedProperties2() & NET::WM2ClientMachine)) {
513 qWarning() <<
"Pass NET::WM2ClientMachine to KWindowInfo";
516 return d->m_info->clientMachine();
519bool KWindowInfo::allowedActionsSupported()
const
522 static enum { noidea, yes, no } wm_supports_allowed_actions = noidea;
523 if (wm_supports_allowed_actions == noidea) {
525 wm_supports_allowed_actions = info.isSupported(NET::WM2AllowedActions) ? yes : no;
527 return wm_supports_allowed_actions == yes;
533#if !defined(KDE_NO_WARNING_OUTPUT)
534 if (!(d->m_info->passedProperties2() & NET::WM2AllowedActions)) {
535 qWarning() <<
"Pass NET::WM2AllowedActions to KWindowInfo";
538 if (allowedActionsSupported()) {
539 return d->m_info->allowedActions() & action;
548#if !defined(KDE_NO_WARNING_OUTPUT)
549 if (!(d->m_info->passedProperties2() & NET::WM2DesktopFileName)) {
550 qWarning() <<
"Pass NET::WM2DesktopFileName to KWindowInfo";
553 return QByteArray(d->m_info->desktopFileName());
559#if !defined(KDE_NO_WARNING_OUTPUT)
560 if (!(d->m_info->passedProperties2() & NET::WM2DesktopFileName)) {
561 qWarning() <<
"Pass NET::WM2DesktopFileName to KWindowInfo";
564 return QByteArray(d->m_info->gtkApplicationId());
570#if !defined(KDE_NO_WARNING_OUTPUT)
571 if (!(d->m_info->passedProperties2() & NET::WM2AppMenuServiceName)) {
572 qWarning() <<
"Pass NET::WM2AppMenuServiceName to KWindowInfo";
575 return QByteArray(d->m_info->appMenuServiceName());
581#if !defined(KDE_NO_WARNING_OUTPUT)
582 if (!(d->m_info->passedProperties2() & NET::WM2AppMenuObjectPath)) {
583 qWarning() <<
"Pass NET::WM2AppMenuObjectPath to KWindowInfo";
586 return QByteArray(d->m_info->appMenuObjectPath());
599#if !defined(KDE_NO_WARNING_OUTPUT)
600 if (!(d->m_info->passedProperties() & NET::WMPid)) {
601 qWarning() <<
"Pass NET::WMPid to KWindowInfo";
605 return d->m_info->pid();
This class provides information about a given X11 window.
QString iconName() const
Returns the name of the window that should be shown in taskbar.
NETExtendedStrut extendedStrut() const
Returns the window extended (partial) strut.
bool isMinimized() const
Returns true if the window is minimized.
int pid() const
Returns the process ID of the window's application if present.
QString visibleName() const
Returns the visible name of the window.
bool valid(bool withdrawn_is_valid=false) const
Returns false if this window info is not valid.
bool actionSupported(NET::Action action) const
Returns true if the given action is currently supported for the window.
QByteArray gtkApplicationId() const
Returns the GTK application id of the window if present.
QByteArray windowClassName() const
Returns the name component of the WM_CLASS X11 property for the window.
QByteArray windowRole() const
Returns the WM_WINDOW_ROLE X11 property for the window.
QString visibleIconNameWithState() const
Returns a visible icon name with state.
bool isOnCurrentDesktop() const
Returns true if the window is on the currently active virtual desktop.
QString visibleNameWithState() const
Returns a visible name with state.
NET::States state() const
Returns the window's state flags.
bool isOnDesktop(int desktop) const
Returns true if the window is on the given virtual desktop.
WId win() const
Returns the window identifier.
bool hasState(NET::States s) const
Returns true if the window has the given state flag set.
WId transientFor() const
Returns the window identifier of the main window this window belongs to.
QByteArray applicationMenuServiceName() const
Returns service name of a window's application menu if present.
KWindowInfo & operator=(const KWindowInfo &)
Assignment operator.
QString visibleIconName() const
Returns the visible name of the window that should be shown in a taskbar.
WId groupLeader() const
Returns the leader window for the group the window is in, if any.
bool onAllDesktops() const
Returns true if the window is on all desktops.
QRect geometry() const
Returns the position and size of the window contents.
NET::WindowType windowType(NET::WindowTypes supported_types) const
Returns the window type of this window.
QByteArray desktopFileName() const
Returns the desktop file name of the window's application if present.
int desktop() const
Returns the virtual desktop this window is on.
KWindowInfo(WId window, NET::Properties properties, NET::Properties2 properties2=NET::Properties2())
Reads all the info about the given window.
QByteArray windowClassClass() const
Returns the class component of the WM_CLASS X11 property for the window.
NET::MappingState mappingState() const
Returns the mapping state of the window.
QRect frameGeometry() const
Returns the frame geometry of the window, i.e.
QStringList activities() const
Returns the list of activity UUIDs this window belongs to.
QByteArray clientMachine() const
Returns the WM_CLIENT_MACHINE property for the window.
QString name() const
Returns the name of the window, as specified by the application.
QByteArray applicationMenuObjectPath() const
Returns object path of a window's application menu if present.
Common API for root window properties/protocols.
Common API for application window properties/protocols.
NET::States state() const
Returns the state of the window (see the NET base class documentation for a description of the variou...
@ Sticky
indicates that the Window Manager SHOULD keep the window's position fixed on the screen,...
@ Shaded
indicates that the window is shaded (rolled-up).
@ Hidden
indicates that a window should not be visible on the screen (e.g.
@ Normal
indicates that this is a normal, top-level window
@ Dialog
indicates that this is a dialog window
Action
Actions that can be done with a window (_NET_WM_ALLOWED_ACTIONS).
MappingState
Client window mapping state.
@ Iconic
indicates that the client window is not visible, but its icon is.
@ Withdrawn
indicates that neither the client window nor its icon is visible.
QString fromLatin1(QByteArrayView str)
QString fromUtf8(QByteArrayView str)
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
Partial strut class for NET classes.
int bottom_width
Bottom border of the strut, width and range.
int left_width
Left border of the strut, width and range.
int right_width
Right border of the strut, width and range.
int top_width
Top border of the strut, width and range.
Simple rectangle class for NET classes.
NETPoint pos
Position of the rectangle.
NETSize size
Size of the rectangle.
int bottom
Bottom border of the strut.
int left
Left border of the strut.
int right
Right border of the strut.
int top
Top border of the strut.