11#include <xcb/xproto.h>
15#include "kxcbevent_p.h"
17#if KWINDOWSYSTEM_HAVE_X11
19#include <QGuiApplication>
22#include <private/qtx11extras_p.h>
24#include <kwindowinfo.h>
25#include <kwindowsystem.h>
26#include <kx11extras.h>
38 int32_t initial_state;
39 xcb_pixmap_t icon_pixmap;
40 xcb_window_t icon_window;
43 xcb_pixmap_t icon_mask;
44 xcb_window_t window_group;
48Q_GLOBAL_STATIC(
AtomHash, s_gAtomsHash)
52 auto it = s_gAtomsHash->constFind(c);
53 if (it == s_gAtomsHash->constEnd()) {
55 s_gAtomsHash->insert(c, atom);
61Atoms::Atoms(xcb_connection_t *c)
65 for (
int i = 0; i < KwsAtomCount; ++i) {
66 m_atoms[i] = XCB_ATOM_NONE;
71static const uint32_t netwm_sendevent_mask = (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY);
73const long MAX_PROP_SIZE = 100000;
75static char *nstrdup(
const char *s1)
78 return (
char *)
nullptr;
81 int l = strlen(s1) + 1;
82 char *s2 =
new char[l];
87static char *nstrndup(
const char *s1,
int l)
90 return (
char *)
nullptr;
93 char *s2 =
new char[l + 1];
99static xcb_window_t *nwindup(
const xcb_window_t *w1,
int n)
102 return (xcb_window_t *)
nullptr;
105 xcb_window_t *w2 =
new xcb_window_t[n];
112static void refdec_nri(NETRootInfoPrivate *p)
115 fprintf(stderr,
"NET: decrementing NETRootInfoPrivate::ref (%d)\n", p->ref - 1);
120 fprintf(stderr,
"NET: \tno more references, deleting\n");
124 delete[] p->stacking;
126 delete[] p->virtual_roots;
127 delete[] p->temp_buf;
130 for (i = 0; i < p->desktop_names.size(); i++) {
131 delete[] p->desktop_names[i];
136static void refdec_nwi(NETWinInfoPrivate *p)
139 fprintf(stderr,
"NET: decrementing NETWinInfoPrivate::ref (%d)\n", p->ref - 1);
144 fprintf(stderr,
"NET: \tno more references, deleting\n");
148 delete[] p->visible_name;
149 delete[] p->window_role;
150 delete[] p->icon_name;
151 delete[] p->visible_icon_name;
152 delete[] p->startup_id;
153 delete[] p->class_class;
154 delete[] p->class_name;
155 delete[] p->activities;
156 delete[] p->client_machine;
157 delete[] p->desktop_file;
158 delete[] p->gtk_application_id;
159 delete[] p->appmenu_object_path;
160 delete[] p->appmenu_service_name;
163 for (i = 0; i < p->icons.size(); i++) {
164 delete[] p->icons[i].data;
166 delete[] p->icon_sizes;
171T get_value_reply(xcb_connection_t *c,
const xcb_get_property_cookie_t cookie, xcb_atom_t type, T def,
bool *success =
nullptr)
175 xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie,
nullptr);
182 if (reply->type == type && reply->value_len == 1 && reply->format ==
sizeof(T) * 8) {
183 value = *
reinterpret_cast<T *
>(xcb_get_property_value(reply));
197QList<T> get_array_reply(xcb_connection_t *c,
const xcb_get_property_cookie_t cookie, xcb_atom_t type)
199 xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie,
nullptr);
206 if (reply->type == type && reply->value_len > 0 && reply->format ==
sizeof(T) * 8) {
207 T *data =
reinterpret_cast<T *
>(xcb_get_property_value(reply));
209 vector.
resize(reply->value_len);
210 memcpy((
void *)&vector.
first(), (
void *)data, reply->value_len *
sizeof(T));
217static QByteArray get_string_reply(xcb_connection_t *c,
const xcb_get_property_cookie_t cookie, xcb_atom_t type)
219 xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie,
nullptr);
226 if (reply->type == type && reply->format == 8 && reply->value_len > 0) {
227 const char *data = (
const char *)xcb_get_property_value(reply);
228 int len = reply->value_len;
231 value =
QByteArray(data, data[len - 1] ? len : len - 1);
239static QList<QByteArray> get_stringlist_reply(xcb_connection_t *c,
const xcb_get_property_cookie_t cookie, xcb_atom_t type)
241 xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie,
nullptr);
248 if (reply->type == type && reply->format == 8 && reply->value_len > 0) {
249 const char *data = (
const char *)xcb_get_property_value(reply);
250 int len = reply->value_len;
263static QByteArray get_atom_name(xcb_connection_t *c, xcb_atom_t atom)
265 const xcb_get_atom_name_cookie_t cookie = xcb_get_atom_name(c, atom);
267 xcb_get_atom_name_reply_t *reply = xcb_get_atom_name_reply(c, cookie, 0);
281#define ENUM_CREATE_CHAR_ARRAY 1
284 xcb_intern_atom_cookie_t cookies[KwsAtomCount];
285 for (
int i = 0; i < KwsAtomCount; ++i) {
286 cookies[i] = xcb_intern_atom(m_connection,
false, strlen(KwsAtomStrings[i]), KwsAtomStrings[i]);
290 for (
int i = 0; i < KwsAtomCount; ++i) {
291 xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(m_connection, cookies[i],
nullptr);
296 m_atoms[i] = reply->atom;
301static void readIcon(xcb_connection_t *c,
const xcb_get_property_cookie_t cookie, NETRArray<NETIcon> &icons,
int &icon_count)
304 fprintf(stderr,
"NET: readIcon\n");
308 for (
int i = 0; i < icons.size(); i++) {
309 delete[] icons[i].data;
315 xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie,
nullptr);
317 if (!reply || reply->value_len < 3 || reply->format != 32 || reply->type != XCB_ATOM_CARDINAL) {
325 uint32_t *data = (uint32_t *)xcb_get_property_value(reply);
327 for (
unsigned int i = 0, j = 0; j < reply->value_len - 2; i++) {
328 uint32_t width = data[j++];
329 uint32_t height = data[j++];
330 uint32_t size = width * height *
sizeof(uint32_t);
332 if (width == 0 || height == 0) {
333 fprintf(stderr,
"Invalid icon size (%d x %d)\n", width, height);
337 constexpr int maxIconSize = 8192;
338 if (width > maxIconSize || height > maxIconSize) {
339 fprintf(stderr,
"Icon size larger than maximum (%d x %d)\n", width, height);
343 if (j + width * height > reply->value_len) {
344 fprintf(stderr,
"Ill-encoded icon data; proposed size leads to out of bounds access. Skipping. (%d x %d)\n", width, height);
348 icons[i].size.width = width;
349 icons[i].size.height = height;
350 icons[i].data =
new unsigned char[size];
352 memcpy((
void *)icons[i].data, (
const void *)&data[j], size);
361 fprintf(stderr,
"NET: readIcon got %d icons\n", icon_count);
365static void send_client_message(xcb_connection_t *c, uint32_t mask, xcb_window_t destination, xcb_window_t window, xcb_atom_t message,
const uint32_t data[])
367 KXcbEvent<xcb_client_message_event_t>
event;
368 event.response_type = XCB_CLIENT_MESSAGE;
372 event.type = message;
374 for (
int i = 0; i < 5; i++) {
375 event.data.data32[i] = data[i];
378 xcb_send_event(c,
false, destination, mask,
event.buffer());
382NETRArray<Z>::NETRArray()
386 d = (Z *)calloc(capacity,
sizeof(Z));
390NETRArray<Z>::~NETRArray()
396void NETRArray<Z>::reset()
400 d = (Z *)realloc(d,
sizeof(Z) * capacity);
401 memset((
void *)d, 0,
sizeof(Z) * capacity);
405Z &NETRArray<Z>::operator[](
int index)
407 if (index >= capacity) {
413 d = (Z *)realloc(d,
sizeof(Z) * newcapacity);
414 memset((
void *)&d[capacity], 0,
sizeof(Z) * (newcapacity - capacity));
437 xcb_window_t supportWindow,
448 fprintf(stderr,
"NETRootInfo::NETRootInfo: using window manager constructor\n");
451 p =
new NETRootInfoPrivate;
453 p->atoms = atomsForConnection(connection);
455 p->name = nstrdup(
wmName);
457 p->conn = connection;
459 p->temp_buf =
nullptr;
460 p->temp_buf_size = 0;
462 const xcb_setup_t *setup = xcb_get_setup(p->conn);
463 xcb_screen_iterator_t it = xcb_setup_roots_iterator(setup);
465 if (screen != -1 && screen < setup->roots_len) {
466 for (
int i = 0; i < screen; i++) {
467 xcb_screen_next(&it);
471 p->root = it.data->root;
473 p->number_of_desktops = p->current_desktop = 0;
474 p->active = XCB_WINDOW_NONE;
475 p->clients = p->stacking = p->virtual_roots = (xcb_window_t *)
nullptr;
476 p->clients_count = p->stacking_count = p->virtual_roots_count = 0;
477 p->showing_desktop =
false;
478 p->desktop_layout_orientation = OrientationHorizontal;
479 p->desktop_layout_corner = DesktopLayoutCornerTopLeft;
480 p->desktop_layout_columns = p->desktop_layout_rows = 0;
481 setDefaultProperties();
482 p->properties = properties;
483 p->properties2 = properties2;
484 p->windowTypes = windowTypes;
486 p->actions = actions;
488 p->properties |= (Supported | SupportingWMCheck);
489 p->clientProperties = DesktopNames
491 p->clientProperties2 = WM2DesktopLayout;
503 fprintf(stderr,
"NETRootInfo::NETRootInfo: using Client constructor\n");
506 p =
new NETRootInfoPrivate;
508 p->atoms = atomsForConnection(connection);
512 p->conn = connection;
514 p->temp_buf =
nullptr;
515 p->temp_buf_size = 0;
517 const xcb_setup_t *setup = xcb_get_setup(p->conn);
518 xcb_screen_iterator_t it = xcb_setup_roots_iterator(setup);
520 if (screen != -1 && screen < setup->roots_len) {
521 for (
int i = 0; i < screen; i++) {
522 xcb_screen_next(&it);
526 p->root = it.data->root;
527 p->rootSize.width = it.data->width_in_pixels;
528 p->rootSize.height = it.data->height_in_pixels;
530 p->supportwindow = XCB_WINDOW_NONE;
531 p->number_of_desktops = p->current_desktop = 0;
532 p->active = XCB_WINDOW_NONE;
533 p->clients = p->stacking = p->virtual_roots = (xcb_window_t *)
nullptr;
534 p->clients_count = p->stacking_count = p->virtual_roots_count = 0;
535 p->showing_desktop =
false;
536 p->desktop_layout_orientation = OrientationHorizontal;
537 p->desktop_layout_corner = DesktopLayoutCornerTopLeft;
538 p->desktop_layout_columns = p->desktop_layout_rows = 0;
539 setDefaultProperties();
540 p->clientProperties = properties;
541 p->clientProperties2 = properties2;
560 fprintf(stderr,
"NETRootInfo::NETRootInfo: using copy constructor\n");
579void NETRootInfo::setDefaultProperties()
581 p->properties = Supported | SupportingWMCheck;
594 fprintf(stderr,
"NETRootInfo::activate: setting supported properties on root\n");
598 update(p->clientProperties, p->clientProperties2);
601 fprintf(stderr,
"NETRootInfo::activate: updating client information\n");
604 update(p->clientProperties, p->clientProperties2);
614 p->clients_count = count;
617 p->clients = nwindup(windows, count);
620 fprintf(stderr,
"NETRootInfo::setClientList: setting list with %ld windows\n", p->clients_count);
623 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->root, p->atom(_NET_CLIENT_LIST), XCB_ATOM_WINDOW, 32, p->clients_count, (
const void *)windows);
632 p->stacking_count = count;
633 delete[] p->stacking;
634 p->stacking = nwindup(windows, count);
637 fprintf(stderr,
"NETRootInfo::setClientListStacking: setting list with %ld windows\n", p->clients_count);
640 xcb_change_property(p->conn,
641 XCB_PROP_MODE_REPLACE,
643 p->atom(_NET_CLIENT_LIST_STACKING),
647 (
const void *)windows);
653 fprintf(stderr,
"NETRootInfo::setNumberOfDesktops: setting desktop count to %d (%s)\n",
numberOfDesktops, (p->role ==
WindowManager) ?
"WM" :
"Client");
659 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->root, p->atom(_NET_NUMBER_OF_DESKTOPS), XCB_ATOM_CARDINAL, 32, 1, (
const void *)&d);
663 send_client_message(p->conn, netwm_sendevent_mask, p->root, p->root, p->atom(_NET_NUMBER_OF_DESKTOPS), data);
670 fprintf(stderr,
"NETRootInfo::setCurrentDesktop: setting current desktop = %d (%s)\n", desktop, (p->role ==
WindowManager) ?
"WM" :
"Client");
674 p->current_desktop = desktop;
675 uint32_t d = p->current_desktop - 1;
676 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->root, p->atom(_NET_CURRENT_DESKTOP), XCB_ATOM_CARDINAL, 32, 1, (
const void *)&d);
683 const uint32_t data[5] = {uint32_t(desktop - 1), 0, 0, 0, 0};
685 send_client_message(p->conn, netwm_sendevent_mask, p->root, p->root, p->atom(_NET_CURRENT_DESKTOP), data);
696 delete[] p->desktop_names[desktop - 1];
697 p->desktop_names[desktop - 1] = nstrdup(
desktopName);
700 unsigned int proplen;
701 unsigned int num = ((p->number_of_desktops > p->desktop_names.size()) ? p->number_of_desktops : p->desktop_names.size());
702 for (i = 0, proplen = 0; i < num; i++) {
703 proplen += (p->desktop_names[i] !=
nullptr ? strlen(p->desktop_names[i]) + 1 : 1);
706 char *prop =
new char[proplen];
709 for (i = 0; i < num; i++) {
710 if (p->desktop_names[i]) {
711 strcpy(propp, p->desktop_names[i]);
712 propp += strlen(p->desktop_names[i]) + 1;
720 "NETRootInfo::setDesktopName(%d, '%s')\n"
721 "NETRootInfo::setDesktopName: total property length = %d",
727 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->root, p->atom(_NET_DESKTOP_NAMES), p->atom(UTF8_STRING), 8, proplen, (
const void *)prop);
735 fprintf(stderr,
"NETRootInfo::setDesktopGeometry( -- , { %d, %d }) (%s)\n", geometry.
width, geometry.
height, (p->role ==
WindowManager) ?
"WM" :
"Client");
739 p->geometry = geometry;
742 data[0] = p->geometry.width;
743 data[1] = p->geometry.height;
745 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->root, p->atom(_NET_DESKTOP_GEOMETRY), XCB_ATOM_CARDINAL, 32, 2, (
const void *)data);
747 uint32_t data[5] = {uint32_t(geometry.
width), uint32_t(geometry.
height), 0, 0, 0};
749 send_client_message(p->conn, netwm_sendevent_mask, p->root, p->root, p->atom(_NET_DESKTOP_GEOMETRY), data);
756 fprintf(stderr,
"NETRootInfo::setDesktopViewport(%d, { %d, %d }) (%s)\n", desktop, viewport.
x, viewport.
y, (p->role ==
WindowManager) ?
"WM" :
"Client");
764 p->viewport[desktop - 1] = viewport;
769 l = p->number_of_desktops * 2;
770 uint32_t *data =
new uint32_t[l];
771 for (d = 0, i = 0; d < p->number_of_desktops; d++) {
772 data[i++] = p->viewport[d].x;
773 data[i++] = p->viewport[d].y;
776 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->root, p->atom(_NET_DESKTOP_VIEWPORT), XCB_ATOM_CARDINAL, 32, l, (
const void *)data);
780 const uint32_t data[5] = {uint32_t(viewport.
x), uint32_t(viewport.
y), 0, 0, 0};
782 send_client_message(p->conn, netwm_sendevent_mask, p->root, p->root, p->atom(_NET_DESKTOP_VIEWPORT), data);
786void NETRootInfo::setSupported()
790 fprintf(stderr,
"NETRootInfo::setSupported - role != WindowManager\n");
796 xcb_atom_t atoms[KwsAtomCount];
800 atoms[0] = p->atom(_NET_SUPPORTED);
801 atoms[1] = p->atom(_NET_SUPPORTING_WM_CHECK);
803 if (p->properties & ClientList) {
804 atoms[pnum++] = p->atom(_NET_CLIENT_LIST);
807 if (p->properties & ClientListStacking) {
808 atoms[pnum++] = p->atom(_NET_CLIENT_LIST_STACKING);
811 if (p->properties & NumberOfDesktops) {
812 atoms[pnum++] = p->atom(_NET_NUMBER_OF_DESKTOPS);
815 if (p->properties & DesktopGeometry) {
816 atoms[pnum++] = p->atom(_NET_DESKTOP_GEOMETRY);
819 if (p->properties & DesktopViewport) {
820 atoms[pnum++] = p->atom(_NET_DESKTOP_VIEWPORT);
823 if (p->properties & CurrentDesktop) {
824 atoms[pnum++] = p->atom(_NET_CURRENT_DESKTOP);
827 if (p->properties & DesktopNames) {
828 atoms[pnum++] = p->atom(_NET_DESKTOP_NAMES);
831 if (p->properties & ActiveWindow) {
832 atoms[pnum++] = p->atom(_NET_ACTIVE_WINDOW);
835 if (p->properties & WorkArea) {
836 atoms[pnum++] = p->atom(_NET_WORKAREA);
839 if (p->properties & VirtualRoots) {
840 atoms[pnum++] = p->atom(_NET_VIRTUAL_ROOTS);
843 if (p->properties2 & WM2DesktopLayout) {
844 atoms[pnum++] = p->atom(_NET_DESKTOP_LAYOUT);
847 if (p->properties & CloseWindow) {
848 atoms[pnum++] = p->atom(_NET_CLOSE_WINDOW);
851 if (p->properties2 & WM2RestackWindow) {
852 atoms[pnum++] = p->atom(_NET_RESTACK_WINDOW);
855 if (p->properties2 & WM2ShowingDesktop) {
856 atoms[pnum++] = p->atom(_NET_SHOWING_DESKTOP);
860 if (p->properties & WMMoveResize) {
861 atoms[pnum++] = p->atom(_NET_WM_MOVERESIZE);
864 if (p->properties2 & WM2MoveResizeWindow) {
865 atoms[pnum++] = p->atom(_NET_MOVERESIZE_WINDOW);
868 if (p->properties & WMName) {
869 atoms[pnum++] = p->atom(_NET_WM_NAME);
872 if (p->properties & WMVisibleName) {
873 atoms[pnum++] = p->atom(_NET_WM_VISIBLE_NAME);
876 if (p->properties & WMIconName) {
877 atoms[pnum++] = p->atom(_NET_WM_ICON_NAME);
880 if (p->properties & WMVisibleIconName) {
881 atoms[pnum++] = p->atom(_NET_WM_VISIBLE_ICON_NAME);
884 if (p->properties & WMDesktop) {
885 atoms[pnum++] = p->atom(_NET_WM_DESKTOP);
888 if (p->properties & WMWindowType) {
889 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE);
893 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE_NORMAL);
896 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE_DESKTOP);
899 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE_DOCK);
902 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE_TOOLBAR);
905 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE_MENU);
908 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE_DIALOG);
911 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE_UTILITY);
914 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE_SPLASH);
917 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE_DROPDOWN_MENU);
920 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE_POPUP_MENU);
923 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE_TOOLTIP);
926 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE_NOTIFICATION);
929 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE_COMBO);
932 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE_DND);
936 atoms[pnum++] = p->atom(_KDE_NET_WM_WINDOW_TYPE_OVERRIDE);
939 atoms[pnum++] = p->atom(_KDE_NET_WM_WINDOW_TYPE_TOPMENU);
942 atoms[pnum++] = p->atom(_KDE_NET_WM_WINDOW_TYPE_ON_SCREEN_DISPLAY);
945 atoms[pnum++] = p->atom(_KDE_NET_WM_WINDOW_TYPE_CRITICAL_NOTIFICATION);
948 atoms[pnum++] = p->atom(_KDE_NET_WM_WINDOW_TYPE_APPLET_POPUP);
952 if (p->properties & WMState) {
953 atoms[pnum++] = p->atom(_NET_WM_STATE);
956 if (p->states &
Modal) {
957 atoms[pnum++] = p->atom(_NET_WM_STATE_MODAL);
960 atoms[pnum++] = p->atom(_NET_WM_STATE_STICKY);
963 atoms[pnum++] = p->atom(_NET_WM_STATE_MAXIMIZED_VERT);
966 atoms[pnum++] = p->atom(_NET_WM_STATE_MAXIMIZED_HORZ);
969 atoms[pnum++] = p->atom(_NET_WM_STATE_SHADED);
972 atoms[pnum++] = p->atom(_NET_WM_STATE_SKIP_TASKBAR);
975 atoms[pnum++] = p->atom(_NET_WM_STATE_SKIP_PAGER);
978 atoms[pnum++] = p->atom(_KDE_NET_WM_STATE_SKIP_SWITCHER);
981 atoms[pnum++] = p->atom(_NET_WM_STATE_HIDDEN);
984 atoms[pnum++] = p->atom(_NET_WM_STATE_FULLSCREEN);
987 atoms[pnum++] = p->atom(_NET_WM_STATE_ABOVE);
989 atoms[pnum++] = p->atom(_NET_WM_STATE_STAYS_ON_TOP);
992 atoms[pnum++] = p->atom(_NET_WM_STATE_BELOW);
995 atoms[pnum++] = p->atom(_NET_WM_STATE_DEMANDS_ATTENTION);
999 atoms[pnum++] = p->atom(_NET_WM_STATE_FOCUSED);
1003 if (p->properties & WMStrut) {
1004 atoms[pnum++] = p->atom(_NET_WM_STRUT);
1007 if (p->properties2 & WM2ExtendedStrut) {
1008 atoms[pnum++] = p->atom(_NET_WM_STRUT_PARTIAL);
1011 if (p->properties & WMIconGeometry) {
1012 atoms[pnum++] = p->atom(_NET_WM_ICON_GEOMETRY);
1015 if (p->properties & WMIcon) {
1016 atoms[pnum++] = p->atom(_NET_WM_ICON);
1019 if (p->properties & WMPid) {
1020 atoms[pnum++] = p->atom(_NET_WM_PID);
1023 if (p->properties & WMHandledIcons) {
1024 atoms[pnum++] = p->atom(_NET_WM_HANDLED_ICONS);
1027 if (p->properties & WMPing) {
1028 atoms[pnum++] = p->atom(_NET_WM_PING);
1031 if (p->properties2 & WM2UserTime) {
1032 atoms[pnum++] = p->atom(_NET_WM_USER_TIME);
1035 if (p->properties2 & WM2StartupId) {
1036 atoms[pnum++] = p->atom(_NET_STARTUP_ID);
1039 if (p->properties2 & WM2Opacity) {
1040 atoms[pnum++] = p->atom(_NET_WM_WINDOW_OPACITY);
1043 if (p->properties2 & WM2FullscreenMonitors) {
1044 atoms[pnum++] = p->atom(_NET_WM_FULLSCREEN_MONITORS);
1047 if (p->properties2 & WM2AllowedActions) {
1048 atoms[pnum++] = p->atom(_NET_WM_ALLOWED_ACTIONS);
1051 if (p->actions & ActionMove) {
1052 atoms[pnum++] = p->atom(_NET_WM_ACTION_MOVE);
1054 if (p->actions & ActionResize) {
1055 atoms[pnum++] = p->atom(_NET_WM_ACTION_RESIZE);
1057 if (p->actions & ActionMinimize) {
1058 atoms[pnum++] = p->atom(_NET_WM_ACTION_MINIMIZE);
1060 if (p->actions & ActionShade) {
1061 atoms[pnum++] = p->atom(_NET_WM_ACTION_SHADE);
1063 if (p->actions & ActionStick) {
1064 atoms[pnum++] = p->atom(_NET_WM_ACTION_STICK);
1066 if (p->actions & ActionMaxVert) {
1067 atoms[pnum++] = p->atom(_NET_WM_ACTION_MAXIMIZE_VERT);
1069 if (p->actions & ActionMaxHoriz) {
1070 atoms[pnum++] = p->atom(_NET_WM_ACTION_MAXIMIZE_HORZ);
1072 if (p->actions & ActionFullScreen) {
1073 atoms[pnum++] = p->atom(_NET_WM_ACTION_FULLSCREEN);
1075 if (p->actions & ActionChangeDesktop) {
1076 atoms[pnum++] = p->atom(_NET_WM_ACTION_CHANGE_DESKTOP);
1078 if (p->actions & ActionClose) {
1079 atoms[pnum++] = p->atom(_NET_WM_ACTION_CLOSE);
1083 if (p->properties & WMFrameExtents) {
1084 atoms[pnum++] = p->atom(_NET_FRAME_EXTENTS);
1085 atoms[pnum++] = p->atom(_KDE_NET_WM_FRAME_STRUT);
1088 if (p->properties2 & WM2FrameOverlap) {
1089 atoms[pnum++] = p->atom(_NET_WM_FRAME_OVERLAP);
1092 if (p->properties2 & WM2KDETemporaryRules) {
1093 atoms[pnum++] = p->atom(_KDE_NET_WM_TEMPORARY_RULES);
1095 if (p->properties2 & WM2FullPlacement) {
1096 atoms[pnum++] = p->atom(_NET_WM_FULL_PLACEMENT);
1099 if (p->properties2 & WM2Activities) {
1100 atoms[pnum++] = p->atom(_KDE_NET_WM_ACTIVITIES);
1103 if (p->properties2 & WM2BlockCompositing) {
1104 atoms[pnum++] = p->atom(_KDE_NET_WM_BLOCK_COMPOSITING);
1105 atoms[pnum++] = p->atom(_NET_WM_BYPASS_COMPOSITOR);
1108 if (p->properties2 & WM2KDEShadow) {
1109 atoms[pnum++] = p->atom(_KDE_NET_WM_SHADOW);
1112 if (p->properties2 & WM2OpaqueRegion) {
1113 atoms[pnum++] = p->atom(_NET_WM_OPAQUE_REGION);
1116 if (p->properties2 & WM2GTKFrameExtents) {
1117 atoms[pnum++] = p->atom(_GTK_FRAME_EXTENTS);
1120 if (p->properties2 & WM2GTKShowWindowMenu) {
1121 atoms[pnum++] = p->atom(_GTK_SHOW_WINDOW_MENU);
1124 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->root, p->atom(_NET_SUPPORTED), XCB_ATOM_ATOM, 32, pnum, (
const void *)atoms);
1126 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->root, p->atom(_NET_SUPPORTING_WM_CHECK), XCB_ATOM_WINDOW, 32, 1, (
const void *)&(p->supportwindow));
1130 "NETRootInfo::setSupported: _NET_SUPPORTING_WM_CHECK = 0x%lx on 0x%lx\n"
1131 " : _NET_WM_NAME = '%s' on 0x%lx\n",
1138 xcb_change_property(p->conn,
1139 XCB_PROP_MODE_REPLACE,
1141 p->atom(_NET_SUPPORTING_WM_CHECK),
1145 (
const void *)&(p->supportwindow));
1147 xcb_change_property(p->conn,
1148 XCB_PROP_MODE_REPLACE,
1150 p->atom(_NET_WM_NAME),
1151 p->atom(UTF8_STRING),
1154 (
const void *)p->name);
1157void NETRootInfo::updateSupportedProperties(xcb_atom_t atom)
1159 if (atom == p->atom(_NET_SUPPORTED)) {
1160 p->properties |= Supported;
1163 else if (atom == p->atom(_NET_SUPPORTING_WM_CHECK)) {
1164 p->properties |= SupportingWMCheck;
1167 else if (atom == p->atom(_NET_CLIENT_LIST)) {
1168 p->properties |= ClientList;
1171 else if (atom == p->atom(_NET_CLIENT_LIST_STACKING)) {
1172 p->properties |= ClientListStacking;
1175 else if (atom == p->atom(_NET_NUMBER_OF_DESKTOPS)) {
1176 p->properties |= NumberOfDesktops;
1179 else if (atom == p->atom(_NET_DESKTOP_GEOMETRY)) {
1180 p->properties |= DesktopGeometry;
1183 else if (atom == p->atom(_NET_DESKTOP_VIEWPORT)) {
1184 p->properties |= DesktopViewport;
1187 else if (atom == p->atom(_NET_CURRENT_DESKTOP)) {
1188 p->properties |= CurrentDesktop;
1191 else if (atom == p->atom(_NET_DESKTOP_NAMES)) {
1192 p->properties |= DesktopNames;
1195 else if (atom == p->atom(_NET_ACTIVE_WINDOW)) {
1196 p->properties |= ActiveWindow;
1199 else if (atom == p->atom(_NET_WORKAREA)) {
1200 p->properties |= WorkArea;
1203 else if (atom == p->atom(_NET_VIRTUAL_ROOTS)) {
1204 p->properties |= VirtualRoots;
1207 else if (atom == p->atom(_NET_DESKTOP_LAYOUT)) {
1208 p->properties2 |= WM2DesktopLayout;
1211 else if (atom == p->atom(_NET_CLOSE_WINDOW)) {
1212 p->properties |= CloseWindow;
1215 else if (atom == p->atom(_NET_RESTACK_WINDOW)) {
1216 p->properties2 |= WM2RestackWindow;
1219 else if (atom == p->atom(_NET_SHOWING_DESKTOP)) {
1220 p->properties2 |= WM2ShowingDesktop;
1224 else if (atom == p->atom(_NET_WM_MOVERESIZE)) {
1225 p->properties |= WMMoveResize;
1228 else if (atom == p->atom(_NET_MOVERESIZE_WINDOW)) {
1229 p->properties2 |= WM2MoveResizeWindow;
1232 else if (atom == p->atom(_NET_WM_NAME)) {
1233 p->properties |= WMName;
1236 else if (atom == p->atom(_NET_WM_VISIBLE_NAME)) {
1237 p->properties |= WMVisibleName;
1240 else if (atom == p->atom(_NET_WM_ICON_NAME)) {
1241 p->properties |= WMIconName;
1244 else if (atom == p->atom(_NET_WM_VISIBLE_ICON_NAME)) {
1245 p->properties |= WMVisibleIconName;
1248 else if (atom == p->atom(_NET_WM_DESKTOP)) {
1249 p->properties |= WMDesktop;
1252 else if (atom == p->atom(_NET_WM_WINDOW_TYPE)) {
1253 p->properties |= WMWindowType;
1257 else if (atom == p->atom(_NET_WM_WINDOW_TYPE_NORMAL)) {
1259 }
else if (atom == p->atom(_NET_WM_WINDOW_TYPE_DESKTOP)) {
1261 }
else if (atom == p->atom(_NET_WM_WINDOW_TYPE_DOCK)) {
1263 }
else if (atom == p->atom(_NET_WM_WINDOW_TYPE_TOOLBAR)) {
1265 }
else if (atom == p->atom(_NET_WM_WINDOW_TYPE_MENU)) {
1267 }
else if (atom == p->atom(_NET_WM_WINDOW_TYPE_DIALOG)) {
1269 }
else if (atom == p->atom(_NET_WM_WINDOW_TYPE_UTILITY)) {
1271 }
else if (atom == p->atom(_NET_WM_WINDOW_TYPE_SPLASH)) {
1273 }
else if (atom == p->atom(_NET_WM_WINDOW_TYPE_DROPDOWN_MENU)) {
1275 }
else if (atom == p->atom(_NET_WM_WINDOW_TYPE_POPUP_MENU)) {
1277 }
else if (atom == p->atom(_NET_WM_WINDOW_TYPE_TOOLTIP)) {
1279 }
else if (atom == p->atom(_NET_WM_WINDOW_TYPE_NOTIFICATION)) {
1281 }
else if (atom == p->atom(_NET_WM_WINDOW_TYPE_COMBO)) {
1283 }
else if (atom == p->atom(_NET_WM_WINDOW_TYPE_DND)) {
1287 else if (atom == p->atom(_KDE_NET_WM_WINDOW_TYPE_OVERRIDE)) {
1289 }
else if (atom == p->atom(_KDE_NET_WM_WINDOW_TYPE_TOPMENU)) {
1291 }
else if (atom == p->atom(_KDE_NET_WM_WINDOW_TYPE_ON_SCREEN_DISPLAY)) {
1293 }
else if (atom == p->atom(_KDE_NET_WM_WINDOW_TYPE_CRITICAL_NOTIFICATION)) {
1295 }
else if (atom == p->atom(_KDE_NET_WM_WINDOW_TYPE_APPLET_POPUP)) {
1299 else if (atom == p->atom(_NET_WM_STATE)) {
1300 p->properties |= WMState;
1304 else if (atom == p->atom(_NET_WM_STATE_MODAL)) {
1306 }
else if (atom == p->atom(_NET_WM_STATE_STICKY)) {
1308 }
else if (atom == p->atom(_NET_WM_STATE_MAXIMIZED_VERT)) {
1310 }
else if (atom == p->atom(_NET_WM_STATE_MAXIMIZED_HORZ)) {
1312 }
else if (atom == p->atom(_NET_WM_STATE_SHADED)) {
1314 }
else if (atom == p->atom(_NET_WM_STATE_SKIP_TASKBAR)) {
1316 }
else if (atom == p->atom(_NET_WM_STATE_SKIP_PAGER)) {
1318 }
else if (atom == p->atom(_KDE_NET_WM_STATE_SKIP_SWITCHER)) {
1320 }
else if (atom == p->atom(_NET_WM_STATE_HIDDEN)) {
1322 }
else if (atom == p->atom(_NET_WM_STATE_FULLSCREEN)) {
1324 }
else if (atom == p->atom(_NET_WM_STATE_ABOVE)) {
1326 }
else if (atom == p->atom(_NET_WM_STATE_BELOW)) {
1328 }
else if (atom == p->atom(_NET_WM_STATE_DEMANDS_ATTENTION)) {
1330 }
else if (atom == p->atom(_NET_WM_STATE_STAYS_ON_TOP)) {
1332 }
else if (atom == p->atom(_NET_WM_STATE_FOCUSED)) {
1336 else if (atom == p->atom(_NET_WM_STRUT)) {
1337 p->properties |= WMStrut;
1340 else if (atom == p->atom(_NET_WM_STRUT_PARTIAL)) {
1341 p->properties2 |= WM2ExtendedStrut;
1344 else if (atom == p->atom(_NET_WM_ICON_GEOMETRY)) {
1345 p->properties |= WMIconGeometry;
1348 else if (atom == p->atom(_NET_WM_ICON)) {
1349 p->properties |= WMIcon;
1352 else if (atom == p->atom(_NET_WM_PID)) {
1353 p->properties |= WMPid;
1356 else if (atom == p->atom(_NET_WM_HANDLED_ICONS)) {
1357 p->properties |= WMHandledIcons;
1360 else if (atom == p->atom(_NET_WM_PING)) {
1361 p->properties |= WMPing;
1364 else if (atom == p->atom(_NET_WM_USER_TIME)) {
1365 p->properties2 |= WM2UserTime;
1368 else if (atom == p->atom(_NET_STARTUP_ID)) {
1369 p->properties2 |= WM2StartupId;
1372 else if (atom == p->atom(_NET_WM_WINDOW_OPACITY)) {
1373 p->properties2 |= WM2Opacity;
1376 else if (atom == p->atom(_NET_WM_FULLSCREEN_MONITORS)) {
1377 p->properties2 |= WM2FullscreenMonitors;
1380 else if (atom == p->atom(_NET_WM_ALLOWED_ACTIONS)) {
1381 p->properties2 |= WM2AllowedActions;
1385 else if (atom == p->atom(_NET_WM_ACTION_MOVE)) {
1386 p->actions |= ActionMove;
1387 }
else if (atom == p->atom(_NET_WM_ACTION_RESIZE)) {
1388 p->actions |= ActionResize;
1389 }
else if (atom == p->atom(_NET_WM_ACTION_MINIMIZE)) {
1390 p->actions |= ActionMinimize;
1391 }
else if (atom == p->atom(_NET_WM_ACTION_SHADE)) {
1392 p->actions |= ActionShade;
1393 }
else if (atom == p->atom(_NET_WM_ACTION_STICK)) {
1394 p->actions |= ActionStick;
1395 }
else if (atom == p->atom(_NET_WM_ACTION_MAXIMIZE_VERT)) {
1396 p->actions |= ActionMaxVert;
1397 }
else if (atom == p->atom(_NET_WM_ACTION_MAXIMIZE_HORZ)) {
1398 p->actions |= ActionMaxHoriz;
1399 }
else if (atom == p->atom(_NET_WM_ACTION_FULLSCREEN)) {
1400 p->actions |= ActionFullScreen;
1401 }
else if (atom == p->atom(_NET_WM_ACTION_CHANGE_DESKTOP)) {
1402 p->actions |= ActionChangeDesktop;
1403 }
else if (atom == p->atom(_NET_WM_ACTION_CLOSE)) {
1404 p->actions |= ActionClose;
1407 else if (atom == p->atom(_NET_FRAME_EXTENTS)) {
1408 p->properties |= WMFrameExtents;
1409 }
else if (atom == p->atom(_KDE_NET_WM_FRAME_STRUT)) {
1410 p->properties |= WMFrameExtents;
1411 }
else if (atom == p->atom(_NET_WM_FRAME_OVERLAP)) {
1412 p->properties2 |= WM2FrameOverlap;
1415 else if (atom == p->atom(_KDE_NET_WM_TEMPORARY_RULES)) {
1416 p->properties2 |= WM2KDETemporaryRules;
1417 }
else if (atom == p->atom(_NET_WM_FULL_PLACEMENT)) {
1418 p->properties2 |= WM2FullPlacement;
1421 else if (atom == p->atom(_KDE_NET_WM_ACTIVITIES)) {
1422 p->properties2 |= WM2Activities;
1425 else if (atom == p->atom(_KDE_NET_WM_BLOCK_COMPOSITING) || atom == p->atom(_NET_WM_BYPASS_COMPOSITOR)) {
1426 p->properties2 |= WM2BlockCompositing;
1429 else if (atom == p->atom(_KDE_NET_WM_SHADOW)) {
1430 p->properties2 |= WM2KDEShadow;
1433 else if (atom == p->atom(_NET_WM_OPAQUE_REGION)) {
1434 p->properties2 |= WM2OpaqueRegion;
1437 else if (atom == p->atom(_GTK_FRAME_EXTENTS)) {
1438 p->properties2 |= WM2GTKFrameExtents;
1441 else if (atom == p->atom(_GTK_SHOW_WINDOW_MENU)) {
1442 p->properties2 |= WM2GTKShowWindowMenu;
1445 else if (atom == p->atom(_KDE_NET_WM_APPMENU_OBJECT_PATH)) {
1446 p->properties2 |= WM2AppMenuObjectPath;
1449 else if (atom == p->atom(_KDE_NET_WM_APPMENU_SERVICE_NAME)) {
1450 p->properties2 |= WM2AppMenuServiceName;
1462 fprintf(stderr,
"NETRootInfo::setActiveWindow(0x%lx) (%s)\n", window, (p->role ==
WindowManager) ?
"WM" :
"Client");
1468 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->root, p->atom(_NET_ACTIVE_WINDOW), XCB_ATOM_WINDOW, 32, 1, (
const void *)&(p->active));
1470 const uint32_t data[5] = {src, timestamp, active_window, 0, 0};
1472 send_client_message(p->conn, netwm_sendevent_mask, p->root, window, p->atom(_NET_ACTIVE_WINDOW), data);
1480 "NETRootInfo::setWorkArea(%d, { %d, %d, %d, %d }) (%s)\n",
1493 p->workarea[desktop - 1] = workarea;
1495 uint32_t *wa =
new uint32_t[p->number_of_desktops * 4];
1498 for (i = 0, o = 0; i < p->number_of_desktops; i++) {
1499 wa[o++] = p->workarea[i].pos.x;
1500 wa[o++] = p->workarea[i].pos.y;
1501 wa[o++] = p->workarea[i].size.width;
1502 wa[o++] = p->workarea[i].size.height;
1505 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->root, p->atom(_NET_WORKAREA), XCB_ATOM_CARDINAL, 32, p->number_of_desktops * 4, (
const void *)wa);
1516 p->virtual_roots_count = count;
1517 delete[] p->virtual_roots;
1518 p->virtual_roots = nwindup(windows, count);
1521 fprintf(stderr,
"NETRootInfo::setVirtualRoots: setting list with %ld windows\n", p->virtual_roots_count);
1524 xcb_change_property(p->conn,
1525 XCB_PROP_MODE_REPLACE,
1527 p->atom(_NET_VIRTUAL_ROOTS),
1530 p->virtual_roots_count,
1531 (
const void *)windows);
1536 p->desktop_layout_orientation = orientation;
1537 p->desktop_layout_columns = columns;
1538 p->desktop_layout_rows = rows;
1539 p->desktop_layout_corner = corner;
1542 fprintf(stderr,
"NETRootInfo::setDesktopLayout: %d %d %d %d\n", orientation, columns, rows, corner);
1546 data[0] = orientation;
1551 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->root, p->atom(_NET_DESKTOP_LAYOUT), XCB_ATOM_CARDINAL, 32, 4, (
const void *)data);
1557 uint32_t d = p->showing_desktop = showing;
1558 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->root, p->atom(_NET_SHOWING_DESKTOP), XCB_ATOM_CARDINAL, 32, 1, (
const void *)&d);
1560 uint32_t data[5] = {uint32_t(showing ? 1 : 0), 0, 0, 0, 0};
1561 send_client_message(p->conn, netwm_sendevent_mask, p->root, p->root, p->atom(_NET_SHOWING_DESKTOP), data);
1567 return p->showing_desktop;
1573 fprintf(stderr,
"NETRootInfo::closeWindowRequest: requesting close for 0x%lx\n", window);
1576 const uint32_t data[5] = {0, 0, 0, 0, 0};
1577 send_client_message(p->conn, netwm_sendevent_mask, p->root, window, p->atom(_NET_CLOSE_WINDOW), data);
1584 "NETRootInfo::moveResizeRequest: requesting resize/move for 0x%lx (%d, %d, %d, %d, %d)\n",
1593 const uint32_t data[5] = {uint32_t(x_root), uint32_t(y_root), uint32_t(direction), uint32_t(button), uint32_t(source)};
1595 send_client_message(p->conn, netwm_sendevent_mask, p->root, window, p->atom(_NET_WM_MOVERESIZE), data);
1601 fprintf(stderr,
"NETRootInfo::moveResizeWindowRequest: resizing/moving 0x%lx (%d, %d, %d, %d, %d)\n", window, flags, x, y, width, height);
1604 const uint32_t data[5] = {uint32_t(flags), uint32_t(x), uint32_t(y), uint32_t(width), uint32_t(height)};
1606 send_client_message(p->conn, netwm_sendevent_mask, p->root, window, p->atom(_NET_MOVERESIZE_WINDOW), data);
1612 fprintf(stderr,
"NETRootInfo::showWindowMenuRequest: requesting menu for 0x%lx (%d, %d, %d)\n", window, device_id, x_root, y_root);
1615 const uint32_t data[5] = {uint32_t(device_id), uint32_t(x_root), uint32_t(y_root), 0, 0};
1616 send_client_message(p->conn, netwm_sendevent_mask, p->root, window, p->atom(_GTK_SHOW_WINDOW_MENU), data);
1622 fprintf(stderr,
"NETRootInfo::restackRequest: requesting restack for 0x%lx (%lx, %d)\n", window, above, detail);
1625 const uint32_t data[5] = {uint32_t(src), uint32_t(above), uint32_t(detail), uint32_t(timestamp), 0};
1627 send_client_message(p->conn, netwm_sendevent_mask, p->root, window, p->atom(_NET_RESTACK_WINDOW), data);
1637 fprintf(stderr,
"NETRootInfo::setPing: window 0x%lx, timestamp %lu\n", window, timestamp);
1640 const uint32_t data[5] = {p->atom(_NET_WM_PING), timestamp, window, 0, 0};
1642 send_client_message(p->conn, 0, window, window, p->atom(WM_PROTOCOLS), data);
1650 fprintf(stderr,
"NETRootInfo::operator=()\n");
1653 if (p != rootinfo.p) {
1678 bool do_update =
false;
1679 const uint8_t eventType =
event->response_type & ~0x80;
1683 if (p->role ==
WindowManager && eventType == XCB_CLIENT_MESSAGE &&
reinterpret_cast<xcb_client_message_event_t *
>(
event)->format == 32) {
1684 xcb_client_message_event_t *message =
reinterpret_cast<xcb_client_message_event_t *
>(
event);
1686 fprintf(stderr,
"NETRootInfo::event: handling ClientMessage event\n");
1689 if (message->type == p->atom(_NET_NUMBER_OF_DESKTOPS)) {
1690 dirty = NumberOfDesktops;
1693 fprintf(stderr,
"NETRootInfo::event: changeNumberOfDesktops(%ld)\n", message->data.data32[0]);
1697 }
else if (message->type == p->atom(_NET_DESKTOP_GEOMETRY)) {
1698 dirty = DesktopGeometry;
1701 sz.
width = message->data.data32[0];
1702 sz.
height = message->data.data32[1];
1705 fprintf(stderr,
"NETRootInfo::event: changeDesktopGeometry( -- , { %d, %d })\n", sz.
width, sz.
height);
1709 }
else if (message->type == p->atom(_NET_DESKTOP_VIEWPORT)) {
1710 dirty = DesktopViewport;
1713 pt.
x = message->data.data32[0];
1714 pt.
y = message->data.data32[1];
1717 fprintf(stderr,
"NETRootInfo::event: changeDesktopViewport(%d, { %d, %d })\n", p->current_desktop, pt.
x, pt.
y);
1721 }
else if (message->type == p->atom(_NET_CURRENT_DESKTOP)) {
1722 dirty = CurrentDesktop;
1725 fprintf(stderr,
"NETRootInfo::event: changeCurrentDesktop(%ld)\n", message->data.data32[0] + 1);
1729 }
else if (message->type == p->atom(_NET_ACTIVE_WINDOW)) {
1730 dirty = ActiveWindow;
1733 fprintf(stderr,
"NETRootInfo::event: changeActiveWindow(0x%lx)\n", message->window);
1737 xcb_timestamp_t timestamp = XCB_TIME_CURRENT_TIME;
1738 xcb_window_t active_window = XCB_WINDOW_NONE;
1742 timestamp = message->data.data32[1];
1743 active_window = message->data.data32[2];
1746 }
else if (message->type == p->atom(_NET_WM_MOVERESIZE)) {
1749 "NETRootInfo::event: moveResize(%ld, %ld, %ld, %ld, %ld, %ld)\n",
1751 message->data.data32[0],
1752 message->data.data32[1],
1753 message->data.data32[2],
1754 message->data.data32[3],
1755 message->data.data32[4]);
1759 message->data.data32[0],
1760 message->data.data32[1],
1761 message->data.data32[2],
1762 message->data.data32[3],
1764 }
else if (message->type == p->atom(_NET_MOVERESIZE_WINDOW)) {
1767 "NETRootInfo::event: moveResizeWindow(%ld, %ld, %ld, %ld, %ld, %ld)\n",
1769 message->data.data32[0],
1770 message->data.data32[1],
1771 message->data.data32[2],
1772 message->data.data32[3],
1773 message->data.data32[4]);
1777 message->data.data32[0],
1778 message->data.data32[1],
1779 message->data.data32[2],
1780 message->data.data32[3],
1781 message->data.data32[4]);
1782 }
else if (message->type == p->atom(_NET_CLOSE_WINDOW)) {
1784 fprintf(stderr,
"NETRootInfo::event: closeWindow(0x%lx)\n", message->window);
1788 }
else if (message->type == p->atom(_NET_RESTACK_WINDOW)) {
1790 fprintf(stderr,
"NETRootInfo::event: restackWindow(0x%lx)\n", message->window);
1794 xcb_timestamp_t timestamp = XCB_TIME_CURRENT_TIME;
1798 timestamp = message->data.data32[3];
1800 restackWindow(message->window, src, message->data.data32[1], message->data.data32[2], timestamp);
1801 }
else if (message->type == p->atom(WM_PROTOCOLS) && (xcb_atom_t)message->data.data32[0] == p->atom(_NET_WM_PING)) {
1805 fprintf(stderr,
"NETRootInfo::event: gotPing(0x%lx,%lu)\n", message->window, message->data.data32[1]);
1807 gotPing(message->data.data32[2], message->data.data32[1]);
1808 }
else if (message->type == p->atom(_NET_SHOWING_DESKTOP)) {
1809 dirty2 = WM2ShowingDesktop;
1812 fprintf(stderr,
"NETRootInfo::event: changeShowingDesktop(%ld)\n", message->data.data32[0]);
1816 }
else if (message->type == p->atom(_GTK_SHOW_WINDOW_MENU)) {
1819 "NETRootInfo::event: showWindowMenu(%ld, %ld, %ld, %ld)\n",
1821 message->data.data32[0],
1822 message->data.data32[1],
1823 message->data.data32[2]);
1826 showWindowMenu(message->window, message->data.data32[0], message->data.data32[1], message->data.data32[2]);
1830 if (eventType == XCB_PROPERTY_NOTIFY) {
1832 fprintf(stderr,
"NETRootInfo::event: handling PropertyNotify event\n");
1835 xcb_property_notify_event_t *pe =
reinterpret_cast<xcb_property_notify_event_t *
>(
event);
1836 if (pe->atom == p->atom(_NET_CLIENT_LIST)) {
1837 dirty |= ClientList;
1838 }
else if (pe->atom == p->atom(_NET_CLIENT_LIST_STACKING)) {
1839 dirty |= ClientListStacking;
1840 }
else if (pe->atom == p->atom(_NET_DESKTOP_NAMES)) {
1841 dirty |= DesktopNames;
1842 }
else if (pe->atom == p->atom(_NET_WORKAREA)) {
1844 }
else if (pe->atom == p->atom(_NET_NUMBER_OF_DESKTOPS)) {
1845 dirty |= NumberOfDesktops;
1846 }
else if (pe->atom == p->atom(_NET_DESKTOP_GEOMETRY)) {
1847 dirty |= DesktopGeometry;
1848 }
else if (pe->atom == p->atom(_NET_DESKTOP_VIEWPORT)) {
1849 dirty |= DesktopViewport;
1850 }
else if (pe->atom == p->atom(_NET_CURRENT_DESKTOP)) {
1851 dirty |= CurrentDesktop;
1852 }
else if (pe->atom == p->atom(_NET_ACTIVE_WINDOW)) {
1853 dirty |= ActiveWindow;
1854 }
else if (pe->atom == p->atom(_NET_SHOWING_DESKTOP)) {
1855 dirty2 |= WM2ShowingDesktop;
1856 }
else if (pe->atom == p->atom(_NET_SUPPORTED)) {
1858 }
else if (pe->atom == p->atom(_NET_SUPPORTING_WM_CHECK)) {
1859 dirty |= SupportingWMCheck;
1860 }
else if (pe->atom == p->atom(_NET_VIRTUAL_ROOTS)) {
1861 dirty |= VirtualRoots;
1862 }
else if (pe->atom == p->atom(_NET_DESKTOP_LAYOUT)) {
1863 dirty2 |= WM2DesktopLayout;
1870 update(dirty, dirty2);
1874 fprintf(stderr,
"NETRootInfo::event: handled events, returning dirty = 0x%lx, 0x%lx\n", dirty, dirty2);
1878 *properties = dirty;
1881 *properties2 = dirty2;
1892 xcb_get_property_cookie_t cookies[255];
1893 xcb_get_property_cookie_t wm_name_cookie;
1897 if (dirty & Supported) {
1898 cookies[c++] = xcb_get_property(p->conn,
false, p->root, p->atom(_NET_SUPPORTED), XCB_ATOM_ATOM, 0, MAX_PROP_SIZE);
1901 if (dirty & ClientList) {
1902 cookies[c++] = xcb_get_property(p->conn,
false, p->root, p->atom(_NET_CLIENT_LIST), XCB_ATOM_WINDOW, 0, MAX_PROP_SIZE);
1905 if (dirty & ClientListStacking) {
1906 cookies[c++] = xcb_get_property(p->conn,
false, p->root, p->atom(_NET_CLIENT_LIST_STACKING), XCB_ATOM_WINDOW, 0, MAX_PROP_SIZE);
1909 if (dirty & NumberOfDesktops) {
1910 cookies[c++] = xcb_get_property(p->conn,
false, p->root, p->atom(_NET_NUMBER_OF_DESKTOPS), XCB_ATOM_CARDINAL, 0, 1);
1913 if (dirty & DesktopGeometry) {
1914 cookies[c++] = xcb_get_property(p->conn,
false, p->root, p->atom(_NET_DESKTOP_GEOMETRY), XCB_ATOM_CARDINAL, 0, 2);
1917 if (dirty & DesktopViewport) {
1918 cookies[c++] = xcb_get_property(p->conn,
false, p->root, p->atom(_NET_DESKTOP_VIEWPORT), XCB_ATOM_CARDINAL, 0, MAX_PROP_SIZE);
1921 if (dirty & CurrentDesktop) {
1922 cookies[c++] = xcb_get_property(p->conn,
false, p->root, p->atom(_NET_CURRENT_DESKTOP), XCB_ATOM_CARDINAL, 0, 1);
1925 if (dirty & DesktopNames) {
1926 cookies[c++] = xcb_get_property(p->conn,
false, p->root, p->atom(_NET_DESKTOP_NAMES), p->atom(UTF8_STRING), 0, MAX_PROP_SIZE);
1929 if (dirty & ActiveWindow) {
1930 cookies[c++] = xcb_get_property(p->conn,
false, p->root, p->atom(_NET_ACTIVE_WINDOW), XCB_ATOM_WINDOW, 0, 1);
1933 if (dirty & WorkArea) {
1934 cookies[c++] = xcb_get_property(p->conn,
false, p->root, p->atom(_NET_WORKAREA), XCB_ATOM_CARDINAL, 0, MAX_PROP_SIZE);
1937 if (dirty & SupportingWMCheck) {
1938 cookies[c++] = xcb_get_property(p->conn,
false, p->root, p->atom(_NET_SUPPORTING_WM_CHECK), XCB_ATOM_WINDOW, 0, 1);
1941 if (dirty & VirtualRoots) {
1942 cookies[c++] = xcb_get_property(p->conn,
false, p->root, p->atom(_NET_VIRTUAL_ROOTS), XCB_ATOM_WINDOW, 0, 1);
1945 if (dirty2 & WM2DesktopLayout) {
1946 cookies[c++] = xcb_get_property(p->conn,
false, p->root, p->atom(_NET_DESKTOP_LAYOUT), XCB_ATOM_CARDINAL, 0, MAX_PROP_SIZE);
1949 if (dirty2 & WM2ShowingDesktop) {
1950 cookies[c++] = xcb_get_property(p->conn,
false, p->root, p->atom(_NET_SHOWING_DESKTOP), XCB_ATOM_CARDINAL, 0, 1);
1956 if (dirty & Supported) {
1964 const QList<xcb_atom_t> atoms = get_array_reply<xcb_atom_t>(p->conn, cookies[c++], XCB_ATOM_ATOM);
1965 for (
const xcb_atom_t atom : atoms) {
1966 updateSupportedProperties(atom);
1970 if (dirty & ClientList) {
1974 QList<xcb_window_t> clients = get_array_reply<xcb_window_t>(p->conn, cookies[c++], XCB_ATOM_WINDOW);
1975 std::sort(clients.
begin(), clients.
end());
1981 int old_count = p->clients_count;
1982 int new_count = clients.
count();
1984 while (old_index < old_count || new_index < new_count) {
1985 if (old_index == old_count) {
1986 clientsToAdd.
append(clients[new_index++]);
1987 }
else if (new_index == new_count) {
1988 clientsToRemove.
append(p->clients[old_index++]);
1990 if (p->clients[old_index] < clients[new_index]) {
1991 clientsToRemove.
append(p->clients[old_index++]);
1992 }
else if (clients[new_index] < p->clients[old_index]) {
1993 clientsToAdd.
append(clients[new_index++]);
2002 delete[] p->clients;
2003 p->clients =
nullptr;
2006 fprintf(stderr,
"NETRootInfo::update: client list null, creating\n");
2010 for (
int i = 0; i < clients.
count(); i++) {
2011 clientsToAdd.
append(clients[i]);
2016 p->clients_count = clients.
count();
2017 p->clients =
new xcb_window_t[clients.
count()];
2018 for (
int i = 0; i < clients.
count(); i++) {
2019 p->clients[i] = clients.
at(i);
2024 fprintf(stderr,
"NETRootInfo::update: client list updated (%ld clients)\n", p->clients_count);
2027 for (
int i = 0; i < clientsToRemove.
size(); ++i) {
2031 for (
int i = 0; i < clientsToAdd.
size(); ++i) {
2036 if (dirty & ClientListStacking) {
2037 p->stacking_count = 0;
2039 delete[] p->stacking;
2040 p->stacking =
nullptr;
2042 const QList<xcb_window_t> wins = get_array_reply<xcb_window_t>(p->conn, cookies[c++], XCB_ATOM_WINDOW);
2045 p->stacking_count = wins.
count();
2046 p->stacking =
new xcb_window_t[wins.
count()];
2047 for (
int i = 0; i < wins.
count(); i++) {
2048 p->stacking[i] = wins.
at(i);
2053 fprintf(stderr,
"NETRootInfo::update: client stacking updated (%ld clients)\n", p->stacking_count);
2057 if (dirty & NumberOfDesktops) {
2058 p->number_of_desktops = get_value_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL, 0);
2061 fprintf(stderr,
"NETRootInfo::update: number of desktops = %d\n", p->number_of_desktops);
2065 if (dirty & DesktopGeometry) {
2066 p->geometry = p->rootSize;
2068 const QList<uint32_t> data = get_array_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL);
2069 if (data.
count() == 2) {
2070 p->geometry.width = data.
at(0);
2071 p->geometry.height = data.
at(1);
2075 fprintf(stderr,
"NETRootInfo::update: desktop geometry updated\n");
2079 if (dirty & DesktopViewport) {
2080 for (
int i = 0; i < p->viewport.size(); i++) {
2081 p->viewport[i].x = p->viewport[i].y = 0;
2084 const QList<uint32_t> data = get_array_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL);
2086 if (data.
count() >= 2) {
2087 int n = data.
count() / 2;
2088 for (
int d = 0, i = 0; d < n; d++) {
2089 p->viewport[d].x = data[i++];
2090 p->viewport[d].y = data[i++];
2094 fprintf(stderr,
"NETRootInfo::update: desktop viewport array updated (%d entries)\n", p->viewport.size());
2096 if (data.
count() % 2 != 0) {
2098 "NETRootInfo::update(): desktop viewport array "
2099 "size not a multiple of 2\n");
2105 if (dirty & CurrentDesktop) {
2106 p->current_desktop = get_value_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL, 0) + 1;
2109 fprintf(stderr,
"NETRootInfo::update: current desktop = %d\n", p->current_desktop);
2113 if (dirty & DesktopNames) {
2114 for (
int i = 0; i < p->desktop_names.size(); ++i) {
2115 delete[] p->desktop_names[i];
2118 p->desktop_names.reset();
2120 const QList<QByteArray> names = get_stringlist_reply(p->conn, cookies[c++], p->atom(UTF8_STRING));
2121 for (
int i = 0; i < names.
count(); i++) {
2122 p->desktop_names[i] = nstrndup(names[i].constData(), names[i].length());
2126 fprintf(stderr,
"NETRootInfo::update: desktop names array updated (%d entries)\n", p->desktop_names.size());
2130 if (dirty & ActiveWindow) {
2131 p->active = get_value_reply<xcb_window_t>(p->conn, cookies[c++], XCB_ATOM_WINDOW, 0);
2134 fprintf(stderr,
"NETRootInfo::update: active window = 0x%lx\n", p->active);
2138 if (dirty & WorkArea) {
2139 p->workarea.reset();
2141 const QList<uint32_t> data = get_array_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL);
2142 if (data.
count() == p->number_of_desktops * 4) {
2143 for (
int i = 0, j = 0; i < p->number_of_desktops; i++) {
2144 p->workarea[i].pos.x = data[j++];
2145 p->workarea[i].pos.y = data[j++];
2146 p->workarea[i].
size.width = data[j++];
2147 p->workarea[i].
size.height = data[j++];
2152 fprintf(stderr,
"NETRootInfo::update: work area array updated (%d entries)\n", p->workarea.size());
2156 if (dirty & SupportingWMCheck) {
2160 p->supportwindow = get_value_reply<xcb_window_t>(p->conn, cookies[c++], XCB_ATOM_WINDOW, 0);
2164 if (p->supportwindow) {
2165 wm_name_cookie = xcb_get_property(p->conn,
false, p->supportwindow, p->atom(_NET_WM_NAME), p->atom(UTF8_STRING), 0, MAX_PROP_SIZE);
2169 if (dirty & VirtualRoots) {
2170 p->virtual_roots_count = 0;
2172 delete[] p->virtual_roots;
2173 p->virtual_roots =
nullptr;
2175 const QList<xcb_window_t> wins = get_array_reply<xcb_window_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL);
2178 p->virtual_roots_count = wins.
count();
2179 p->virtual_roots =
new xcb_window_t[wins.
count()];
2180 for (
int i = 0; i < wins.
count(); i++) {
2181 p->virtual_roots[i] = wins.
at(i);
2186 fprintf(stderr,
"NETRootInfo::updated: virtual roots updated (%ld windows)\n", p->virtual_roots_count);
2190 if (dirty2 & WM2DesktopLayout) {
2191 p->desktop_layout_orientation = OrientationHorizontal;
2192 p->desktop_layout_corner = DesktopLayoutCornerTopLeft;
2193 p->desktop_layout_columns = p->desktop_layout_rows = 0;
2195 const QList<uint32_t> data = get_array_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL);
2197 if (data.
count() >= 4 && data[3] <= 3) {
2201 if (data.
count() >= 3) {
2206 p->desktop_layout_columns = data[1];
2207 p->desktop_layout_rows = data[2];
2212 "NETRootInfo::updated: desktop layout updated (%d %d %d %d)\n",
2213 p->desktop_layout_orientation,
2214 p->desktop_layout_columns,
2215 p->desktop_layout_rows,
2216 p->desktop_layout_corner);
2220 if (dirty2 & WM2ShowingDesktop) {
2221 const uint32_t val = get_value_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL, 0);
2222 p->showing_desktop = bool(val);
2225 fprintf(stderr,
"NETRootInfo::update: showing desktop = %d\n", p->showing_desktop);
2229 if ((dirty & SupportingWMCheck) && p->supportwindow) {
2230 const QByteArray ba = get_string_reply(p->conn, wm_name_cookie, p->atom(UTF8_STRING));
2236 fprintf(stderr,
"NETRootInfo::update: supporting window manager = '%s'\n", p->name);
2253 return p->supportwindow;
2263 return p->properties;
2268 return p->properties2;
2278 return p->windowTypes;
2288 return p->role ==
WindowManager ? p->properties : p->clientProperties;
2293 return p->role ==
WindowManager ? p->properties2 : p->clientProperties2;
2318 p->properties |= property;
2321 p->properties &= ~property;
2333 p->properties2 |= property;
2336 p->properties2 &= ~property;
2348 p->windowTypes |= property;
2351 p->windowTypes &= ~property;
2363 p->states |= property;
2366 p->states &= ~property;
2378 p->actions |= property;
2381 p->actions &= ~property;
2388 return p->properties & property;
2393 return p->properties2 & property;
2398 return p->windowTypes & type;
2403 return p->states & state;
2408 return p->actions & action;
2418 return p->clients_count;
2428 return p->stacking_count;
2433 return p->geometry.
width != 0 ? p->geometry : p->rootSize;
2443 return p->viewport[desktop - 1];
2453 return p->workarea[desktop - 1];
2462 return p->desktop_names[desktop - 1];
2467 return p->virtual_roots;
2472 return p->virtual_roots_count;
2477 return p->desktop_layout_orientation;
2482 return QSize(p->desktop_layout_columns, p->desktop_layout_rows);
2487 return p->desktop_layout_corner;
2495 return p->number_of_desktops == 0 ? 1 : p->number_of_desktops;
2503 return p->current_desktop == 0 ? 1 : p->current_desktop;
2516 xcb_window_t window,
2517 xcb_window_t rootWindow,
2523 fprintf(stderr,
"NETWinInfo::NETWinInfo: constructing object with role '%s'\n", (role ==
WindowManager) ?
"WindowManager" :
"Client");
2526 p =
new NETWinInfoPrivate;
2528 p->atoms = atomsForConnection(connection);
2530 p->conn = connection;
2532 p->root = rootWindow;
2534 p->mapping_state_dirty =
true;
2537 p->name = (
char *)
nullptr;
2538 p->visible_name = (
char *)
nullptr;
2539 p->icon_name = (
char *)
nullptr;
2540 p->visible_icon_name = (
char *)
nullptr;
2541 p->desktop = p->pid = 0;
2542 p->handled_icons =
false;
2544 p->startup_id =
nullptr;
2545 p->transient_for = XCB_NONE;
2546 p->opacity = 0xffffffffU;
2547 p->window_group = XCB_NONE;
2548 p->icon_pixmap = XCB_PIXMAP_NONE;
2549 p->icon_mask = XCB_PIXMAP_NONE;
2551 p->has_net_support =
false;
2552 p->class_class = (
char *)
nullptr;
2553 p->class_name = (
char *)
nullptr;
2554 p->window_role = (
char *)
nullptr;
2555 p->client_machine = (
char *)
nullptr;
2556 p->icon_sizes =
nullptr;
2557 p->activities = (
char *)
nullptr;
2558 p->desktop_file =
nullptr;
2559 p->gtk_application_id =
nullptr;
2560 p->appmenu_object_path =
nullptr;
2561 p->appmenu_service_name =
nullptr;
2562 p->blockCompositing =
false;
2566 p->protocols = NET::NoProtocol;
2572 p->properties = properties;
2573 p->properties2 = properties2;
2579 update(p->properties, p->properties2);
2602 fprintf(stderr,
"NETWinInfo::operator=()\n");
2605 if (p != wininfo.p) {
2621 setIconInternal(p->icons, p->icon_count, p->atom(_NET_WM_ICON),
icon, replace);
2624void NETWinInfo::setIconInternal(NETRArray<NETIcon> &icons,
int &icon_count, xcb_atom_t property,
NETIcon icon,
bool replace)
2631 for (
int i = 0; i < icons.size(); i++) {
2632 delete[] icons[i].data;
2634 icons[i].data =
nullptr;
2635 icons[i].size.width = 0;
2636 icons[i].size.height = 0;
2643 icons[icon_count] =
icon;
2647 NETIcon &ni = icons[icon_count - 1];
2649 uint32_t *d =
new uint32_t[sz];
2650 ni.
data = (
unsigned char *)d;
2651 memcpy(d,
icon.
data, sz *
sizeof(uint32_t));
2655 for (
int i = 0; i < icon_count; i++) {
2656 proplen += 2 + (icons[i].size.width * icons[i].size.height);
2659 uint32_t *prop =
new uint32_t[proplen];
2660 uint32_t *pprop = prop;
2661 for (
int i = 0; i < icon_count; i++) {
2663 *pprop++ = icons[i].size.width;
2664 *pprop++ = icons[i].size.height;
2667 sz = (icons[i].size.width * icons[i].size.height);
2668 uint32_t *d32 = (uint32_t *)icons[i].data;
2669 for (
int j = 0; j < sz; j++) {
2674 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, property, XCB_ATOM_CARDINAL, 32, proplen, (
const void *)prop);
2677 delete[] p->icon_sizes;
2678 p->icon_sizes =
nullptr;
2687 const qreal scaleFactor = qApp->devicePixelRatio();
2688 geometry.
pos.
x *= scaleFactor;
2689 geometry.
pos.
y *= scaleFactor;
2693 p->icon_geom = geometry;
2696 xcb_delete_property(p->conn, p->window, p->atom(_NET_WM_ICON_GEOMETRY));
2699 data[0] = geometry.
pos.
x;
2700 data[1] = geometry.
pos.
y;
2704 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_ICON_GEOMETRY), XCB_ATOM_CARDINAL, 32, 4, (
const void *)data);
2714 p->extended_strut = extended_strut;
2721 data[4] = extended_strut.left_start;
2722 data[5] = extended_strut.left_end;
2723 data[6] = extended_strut.right_start;
2724 data[7] = extended_strut.right_end;
2725 data[8] = extended_strut.top_start;
2726 data[9] = extended_strut.top_end;
2727 data[10] = extended_strut.bottom_start;
2728 data[11] = extended_strut.bottom_end;
2730 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_STRUT_PARTIAL), XCB_ATOM_CARDINAL, 32, 12, (
const void *)data);
2747 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_STRUT), XCB_ATOM_CARDINAL, 32, 4, (
const void *)data);
2753 const uint32_t data[5] = {uint32_t(topology.
top), uint32_t(topology.
bottom), uint32_t(topology.
left), uint32_t(topology.
right), 1};
2755 send_client_message(p->conn, netwm_sendevent_mask, p->root, p->window, p->atom(_NET_WM_FULLSCREEN_MONITORS), data);
2757 p->fullscreen_monitors = topology;
2760 data[0] = topology.
top;
2761 data[1] = topology.
bottom;
2762 data[2] = topology.
left;
2763 data[3] = topology.
right;
2765 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_FULLSCREEN_MONITORS), XCB_ATOM_CARDINAL, 32, 4, (
const void *)data);
2771 if (p->mapping_state_dirty) {
2776 if ((p->properties & WMState) == 0) {
2777 p->properties |= WMState;
2781 p->properties &= ~WMState;
2786 fprintf(stderr,
"NETWinInfo::setState (0x%lx, 0x%lx) (Client)\n",
state, mask);
2789 KXcbEvent<xcb_client_message_event_t>
event;
2790 event.response_type = XCB_CLIENT_MESSAGE;
2793 event.window = p->window;
2794 event.type = p->atom(_NET_WM_STATE);
2795 event.data.data32[3] = 0;
2796 event.data.data32[4] = 0;
2799 event.data.data32[0] = (
state &
Modal) ? 1 : 0;
2800 event.data.data32[1] = p->atom(_NET_WM_STATE_MODAL);
2801 event.data.data32[2] = 0l;
2803 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask,
event.buffer());
2808 event.data.data32[1] = p->atom(_NET_WM_STATE_STICKY);
2809 event.data.data32[2] = 0l;
2811 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask,
event.buffer());
2814 if ((mask &
Max) && (((p->state & mask) &
Max) != (
state &
Max))) {
2817 if ((wishstate &
Max) ==
Max) {
2818 event.data.data32[0] = 1;
2819 event.data.data32[1] = p->atom(_NET_WM_STATE_MAXIMIZED_HORZ);
2820 event.data.data32[2] = p->atom(_NET_WM_STATE_MAXIMIZED_VERT);
2821 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask,
event.buffer());
2822 }
else if ((wishstate &
Max) == 0) {
2823 event.data.data32[0] = 0;
2824 event.data.data32[1] = p->atom(_NET_WM_STATE_MAXIMIZED_HORZ);
2825 event.data.data32[2] = p->atom(_NET_WM_STATE_MAXIMIZED_VERT);
2826 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask,
event.buffer());
2828 event.data.data32[0] = (wishstate &
MaxHoriz) ? 1 : 0;
2829 event.data.data32[1] = p->atom(_NET_WM_STATE_MAXIMIZED_HORZ);
2830 event.data.data32[2] = 0;
2831 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask,
event.buffer());
2833 event.data.data32[0] = (wishstate &
MaxVert) ? 1 : 0;
2834 event.data.data32[1] = p->atom(_NET_WM_STATE_MAXIMIZED_VERT);
2835 event.data.data32[2] = 0;
2836 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask,
event.buffer());
2839 event.data.data32[0] = (wishstate &
MaxVert) ? 1 : 0;
2840 event.data.data32[1] = p->atom(_NET_WM_STATE_MAXIMIZED_VERT);
2841 event.data.data32[2] = 0;
2843 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask,
event.buffer());
2845 event.data.data32[0] = (wishstate &
MaxHoriz) ? 1 : 0;
2846 event.data.data32[1] = p->atom(_NET_WM_STATE_MAXIMIZED_HORZ);
2847 event.data.data32[2] = 0;
2849 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask,
event.buffer());
2855 event.data.data32[1] = p->atom(_NET_WM_STATE_SHADED);
2856 event.data.data32[2] = 0l;
2858 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask,
event.buffer());
2863 event.data.data32[1] = p->atom(_NET_WM_STATE_SKIP_TASKBAR);
2864 event.data.data32[2] = 0l;
2866 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask,
event.buffer());
2871 event.data.data32[1] = p->atom(_NET_WM_STATE_SKIP_PAGER);
2872 event.data.data32[2] = 0l;
2874 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask,
event.buffer());
2879 event.data.data32[1] = p->atom(_KDE_NET_WM_STATE_SKIP_SWITCHER);
2880 event.data.data32[2] = 0l;
2882 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask,
event.buffer());
2887 event.data.data32[1] = p->atom(_NET_WM_STATE_HIDDEN);
2888 event.data.data32[2] = 0l;
2890 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask,
event.buffer());
2895 event.data.data32[1] = p->atom(_NET_WM_STATE_FULLSCREEN);
2896 event.data.data32[2] = 0l;
2898 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask,
event.buffer());
2903 event.data.data32[1] = p->atom(_NET_WM_STATE_ABOVE);
2904 event.data.data32[2] = 0l;
2906 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask,
event.buffer());
2910 event.data.data32[1] = p->atom(_NET_WM_STATE_STAYS_ON_TOP);
2911 event.data.data32[2] = 0l;
2913 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask,
event.buffer());
2918 event.data.data32[1] = p->atom(_NET_WM_STATE_BELOW);
2919 event.data.data32[2] = 0l;
2921 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask,
event.buffer());
2926 event.data.data32[1] = p->atom(_NET_WM_STATE_DEMANDS_ATTENTION);
2927 event.data.data32[2] = 0l;
2929 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask,
event.buffer());
2941 if (p->state &
Modal) {
2942 data[count++] = p->atom(_NET_WM_STATE_MODAL);
2945 data[count++] = p->atom(_NET_WM_STATE_MAXIMIZED_VERT);
2948 data[count++] = p->atom(_NET_WM_STATE_MAXIMIZED_HORZ);
2951 data[count++] = p->atom(_NET_WM_STATE_SHADED);
2954 data[count++] = p->atom(_NET_WM_STATE_HIDDEN);
2957 data[count++] = p->atom(_NET_WM_STATE_FULLSCREEN);
2960 data[count++] = p->atom(_NET_WM_STATE_DEMANDS_ATTENTION);
2963 data[count++] = p->atom(_NET_WM_STATE_FOCUSED);
2968 data[count++] = p->atom(_NET_WM_STATE_ABOVE);
2970 data[count++] = p->atom(_NET_WM_STATE_STAYS_ON_TOP);
2973 data[count++] = p->atom(_NET_WM_STATE_BELOW);
2976 data[count++] = p->atom(_NET_WM_STATE_STICKY);
2979 data[count++] = p->atom(_NET_WM_STATE_SKIP_TASKBAR);
2982 data[count++] = p->atom(_NET_WM_STATE_SKIP_PAGER);
2985 data[count++] = p->atom(_KDE_NET_WM_STATE_SKIP_SWITCHER);
2989 fprintf(stderr,
"NETWinInfo::setState: setting state property (%d)\n", count);
2990 for (
int i = 0; i < count; i++) {
2991 const QByteArray ba = get_atom_name(p->conn, data[i]);
2992 fprintf(stderr,
"NETWinInfo::setState: state %ld '%s'\n", data[i], ba.
constData());
2996 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_STATE), XCB_ATOM_ATOM, 32, count, (
const void *)data);
3013 data[0] = p->atom(_KDE_NET_WM_WINDOW_TYPE_OVERRIDE);
3014 data[1] = p->atom(_NET_WM_WINDOW_TYPE_NORMAL);
3019 data[0] = p->atom(_NET_WM_WINDOW_TYPE_DIALOG);
3025 data[0] = p->atom(_NET_WM_WINDOW_TYPE_MENU);
3033 data[0] = p->atom(_KDE_NET_WM_WINDOW_TYPE_TOPMENU);
3034 data[1] = p->atom(_NET_WM_WINDOW_TYPE_DOCK);
3039 data[0] = p->atom(_NET_WM_WINDOW_TYPE_TOOLBAR);
3045 data[0] = p->atom(_NET_WM_WINDOW_TYPE_DOCK);
3051 data[0] = p->atom(_NET_WM_WINDOW_TYPE_DESKTOP);
3057 data[0] = p->atom(_NET_WM_WINDOW_TYPE_UTILITY);
3058 data[1] = p->atom(_NET_WM_WINDOW_TYPE_DIALOG);
3063 data[0] = p->atom(_NET_WM_WINDOW_TYPE_SPLASH);
3064 data[1] = p->atom(_NET_WM_WINDOW_TYPE_DOCK);
3069 data[0] = p->atom(_NET_WM_WINDOW_TYPE_DROPDOWN_MENU);
3070 data[1] = p->atom(_NET_WM_WINDOW_TYPE_MENU);
3075 data[0] = p->atom(_NET_WM_WINDOW_TYPE_POPUP_MENU);
3076 data[1] = p->atom(_NET_WM_WINDOW_TYPE_MENU);
3081 data[0] = p->atom(_NET_WM_WINDOW_TYPE_TOOLTIP);
3087 data[0] = p->atom(_NET_WM_WINDOW_TYPE_NOTIFICATION);
3088 data[1] = p->atom(_NET_WM_WINDOW_TYPE_UTILITY);
3093 data[0] = p->atom(_NET_WM_WINDOW_TYPE_COMBO);
3099 data[0] = p->atom(_NET_WM_WINDOW_TYPE_DND);
3105 data[0] = p->atom(_KDE_NET_WM_WINDOW_TYPE_ON_SCREEN_DISPLAY);
3106 data[1] = p->atom(_NET_WM_WINDOW_TYPE_NOTIFICATION);
3111 data[0] = p->atom(_KDE_NET_WM_WINDOW_TYPE_CRITICAL_NOTIFICATION);
3112 data[1] = p->atom(_NET_WM_WINDOW_TYPE_NOTIFICATION);
3117 data[0] = p->atom(_KDE_NET_WM_WINDOW_TYPE_APPLET_POPUP);
3124 data[0] = p->atom(_NET_WM_WINDOW_TYPE_NORMAL);
3130 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_WINDOW_TYPE), XCB_ATOM_ATOM, 32, len, (
const void *)&data);
3140 p->name = nstrdup(
name);
3142 if (p->name[0] !=
'\0') {
3143 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_NAME), p->atom(UTF8_STRING), 8, strlen(p->name), (
const void *)p->name);
3145 xcb_delete_property(p->conn, p->window, p->atom(_NET_WM_NAME));
3155 delete[] p->visible_name;
3158 if (p->visible_name[0] !=
'\0') {
3159 xcb_change_property(p->conn,
3160 XCB_PROP_MODE_REPLACE,
3162 p->atom(_NET_WM_VISIBLE_NAME),
3163 p->atom(UTF8_STRING),
3165 strlen(p->visible_name),
3166 (
const void *)p->visible_name);
3168 xcb_delete_property(p->conn, p->window, p->atom(_NET_WM_VISIBLE_NAME));
3178 delete[] p->icon_name;
3181 if (p->icon_name[0] !=
'\0') {
3182 xcb_change_property(p->conn,
3183 XCB_PROP_MODE_REPLACE,
3185 p->atom(_NET_WM_ICON_NAME),
3186 p->atom(UTF8_STRING),
3188 strlen(p->icon_name),
3189 (
const void *)p->icon_name);
3191 xcb_delete_property(p->conn, p->window, p->atom(_NET_WM_ICON_NAME));
3201 delete[] p->visible_icon_name;
3204 if (p->visible_icon_name[0] !=
'\0') {
3205 xcb_change_property(p->conn,
3206 XCB_PROP_MODE_REPLACE,
3208 p->atom(_NET_WM_VISIBLE_ICON_NAME),
3209 p->atom(UTF8_STRING),
3211 strlen(p->visible_icon_name),
3212 (
const void *)p->visible_icon_name);
3214 xcb_delete_property(p->conn, p->window, p->atom(_NET_WM_VISIBLE_ICON_NAME));
3220 if (p->mapping_state_dirty) {
3238 send_client_message(p->conn, netwm_sendevent_mask, p->root, p->window, p->atom(_NET_WM_DESKTOP), data);
3244 xcb_delete_property(p->conn, p->window, p->atom(_NET_WM_DESKTOP));
3247 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_DESKTOP), XCB_ATOM_CARDINAL, 32, 1, (
const void *)&d);
3260 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_PID), XCB_ATOM_CARDINAL, 32, 1, (
const void *)&d);
3269 p->handled_icons = handled;
3270 uint32_t d = handled;
3271 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_HANDLED_ICONS), XCB_ATOM_CARDINAL, 32, 1, (
const void *)&d);
3280 delete[] p->startup_id;
3281 p->startup_id = nstrdup(
id);
3283 xcb_change_property(p->conn,
3284 XCB_PROP_MODE_REPLACE,
3286 p->atom(_NET_STARTUP_ID),
3287 p->atom(UTF8_STRING),
3289 strlen(p->startup_id),
3290 (
const void *)p->startup_id);
3298 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_WINDOW_OPACITY), XCB_ATOM_CARDINAL, 32, 1, (
const void *)&p->opacity);
3315 p->allowed_actions = actions;
3316 if (p->allowed_actions & ActionMove) {
3317 data[count++] = p->atom(_NET_WM_ACTION_MOVE);
3319 if (p->allowed_actions & ActionResize) {
3320 data[count++] = p->atom(_NET_WM_ACTION_RESIZE);
3322 if (p->allowed_actions & ActionMinimize) {
3323 data[count++] = p->atom(_NET_WM_ACTION_MINIMIZE);
3325 if (p->allowed_actions & ActionShade) {
3326 data[count++] = p->atom(_NET_WM_ACTION_SHADE);
3328 if (p->allowed_actions & ActionStick) {
3329 data[count++] = p->atom(_NET_WM_ACTION_STICK);
3331 if (p->allowed_actions & ActionMaxVert) {
3332 data[count++] = p->atom(_NET_WM_ACTION_MAXIMIZE_VERT);
3334 if (p->allowed_actions & ActionMaxHoriz) {
3335 data[count++] = p->atom(_NET_WM_ACTION_MAXIMIZE_HORZ);
3337 if (p->allowed_actions & ActionFullScreen) {
3338 data[count++] = p->atom(_NET_WM_ACTION_FULLSCREEN);
3340 if (p->allowed_actions & ActionChangeDesktop) {
3341 data[count++] = p->atom(_NET_WM_ACTION_CHANGE_DESKTOP);
3343 if (p->allowed_actions & ActionClose) {
3344 data[count++] = p->atom(_NET_WM_ACTION_CLOSE);
3348 fprintf(stderr,
"NETWinInfo::setAllowedActions: setting property (%d)\n", count);
3349 for (
int i = 0; i < count; i++) {
3350 const QByteArray ba = get_atom_name(p->conn, data[i]);
3351 fprintf(stderr,
"NETWinInfo::setAllowedActions: action %ld '%s'\n", data[i], ba.
constData());
3355 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_ALLOWED_ACTIONS), XCB_ATOM_ATOM, 32, count, (
const void *)data);
3364 p->frame_strut =
strut;
3372 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_FRAME_EXTENTS), XCB_ATOM_CARDINAL, 32, 4, (
const void *)d);
3373 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_KDE_NET_WM_FRAME_STRUT), XCB_ATOM_CARDINAL, 32, 4, (
const void *)d);
3378 return p->frame_strut;
3390 p->frame_overlap =
strut;
3398 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_FRAME_OVERLAP), XCB_ATOM_CARDINAL, 32, 4, (
const void *)d);
3403 return p->frame_overlap;
3408 p->gtk_frame_extents =
strut;
3416 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_GTK_FRAME_EXTENTS), XCB_ATOM_CARDINAL, 32, 4, (
const void *)d);
3421 return p->gtk_frame_extents;
3430 delete[] p->appmenu_object_path;
3431 p->appmenu_object_path = nstrdup(
name);
3433 xcb_change_property(p->conn,
3434 XCB_PROP_MODE_REPLACE,
3436 p->atom(_KDE_NET_WM_APPMENU_OBJECT_PATH),
3439 strlen(p->appmenu_object_path),
3440 (
const void *)p->appmenu_object_path);
3449 delete[] p->appmenu_service_name;
3450 p->appmenu_service_name = nstrdup(
name);
3452 xcb_change_property(p->conn,
3453 XCB_PROP_MODE_REPLACE,
3455 p->atom(_KDE_NET_WM_APPMENU_SERVICE_NAME),
3458 strlen(p->appmenu_service_name),
3459 (
const void *)p->appmenu_service_name);
3464 return p->appmenu_object_path;
3469 return p->appmenu_service_name;
3474 if (p->win_geom.size.width == 0 || p->win_geom.size.height == 0) {
3475 const xcb_get_geometry_cookie_t geometry_cookie = xcb_get_geometry(p->conn, p->window);
3477 const xcb_translate_coordinates_cookie_t translate_cookie = xcb_translate_coordinates(p->conn, p->window, p->root, 0, 0);
3479 xcb_get_geometry_reply_t *geometry = xcb_get_geometry_reply(p->conn, geometry_cookie,
nullptr);
3480 xcb_translate_coordinates_reply_t *translated = xcb_translate_coordinates_reply(p->conn, translate_cookie,
nullptr);
3482 if (geometry && translated) {
3483 p->win_geom.pos.x = translated->dst_x;
3484 p->win_geom.pos.y = translated->dst_y;
3486 p->win_geom.size.width = geometry->width;
3487 p->win_geom.size.height = geometry->height;
3500 window = p->win_geom;
3502 frame.
pos.
x = window.
pos.x - p->frame_strut.left;
3503 frame.
pos.
y = window.
pos.y - p->frame_strut.top;
3504 frame.
size.
width = window.
size.width + p->frame_strut.left + p->frame_strut.right;
3505 frame.
size.
height = window.
size.height + p->frame_strut.top + p->frame_strut.bottom;
3510 return iconInternal(p->icons, p->icon_count, width, height);
3515 if (p->icon_sizes ==
nullptr) {
3516 p->icon_sizes =
new int[p->icon_count * 2 + 2];
3517 for (
int i = 0; i < p->icon_count; ++i) {
3518 p->icon_sizes[i * 2] = p->icons[i].size.width;
3519 p->icon_sizes[i * 2 + 1] = p->icons[i].size.height;
3521 p->icon_sizes[p->icon_count * 2] = 0;
3522 p->icon_sizes[p->icon_count * 2 + 1] = 0;
3524 return p->icon_sizes;
3527NETIcon NETWinInfo::iconInternal(NETRArray<NETIcon> &icons,
int icon_count,
int width,
int height)
const
3534 result.
data =
nullptr;
3540 for (
int i = 1; i < icons.size(); i++) {
3541 if (icons[i].size.width >= result.
size.
width && icons[i].size.height >= result.
size.
height) {
3547 if (width == -1 && height == -1) {
3552 for (
int i = 0; i < icons.size(); i++) {
3553 if ((icons[i].size.width >= width && icons[i].size.width < result.
size.
width)
3554 && (icons[i].size.height >= height && icons[i].size.height < result.
size.
height)) {
3568 p->user_time = time;
3571 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_USER_TIME), XCB_ATOM_CARDINAL, 32, 1, (
const void *)&d);
3577 event(ev, &properties);
3585 bool do_update =
false;
3586 const uint8_t eventType =
event->response_type & ~0x80;
3588 if (p->role ==
WindowManager && eventType == XCB_CLIENT_MESSAGE &&
reinterpret_cast<xcb_client_message_event_t *
>(
event)->format == 32) {
3589 xcb_client_message_event_t *message =
reinterpret_cast<xcb_client_message_event_t *
>(
event);
3591 fprintf(stderr,
"NETWinInfo::event: handling ClientMessage event\n");
3594 if (message->type == p->atom(_NET_WM_STATE)) {
3600 fprintf(stderr,
"NETWinInfo::event: state client message, getting new state/mask\n");
3607 for (i = 1; i < 3; i++) {
3609 const QByteArray ba = get_atom_name(p->conn, (xcb_atom_t)message->data.data32[i]);
3610 fprintf(stderr,
"NETWinInfo::event: message %ld '%s'\n", message->data.data32[i], ba.
constData());
3613 if ((xcb_atom_t)message->data.data32[i] == p->atom(_NET_WM_STATE_MODAL)) {
3615 }
else if ((xcb_atom_t)message->data.data32[i] == p->atom(_NET_WM_STATE_STICKY)) {
3617 }
else if ((xcb_atom_t)message->data.data32[i] == p->atom(_NET_WM_STATE_MAXIMIZED_VERT)) {
3619 }
else if ((xcb_atom_t)message->data.data32[i] == p->atom(_NET_WM_STATE_MAXIMIZED_HORZ)) {
3621 }
else if ((xcb_atom_t)message->data.data32[i] == p->atom(_NET_WM_STATE_SHADED)) {
3623 }
else if ((xcb_atom_t)message->data.data32[i] == p->atom(_NET_WM_STATE_SKIP_TASKBAR)) {
3625 }
else if ((xcb_atom_t)message->data.data32[i] == p->atom(_NET_WM_STATE_SKIP_PAGER)) {
3627 }
else if ((xcb_atom_t)message->data.data32[i] == p->atom(_KDE_NET_WM_STATE_SKIP_SWITCHER)) {
3629 }
else if ((xcb_atom_t)message->data.data32[i] == p->atom(_NET_WM_STATE_HIDDEN)) {
3631 }
else if ((xcb_atom_t)message->data.data32[i] == p->atom(_NET_WM_STATE_FULLSCREEN)) {
3633 }
else if ((xcb_atom_t)message->data.data32[i] == p->atom(_NET_WM_STATE_ABOVE)) {
3635 }
else if ((xcb_atom_t)message->data.data32[i] == p->atom(_NET_WM_STATE_BELOW)) {
3637 }
else if ((xcb_atom_t)message->data.data32[i] == p->atom(_NET_WM_STATE_DEMANDS_ATTENTION)) {
3639 }
else if ((xcb_atom_t)message->data.data32[i] == p->atom(_NET_WM_STATE_STAYS_ON_TOP)) {
3641 }
else if ((xcb_atom_t)message->data.data32[i] == p->atom(_NET_WM_STATE_FOCUSED)) {
3647 switch (message->data.data32[0]) {
3655 state = (p->state & mask) ^ mask;
3664 fprintf(stderr,
"NETWinInfo::event: calling changeState(%lx, %lx)\n",
state, mask);
3668 }
else if (message->type == p->atom(_NET_WM_DESKTOP)) {
3676 }
else if (message->type == p->atom(_NET_WM_FULLSCREEN_MONITORS)) {
3677 dirty2 = WM2FullscreenMonitors;
3680 topology.
top = message->data.data32[0];
3681 topology.
bottom = message->data.data32[1];
3682 topology.
left = message->data.data32[2];
3683 topology.
right = message->data.data32[3];
3687 "NETWinInfo2::event: calling changeFullscreenMonitors"
3688 "(%ld, %ld, %ld, %ld, %ld)\n",
3690 message->data.data32[0],
3691 message->data.data32[1],
3692 message->data.data32[2],
3693 message->data.data32[3]);
3699 if (eventType == XCB_PROPERTY_NOTIFY) {
3701 fprintf(stderr,
"NETWinInfo::event: handling PropertyNotify event\n");
3704 xcb_property_notify_event_t *pe =
reinterpret_cast<xcb_property_notify_event_t *
>(
event);
3706 if (pe->atom == p->atom(_NET_WM_NAME)) {
3708 }
else if (pe->atom == p->atom(_NET_WM_VISIBLE_NAME)) {
3709 dirty |= WMVisibleName;
3710 }
else if (pe->atom == p->atom(_NET_WM_DESKTOP)) {
3712 }
else if (pe->atom == p->atom(_NET_WM_WINDOW_TYPE)) {
3713 dirty |= WMWindowType;
3714 }
else if (pe->atom == p->atom(_NET_WM_STATE)) {
3716 }
else if (pe->atom == p->atom(_NET_WM_STRUT)) {
3718 }
else if (pe->atom == p->atom(_NET_WM_STRUT_PARTIAL)) {
3719 dirty2 |= WM2ExtendedStrut;
3720 }
else if (pe->atom == p->atom(_NET_WM_ICON_GEOMETRY)) {
3721 dirty |= WMIconGeometry;
3722 }
else if (pe->atom == p->atom(_NET_WM_ICON)) {
3724 }
else if (pe->atom == p->atom(_NET_WM_PID)) {
3726 }
else if (pe->atom == p->atom(_NET_WM_HANDLED_ICONS)) {
3727 dirty |= WMHandledIcons;
3728 }
else if (pe->atom == p->atom(_NET_STARTUP_ID)) {
3729 dirty2 |= WM2StartupId;
3730 }
else if (pe->atom == p->atom(_NET_WM_WINDOW_OPACITY)) {
3731 dirty2 |= WM2Opacity;
3732 }
else if (pe->atom == p->atom(_NET_WM_ALLOWED_ACTIONS)) {
3733 dirty2 |= WM2AllowedActions;
3734 }
else if (pe->atom == p->atom(WM_STATE)) {
3736 }
else if (pe->atom == p->atom(_NET_FRAME_EXTENTS)) {
3737 dirty |= WMFrameExtents;
3738 }
else if (pe->atom == p->atom(_KDE_NET_WM_FRAME_STRUT)) {
3739 dirty |= WMFrameExtents;
3740 }
else if (pe->atom == p->atom(_NET_WM_FRAME_OVERLAP)) {
3741 dirty2 |= WM2FrameOverlap;
3742 }
else if (pe->atom == p->atom(_NET_WM_ICON_NAME)) {
3743 dirty |= WMIconName;
3744 }
else if (pe->atom == p->atom(_NET_WM_VISIBLE_ICON_NAME)) {
3745 dirty |= WMVisibleIconName;
3746 }
else if (pe->atom == p->atom(_NET_WM_USER_TIME)) {
3747 dirty2 |= WM2UserTime;
3748 }
else if (pe->atom == XCB_ATOM_WM_HINTS) {
3749 dirty2 |= WM2GroupLeader;
3750 dirty2 |= WM2Urgency;
3752 dirty2 |= WM2InitialMappingState;
3753 dirty2 |= WM2IconPixmap;
3754 }
else if (pe->atom == XCB_ATOM_WM_TRANSIENT_FOR) {
3755 dirty2 |= WM2TransientFor;
3756 }
else if (pe->atom == XCB_ATOM_WM_CLASS) {
3757 dirty2 |= WM2WindowClass;
3758 }
else if (pe->atom == p->atom(WM_WINDOW_ROLE)) {
3759 dirty2 |= WM2WindowRole;
3760 }
else if (pe->atom == XCB_ATOM_WM_CLIENT_MACHINE) {
3761 dirty2 |= WM2ClientMachine;
3762 }
else if (pe->atom == p->atom(_KDE_NET_WM_ACTIVITIES)) {
3763 dirty2 |= WM2Activities;
3764 }
else if (pe->atom == p->atom(_KDE_NET_WM_BLOCK_COMPOSITING) || pe->atom == p->atom(_NET_WM_BYPASS_COMPOSITOR)) {
3765 dirty2 |= WM2BlockCompositing;
3766 }
else if (pe->atom == p->atom(_KDE_NET_WM_SHADOW)) {
3767 dirty2 |= WM2KDEShadow;
3768 }
else if (pe->atom == p->atom(WM_PROTOCOLS)) {
3769 dirty2 |= WM2Protocols;
3770 }
else if (pe->atom == p->atom(_NET_WM_OPAQUE_REGION)) {
3771 dirty2 |= WM2OpaqueRegion;
3772 }
else if (pe->atom == p->atom(_KDE_NET_WM_DESKTOP_FILE)) {
3773 dirty2 = WM2DesktopFileName;
3774 }
else if (pe->atom == p->atom(_GTK_APPLICATION_ID)) {
3775 dirty2 = WM2GTKApplicationId;
3776 }
else if (pe->atom == p->atom(_NET_WM_FULLSCREEN_MONITORS)) {
3777 dirty2 = WM2FullscreenMonitors;
3778 }
else if (pe->atom == p->atom(_GTK_FRAME_EXTENTS)) {
3779 dirty2 |= WM2GTKFrameExtents;
3780 }
else if (pe->atom == p->atom(_GTK_SHOW_WINDOW_MENU)) {
3781 dirty2 |= WM2GTKShowWindowMenu;
3782 }
else if (pe->atom == p->atom(_KDE_NET_WM_APPMENU_SERVICE_NAME)) {
3783 dirty2 |= WM2AppMenuServiceName;
3784 }
else if (pe->atom == p->atom(_KDE_NET_WM_APPMENU_OBJECT_PATH)) {
3785 dirty2 |= WM2AppMenuObjectPath;
3789 }
else if (eventType == XCB_CONFIGURE_NOTIFY) {
3791 fprintf(stderr,
"NETWinInfo::event: handling ConfigureNotify event\n");
3794 dirty |= WMGeometry;
3797 xcb_configure_notify_event_t *configure =
reinterpret_cast<xcb_configure_notify_event_t *
>(
event);
3798 p->win_geom.pos.x = configure->x;
3799 p->win_geom.pos.y = configure->y;
3800 p->win_geom.size.width = configure->width;
3801 p->win_geom.size.height = configure->height;
3805 update(dirty, dirty2);
3809 *properties = dirty;
3812 *properties2 = dirty2;
3816void NETWinInfo::updateWMState()
3823 Properties dirty = dirtyProperties & p->properties;
3824 Properties2 dirty2 = dirtyProperties2 & p->properties2;
3827 if (dirtyProperties & XAWMState) {
3831 xcb_get_property_cookie_t cookies[255];
3834 if (dirty & XAWMState) {
3835 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(WM_STATE), p->atom(WM_STATE), 0, 1);
3838 if (dirty & WMState) {
3839 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_STATE), XCB_ATOM_ATOM, 0, 2048);
3842 if (dirty & WMDesktop) {
3843 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_DESKTOP), XCB_ATOM_CARDINAL, 0, 1);
3846 if (dirty & WMName) {
3847 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_NAME), p->atom(UTF8_STRING), 0, MAX_PROP_SIZE);
3850 if (dirty & WMVisibleName) {
3851 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_VISIBLE_NAME), p->atom(UTF8_STRING), 0, MAX_PROP_SIZE);
3854 if (dirty & WMIconName) {
3855 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_ICON_NAME), p->atom(UTF8_STRING), 0, MAX_PROP_SIZE);
3858 if (dirty & WMVisibleIconName) {
3859 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_VISIBLE_ICON_NAME), p->atom(UTF8_STRING), 0, MAX_PROP_SIZE);
3862 if (dirty & WMWindowType) {
3863 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_WINDOW_TYPE), XCB_ATOM_ATOM, 0, 2048);
3866 if (dirty & WMStrut) {
3867 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_STRUT), XCB_ATOM_CARDINAL, 0, 4);
3870 if (dirty2 & WM2ExtendedStrut) {
3871 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_STRUT_PARTIAL), XCB_ATOM_CARDINAL, 0, 12);
3874 if (dirty2 & WM2FullscreenMonitors) {
3875 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_FULLSCREEN_MONITORS), XCB_ATOM_CARDINAL, 0, 4);
3878 if (dirty & WMIconGeometry) {
3879 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_ICON_GEOMETRY), XCB_ATOM_CARDINAL, 0, 4);
3882 if (dirty & WMIcon) {
3883 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_ICON), XCB_ATOM_CARDINAL, 0, 0xffffffff);
3886 if (dirty & WMFrameExtents) {
3887 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_FRAME_EXTENTS), XCB_ATOM_CARDINAL, 0, 4);
3888 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_KDE_NET_WM_FRAME_STRUT), XCB_ATOM_CARDINAL, 0, 4);
3891 if (dirty2 & WM2FrameOverlap) {
3892 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_FRAME_OVERLAP), XCB_ATOM_CARDINAL, 0, 4);
3895 if (dirty2 & WM2Activities) {
3896 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_KDE_NET_WM_ACTIVITIES), XCB_ATOM_STRING, 0, MAX_PROP_SIZE);
3899 if (dirty2 & WM2BlockCompositing) {
3900 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_KDE_NET_WM_BLOCK_COMPOSITING), XCB_ATOM_CARDINAL, 0, 1);
3901 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_BYPASS_COMPOSITOR), XCB_ATOM_CARDINAL, 0, 1);
3904 if (dirty & WMPid) {
3905 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_PID), XCB_ATOM_CARDINAL, 0, 1);
3908 if (dirty2 & WM2StartupId) {
3909 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_STARTUP_ID), p->atom(UTF8_STRING), 0, MAX_PROP_SIZE);
3912 if (dirty2 & WM2Opacity) {
3913 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_WINDOW_OPACITY), XCB_ATOM_CARDINAL, 0, 1);
3916 if (dirty2 & WM2AllowedActions) {
3917 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_ALLOWED_ACTIONS), XCB_ATOM_ATOM, 0, 2048);
3920 if (dirty2 & WM2UserTime) {
3921 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_USER_TIME), XCB_ATOM_CARDINAL, 0, 1);
3924 if (dirty2 & WM2TransientFor) {
3925 cookies[c++] = xcb_get_property(p->conn,
false, p->window, XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 0, 1);
3928 if (dirty2 & (WM2GroupLeader | WM2Urgency | WM2Input | WM2InitialMappingState | WM2IconPixmap)) {
3929 cookies[c++] = xcb_get_property(p->conn,
false, p->window, XCB_ATOM_WM_HINTS, XCB_ATOM_WM_HINTS, 0, 9);
3932 if (dirty2 & WM2WindowClass) {
3933 cookies[c++] = xcb_get_property(p->conn,
false, p->window, XCB_ATOM_WM_CLASS, XCB_ATOM_STRING, 0, MAX_PROP_SIZE);
3936 if (dirty2 & WM2WindowRole) {
3937 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(WM_WINDOW_ROLE), XCB_ATOM_STRING, 0, MAX_PROP_SIZE);
3940 if (dirty2 & WM2ClientMachine) {
3941 cookies[c++] = xcb_get_property(p->conn,
false, p->window, XCB_ATOM_WM_CLIENT_MACHINE, XCB_ATOM_STRING, 0, MAX_PROP_SIZE);
3944 if (dirty2 & WM2Protocols) {
3945 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(WM_PROTOCOLS), XCB_ATOM_ATOM, 0, 2048);
3948 if (dirty2 & WM2OpaqueRegion) {
3949 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_OPAQUE_REGION), XCB_ATOM_CARDINAL, 0, MAX_PROP_SIZE);
3952 if (dirty2 & WM2DesktopFileName) {
3953 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_KDE_NET_WM_DESKTOP_FILE), p->atom(UTF8_STRING), 0, MAX_PROP_SIZE);
3956 if (dirty2 & WM2GTKApplicationId) {
3957 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_GTK_APPLICATION_ID), p->atom(UTF8_STRING), 0, MAX_PROP_SIZE);
3960 if (dirty2 & WM2GTKFrameExtents) {
3961 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_GTK_FRAME_EXTENTS), XCB_ATOM_CARDINAL, 0, 4);
3964 if (dirty2 & WM2AppMenuObjectPath) {
3965 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_KDE_NET_WM_APPMENU_OBJECT_PATH), XCB_ATOM_STRING, 0, MAX_PROP_SIZE);
3968 if (dirty2 & WM2AppMenuServiceName) {
3969 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_KDE_NET_WM_APPMENU_SERVICE_NAME), XCB_ATOM_STRING, 0, MAX_PROP_SIZE);
3974 if (dirty & XAWMState) {
3978 uint32_t
state = get_value_reply<uint32_t>(p->conn, cookies[c++], p->atom(WM_STATE), 0, &success);
3983 p->mapping_state =
Iconic;
3996 p->mapping_state_dirty =
false;
4000 if (dirty & WMState) {
4002 const QList<xcb_atom_t> states = get_array_reply<xcb_atom_t>(p->conn, cookies[c++], XCB_ATOM_ATOM);
4005 fprintf(stderr,
"NETWinInfo::update: updating window state (%ld)\n", states.
count());
4008 for (
const xcb_atom_t
state : states) {
4011 fprintf(stderr,
"NETWinInfo::update: adding window state %ld '%s'\n",
state, ba.
constData());
4013 if (
state == p->atom(_NET_WM_STATE_MODAL)) {
4017 else if (
state == p->atom(_NET_WM_STATE_STICKY)) {
4021 else if (
state == p->atom(_NET_WM_STATE_MAXIMIZED_VERT)) {
4025 else if (
state == p->atom(_NET_WM_STATE_MAXIMIZED_HORZ)) {
4029 else if (
state == p->atom(_NET_WM_STATE_SHADED)) {
4033 else if (
state == p->atom(_NET_WM_STATE_SKIP_TASKBAR)) {
4037 else if (
state == p->atom(_NET_WM_STATE_SKIP_PAGER)) {
4041 else if (
state == p->atom(_KDE_NET_WM_STATE_SKIP_SWITCHER)) {
4045 else if (
state == p->atom(_NET_WM_STATE_HIDDEN)) {
4049 else if (
state == p->atom(_NET_WM_STATE_FULLSCREEN)) {
4053 else if (
state == p->atom(_NET_WM_STATE_ABOVE)) {
4057 else if (
state == p->atom(_NET_WM_STATE_BELOW)) {
4061 else if (
state == p->atom(_NET_WM_STATE_DEMANDS_ATTENTION)) {
4065 else if (
state == p->atom(_NET_WM_STATE_STAYS_ON_TOP)) {
4069 else if (
state == p->atom(_NET_WM_STATE_FOCUSED)) {
4075 if (dirty & WMDesktop) {
4079 uint32_t
desktop = get_value_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL, 0, &success);
4090 if (dirty & WMName) {
4094 const QByteArray str = get_string_reply(p->conn, cookies[c++], p->atom(UTF8_STRING));
4100 if (dirty & WMVisibleName) {
4101 delete[] p->visible_name;
4102 p->visible_name =
nullptr;
4104 const QByteArray str = get_string_reply(p->conn, cookies[c++], p->atom(UTF8_STRING));
4110 if (dirty & WMIconName) {
4111 delete[] p->icon_name;
4112 p->icon_name =
nullptr;
4114 const QByteArray str = get_string_reply(p->conn, cookies[c++], p->atom(UTF8_STRING));
4120 if (dirty & WMVisibleIconName) {
4121 delete[] p->visible_icon_name;
4122 p->visible_icon_name =
nullptr;
4124 const QByteArray str = get_string_reply(p->conn, cookies[c++], p->atom(UTF8_STRING));
4130 if (dirty & WMWindowType) {
4133 p->has_net_support =
false;
4135 const QList<xcb_atom_t> types = get_array_reply<xcb_atom_t>(p->conn, cookies[c++], XCB_ATOM_ATOM);
4139 fprintf(stderr,
"NETWinInfo::update: getting window type (%ld)\n", types.
count());
4141 p->has_net_support =
true;
4144 for (
const xcb_atom_t type : types) {
4147 fprintf(stderr,
"NETWinInfo::update: examining window type %ld %s\n", type,
name.constData());
4149 if (type == p->atom(_NET_WM_WINDOW_TYPE_NORMAL)) {
4150 p->types[pos++] =
Normal;
4153 else if (type == p->atom(_NET_WM_WINDOW_TYPE_DESKTOP)) {
4157 else if (type == p->atom(_NET_WM_WINDOW_TYPE_DOCK)) {
4158 p->types[pos++] =
Dock;
4161 else if (type == p->atom(_NET_WM_WINDOW_TYPE_TOOLBAR)) {
4165 else if (type == p->atom(_NET_WM_WINDOW_TYPE_MENU)) {
4166 p->types[pos++] =
Menu;
4169 else if (type == p->atom(_NET_WM_WINDOW_TYPE_DIALOG)) {
4170 p->types[pos++] =
Dialog;
4173 else if (type == p->atom(_NET_WM_WINDOW_TYPE_UTILITY)) {
4177 else if (type == p->atom(_NET_WM_WINDOW_TYPE_SPLASH)) {
4178 p->types[pos++] =
Splash;
4181 else if (type == p->atom(_NET_WM_WINDOW_TYPE_DROPDOWN_MENU)) {
4185 else if (type == p->atom(_NET_WM_WINDOW_TYPE_POPUP_MENU)) {
4189 else if (type == p->atom(_NET_WM_WINDOW_TYPE_TOOLTIP)) {
4193 else if (type == p->atom(_NET_WM_WINDOW_TYPE_NOTIFICATION)) {
4197 else if (type == p->atom(_NET_WM_WINDOW_TYPE_COMBO)) {
4201 else if (type == p->atom(_NET_WM_WINDOW_TYPE_DND)) {
4205 else if (type == p->atom(_KDE_NET_WM_WINDOW_TYPE_OVERRIDE)) {
4209 else if (type == p->atom(_KDE_NET_WM_WINDOW_TYPE_TOPMENU)) {
4213 else if (type == p->atom(_KDE_NET_WM_WINDOW_TYPE_ON_SCREEN_DISPLAY)) {
4217 else if (type == p->atom(_KDE_NET_WM_WINDOW_TYPE_CRITICAL_NOTIFICATION)) {
4221 else if (type == p->atom(_KDE_NET_WM_WINDOW_TYPE_APPLET_POPUP)) {
4228 if (dirty & WMStrut) {
4231 QList<uint32_t> data = get_array_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL);
4232 if (data.
count() == 4) {
4233 p->strut.left = data[0];
4234 p->strut.right = data[1];
4235 p->strut.top = data[2];
4236 p->strut.bottom = data[3];
4240 if (dirty2 & WM2ExtendedStrut) {
4243 QList<uint32_t> data = get_array_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL);
4244 if (data.
count() == 12) {
4245 p->extended_strut.left_width = data[0];
4246 p->extended_strut.right_width = data[1];
4247 p->extended_strut.top_width = data[2];
4248 p->extended_strut.bottom_width = data[3];
4249 p->extended_strut.left_start = data[4];
4250 p->extended_strut.left_end = data[5];
4251 p->extended_strut.right_start = data[6];
4252 p->extended_strut.right_end = data[7];
4253 p->extended_strut.top_start = data[8];
4254 p->extended_strut.top_end = data[9];
4255 p->extended_strut.bottom_start = data[10];
4256 p->extended_strut.bottom_end = data[11];
4260 if (dirty2 & WM2FullscreenMonitors) {
4263 QList<uint32_t> data = get_array_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL);
4264 if (data.
count() == 4) {
4265 p->fullscreen_monitors.top = data[0];
4266 p->fullscreen_monitors.bottom = data[1];
4267 p->fullscreen_monitors.left = data[2];
4268 p->fullscreen_monitors.right = data[3];
4272 if (dirty & WMIconGeometry) {
4275 QList<uint32_t> data = get_array_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL);
4276 if (data.
count() == 4) {
4277 p->icon_geom.pos.x = data[0];
4278 p->icon_geom.pos.y = data[1];
4279 p->icon_geom.
size.width = data[2];
4280 p->icon_geom.
size.height = data[3];
4284 if (dirty & WMIcon) {
4285 readIcon(p->conn, cookies[c++], p->icons, p->icon_count);
4286 delete[] p->icon_sizes;
4287 p->icon_sizes =
nullptr;
4290 if (dirty & WMFrameExtents) {
4293 QList<uint32_t> data = get_array_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL);
4296 data = get_array_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL);
4298 xcb_discard_reply(p->conn, cookies[c++].sequence);
4301 if (data.
count() == 4) {
4302 p->frame_strut.left = data[0];
4303 p->frame_strut.right = data[1];
4304 p->frame_strut.top = data[2];
4305 p->frame_strut.bottom = data[3];
4309 if (dirty2 & WM2FrameOverlap) {
4312 QList<uint32_t> data = get_array_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL);
4313 if (data.
count() == 4) {
4314 p->frame_overlap.left = data[0];
4315 p->frame_overlap.right = data[1];
4316 p->frame_overlap.top = data[2];
4317 p->frame_overlap.bottom = data[3];
4321 if (dirty2 & WM2Activities) {
4322 delete[] p->activities;
4323 p->activities =
nullptr;
4331 if (dirty2 & WM2BlockCompositing) {
4333 p->blockCompositing =
false;
4336 uint32_t data = get_value_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL, 0, &success);
4338 p->blockCompositing = bool(data);
4342 data = get_value_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL, 0, &success);
4346 p->blockCompositing =
true;
4349 p->blockCompositing =
false;
4357 if (dirty & WMPid) {
4358 p->pid = get_value_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL, 0);
4361 if (dirty2 & WM2StartupId) {
4362 delete[] p->startup_id;
4363 p->startup_id =
nullptr;
4365 const QByteArray id = get_string_reply(p->conn, cookies[c++], p->atom(UTF8_STRING));
4366 if (
id.length() > 0) {
4367 p->startup_id = nstrndup(
id.constData(),
id.length());
4371 if (dirty2 & WM2Opacity) {
4372 p->opacity = get_value_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL, 0xffffffff);
4375 if (dirty2 & WM2AllowedActions) {
4378 const QList<xcb_atom_t> actions = get_array_reply<xcb_atom_t>(p->conn, cookies[c++], XCB_ATOM_ATOM);
4381 fprintf(stderr,
"NETWinInfo::update: updating allowed actions (%ld)\n", actions.
count());
4384 for (
const xcb_atom_t action : actions) {
4387 fprintf(stderr,
"NETWinInfo::update: adding allowed action %ld '%s'\n", action,
name.constData());
4389 if (action == p->atom(_NET_WM_ACTION_MOVE)) {
4390 p->allowed_actions |= ActionMove;
4393 else if (action == p->atom(_NET_WM_ACTION_RESIZE)) {
4394 p->allowed_actions |= ActionResize;
4397 else if (action == p->atom(_NET_WM_ACTION_MINIMIZE)) {
4398 p->allowed_actions |= ActionMinimize;
4401 else if (action == p->atom(_NET_WM_ACTION_SHADE)) {
4402 p->allowed_actions |= ActionShade;
4405 else if (action == p->atom(_NET_WM_ACTION_STICK)) {
4406 p->allowed_actions |= ActionStick;
4409 else if (action == p->atom(_NET_WM_ACTION_MAXIMIZE_VERT)) {
4410 p->allowed_actions |= ActionMaxVert;
4413 else if (action == p->atom(_NET_WM_ACTION_MAXIMIZE_HORZ)) {
4414 p->allowed_actions |= ActionMaxHoriz;
4417 else if (action == p->atom(_NET_WM_ACTION_FULLSCREEN)) {
4418 p->allowed_actions |= ActionFullScreen;
4421 else if (action == p->atom(_NET_WM_ACTION_CHANGE_DESKTOP)) {
4422 p->allowed_actions |= ActionChangeDesktop;
4425 else if (action == p->atom(_NET_WM_ACTION_CLOSE)) {
4426 p->allowed_actions |= ActionClose;
4432 if (dirty2 & WM2UserTime) {
4436 uint32_t value = get_value_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL, 0, &success);
4439 p->user_time = value;
4443 if (dirty2 & WM2TransientFor) {
4444 p->transient_for = get_value_reply<xcb_window_t>(p->conn, cookies[c++], XCB_ATOM_WINDOW, 0);
4447 if (dirty2 & (WM2GroupLeader | WM2Urgency | WM2Input | WM2InitialMappingState | WM2IconPixmap)) {
4448 xcb_get_property_reply_t *reply = xcb_get_property_reply(p->conn, cookies[c++],
nullptr);
4450 if (reply && reply->format == 32 && reply->value_len == 9 && reply->type == XCB_ATOM_WM_HINTS) {
4451 kde_wm_hints *hints =
reinterpret_cast<kde_wm_hints *
>(xcb_get_property_value(reply));
4453 if (hints->flags & (1 << 0) ) {
4454 p->input = hints->input;
4456 if (hints->flags & (1 << 1) ) {
4457 switch (hints->initial_state) {
4459 p->initialMappingState =
Iconic;
4463 p->initialMappingState =
Visible;
4472 if (hints->flags & (1 << 2) ) {
4473 p->icon_pixmap = hints->icon_pixmap;
4475 if (hints->flags & (1 << 5) ) {
4476 p->icon_mask = hints->icon_mask;
4478 if (hints->flags & (1 << 6) ) {
4479 p->window_group = hints->window_group;
4481 p->urgency = (hints->flags & (1 << 8) );
4489 if (dirty2 & WM2WindowClass) {
4490 delete[] p->class_name;
4491 delete[] p->class_class;
4492 p->class_name =
nullptr;
4493 p->class_class =
nullptr;
4497 p->class_name = nstrdup(
list.
at(0).constData());
4498 p->class_class = nstrdup(
list.
at(1).constData());
4500 p->class_name = nstrdup(
list.
at(0).constData());
4501 p->class_class = nstrdup(
list.
at(0).constData());
4505 if (dirty2 & WM2WindowRole) {
4506 delete[] p->window_role;
4507 p->window_role =
nullptr;
4509 const QByteArray role = get_string_reply(p->conn, cookies[c++], XCB_ATOM_STRING);
4515 if (dirty2 & WM2ClientMachine) {
4516 delete[] p->client_machine;
4517 p->client_machine =
nullptr;
4519 const QByteArray value = get_string_reply(p->conn, cookies[c++], XCB_ATOM_STRING);
4520 if (value.
length() > 0) {
4525 if (dirty2 & WM2Protocols) {
4527 p->protocols = NET::NoProtocol;
4529 if ((*it) == p->atom(WM_TAKE_FOCUS)) {
4531 }
else if ((*it) == p->atom(WM_DELETE_WINDOW)) {
4533 }
else if ((*it) == p->atom(_NET_WM_PING)) {
4535 }
else if ((*it) == p->atom(_NET_WM_SYNC_REQUEST)) {
4537 }
else if ((*it) == p->atom(_NET_WM_CONTEXT_HELP)) {
4543 if (dirty2 & WM2OpaqueRegion) {
4544 const QList<qint32> values = get_array_reply<qint32>(p->conn, cookies[c++], XCB_ATOM_CARDINAL);
4545 p->opaqueRegion.clear();
4546 p->opaqueRegion.reserve(values.
count() / 4);
4547 for (
int i = 0; i < values.
count() - 3; i += 4) {
4549 rect.
pos.
x = values.
at(i);
4550 rect.
pos.
y = values.
at(i + 1);
4553 p->opaqueRegion.push_back(rect);
4557 if (dirty2 & WM2DesktopFileName) {
4558 delete[] p->desktop_file;
4559 p->desktop_file =
nullptr;
4561 const QByteArray id = get_string_reply(p->conn, cookies[c++], p->atom(UTF8_STRING));
4562 if (
id.length() > 0) {
4563 p->desktop_file = nstrndup(
id.constData(),
id.length());
4567 if (dirty2 & WM2GTKApplicationId) {
4568 delete[] p->gtk_application_id;
4569 p->gtk_application_id =
nullptr;
4571 const QByteArray id = get_string_reply(p->conn, cookies[c++], p->atom(UTF8_STRING));
4572 if (
id.length() > 0) {
4573 p->gtk_application_id = nstrndup(
id.constData(),
id.length());
4577 if (dirty2 & WM2GTKFrameExtents) {
4580 QList<uint32_t> data = get_array_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL);
4581 if (data.
count() == 4) {
4582 p->gtk_frame_extents.left = data[0];
4583 p->gtk_frame_extents.right = data[1];
4584 p->gtk_frame_extents.top = data[2];
4585 p->gtk_frame_extents.bottom = data[3];
4589 if (dirty2 & WM2AppMenuObjectPath) {
4590 delete[] p->appmenu_object_path;
4591 p->appmenu_object_path =
nullptr;
4593 const QByteArray id = get_string_reply(p->conn, cookies[c++], XCB_ATOM_STRING);
4594 if (
id.length() > 0) {
4595 p->appmenu_object_path = nstrndup(
id.constData(),
id.length());
4599 if (dirty2 & WM2AppMenuServiceName) {
4600 delete[] p->appmenu_service_name;
4601 p->appmenu_service_name =
nullptr;
4603 const QByteArray id = get_string_reply(p->conn, cookies[c++], XCB_ATOM_STRING);
4604 if (
id.length() > 0) {
4605 p->appmenu_service_name = nstrndup(
id.constData(),
id.length());
4612 return p->icon_geom;
4627 return p->extended_strut;
4632 return p->fullscreen_monitors;
4639#define CHECK_TYPE_MASK( type ) \
4641 if( mask & type##Mask ) \
4647 CHECK_TYPE_MASK(
Dock)
4649 CHECK_TYPE_MASK(
Menu)
4664#undef CHECK_TYPE_MASK
4673 for (
int i = 0; i < p->types.size(); ++i) {
4684 return p->types.size() > 0;
4694 return p->visible_name;
4699 return p->icon_name;
4704 return p->visible_icon_name;
4710 const KWindowInfo info(p->window, NET::WMDesktop);
4723 return p->user_time;
4728 return p->startup_id;
4738 if (p->opacity == 0xffffffff) {
4741 return p->opacity * 1.0 / 0xffffffff;
4746 return p->allowed_actions;
4751 return p->has_net_support;
4756 return p->transient_for;
4761 return p->window_group;
4776 return p->initialMappingState;
4781 return p->icon_pixmap;
4786 return p->icon_mask;
4791 return p->class_class;
4796 return p->class_name;
4801 return p->window_role;
4806 return p->client_machine;
4811 return p->activities;
4816 delete[] p->activities;
4820 static const char nulluuid[] = KDE_ALL_ACTIVITIES_UUID;
4822 p->activities = nstrdup(nulluuid);
4828 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_KDE_NET_WM_ACTIVITIES), XCB_ATOM_STRING, 8, strlen(p->activities), p->activities);
4837 p->blockCompositing = active;
4840 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_KDE_NET_WM_BLOCK_COMPOSITING), XCB_ATOM_CARDINAL, 32, 1, (
const void *)&d);
4841 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_BYPASS_COMPOSITOR), XCB_ATOM_CARDINAL, 32, 1, (
const void *)&d);
4843 xcb_delete_property(p->conn, p->window, p->atom(_KDE_NET_WM_BLOCK_COMPOSITING));
4844 xcb_delete_property(p->conn, p->window, p->atom(_NET_WM_BYPASS_COMPOSITOR));
4850 return p->blockCompositing;
4855 return p->handled_icons;
4860 return p->properties;
4865 return p->properties2;
4870 return p->mapping_state;
4875 return p->protocols;
4880 return p->protocols.testFlag(protocol);
4885 return p->opaqueRegion;
4899 delete[] p->desktop_file;
4900 p->desktop_file = nstrdup(
name);
4902 xcb_change_property(p->conn,
4903 XCB_PROP_MODE_REPLACE,
4905 p->atom(_KDE_NET_WM_DESKTOP_FILE),
4906 p->atom(UTF8_STRING),
4908 strlen(p->desktop_file),
4909 (
const void *)p->desktop_file);
4914 return p->desktop_file;
4919 return p->gtk_application_id;
4934 return KXUtils::timestampCompare(time1, time2);
4939 return KXUtils::timestampDiff(time1, time2);
This class provides information about a given X11 window.
int desktop() const
Returns the virtual desktop this window is on.
Common API for root window properties/protocols.
virtual void closeWindow(xcb_window_t window)
A Window Manager should subclass NETRootInfo and reimplement this function when it wants to know when...
virtual void changeDesktopViewport(int desktop, const NETPoint &viewport)
A Window Manager should subclass NETRootInfo and reimplement this function when it wants to know when...
void setClientList(const xcb_window_t *windows, unsigned int count)
Sets the list of managed windows on the Root/Desktop window.
int clientListCount() const
Returns the number of managed windows in clientList array.
void setDesktopLayout(NET::Orientation orientation, int columns, int rows, NET::DesktopLayoutCorner corner)
Sets the desktop layout.
virtual void addClient(xcb_window_t window)
A Client should subclass NETRootInfo and reimplement this function when it wants to know when a windo...
NET::States passedStates() const
NET::Orientation desktopLayoutOrientation() const
Returns the desktop layout orientation.
virtual void moveResizeWindow(xcb_window_t window, int flags, int x, int y, int width, int height)
A Window Manager should subclass NETRootInfo and reimplement this function when it wants to know when...
xcb_connection_t * xcbConnection() const
Returns the xcb connection used.
int virtualRootsCount() const
Returns the number of window in the virtualRoots array.
void moveResizeRequest(xcb_window_t window, int x_root, int y_root, Direction direction, xcb_button_t button=XCB_BUTTON_INDEX_ANY, RequestSource source=RequestSource::FromUnknown)
Clients (such as pagers/taskbars) that wish to start a WMMoveResize (where the window manager control...
xcb_window_t rootWindow() const
Returns the Window id of the rootWindow.
virtual void gotPing(xcb_window_t window, xcb_timestamp_t timestamp)
A Window Manager should subclass NETRootInfo and reimplement this function when it wants to receive r...
void showWindowMenuRequest(xcb_window_t window, int device_id, int x_root, int y_root)
Clients that wish to show the window menu using WM2GTKShowWindowMenu (_GTK_SHOW_WINDOW_MENU) should c...
void setDesktopViewport(int desktop, const NETPoint &viewport)
Sets the viewport for the current desktop to the specified point.
virtual void showWindowMenu(xcb_window_t window, int device_id, int x_root, int y_root)
A Window Manager should subclass NETRootInfo and reimplement this function when it wants to know when...
virtual void restackWindow(xcb_window_t window, RequestSource source, xcb_window_t above, int detail, xcb_timestamp_t timestamp)
A Window Manager should subclass NETRootInfo and reimplement this function when it wants to know when...
int currentDesktop(bool ignore_viewport=false) const
Returns the current desktop.
xcb_window_t activeWindow() const
Returns the active (focused) window.
const xcb_window_t * clientListStacking() const
Returns an array of Window id's, which contain all managed windows in stacking order.
virtual void changeActiveWindow(xcb_window_t window, NET::RequestSource src, xcb_timestamp_t timestamp, xcb_window_t active_window)
A Window Manager should subclass NETRootInfo and reimplement this function when it wants to know when...
void restackRequest(xcb_window_t window, RequestSource source, xcb_window_t above, int detail, xcb_timestamp_t timestamp)
Sends the _NET_RESTACK_WINDOW request.
void setDesktopName(int desktop, const char *desktopName)
Sets the name of the specified desktop.
void sendPing(xcb_window_t window, xcb_timestamp_t timestamp)
Sends a ping with the given timestamp to the window, using the _NET_WM_PING protocol.
const xcb_window_t * virtualRoots() const
Returns an array of Window id's, which contain the virtual root windows.
void activate()
Window Managers must call this after creating the NETRootInfo object, and before using any other meth...
NET::Properties2 supportedProperties2() const
In the Window Manager mode, this is equivalent to the properties2 argument passed to the constructor.
int clientListStackingCount() const
Returns the number of managed windows in the clientListStacking array.
NETPoint desktopViewport(int desktop) const
Returns the viewport of the specified desktop.
NET::Properties passedProperties() const
void setWorkArea(int desktop, const NETRect &workArea)
Sets the workarea for the specified desktop.
virtual ~NETRootInfo()
Destroys the NETRootInfo object.
NETRootInfo(xcb_connection_t *connection, xcb_window_t supportWindow, const char *wmName, NET::Properties properties, NET::WindowTypes windowTypes, NET::States states, NET::Properties2 properties2, NET::Actions actions, int screen=-1, bool doActivate=true)
Window Managers should use this constructor to create a NETRootInfo object, which will be used to set...
NET::WindowTypes passedWindowTypes() const
void setSupported(NET::Property property, bool on=true)
Sets the given property if on is true, and clears the property otherwise.
virtual void virtual_hook(int id, void *data)
Virtual hook, used to add new "virtual" functions while maintaining binary compatibility.
virtual void changeDesktopGeometry(int desktop, const NETSize &geom)
A Window Manager should subclass NETRootInfo and reimplement this function when it wants to know when...
xcb_window_t supportWindow() const
Returns the Window id of the supportWindow.
NET::DesktopLayoutCorner desktopLayoutCorner() const
Returns the desktop layout starting corner.
NETSize desktopGeometry() const
Returns the desktop geometry size.
const char * desktopName(int desktop) const
Returns the name for the specified desktop.
NET::Properties supportedProperties() const
In the Window Manager mode, this is equivalent to the properties argument passed to the constructor.
void closeWindowRequest(xcb_window_t window)
Clients (such as pagers/taskbars) that wish to close a window should call this function.
virtual void removeClient(xcb_window_t window)
A Client should subclass NETRootInfo and reimplement this function when it wants to know when a windo...
void setShowingDesktop(bool showing)
Sets the _NET_SHOWING_DESKTOP status (whether desktop is being shown).
virtual void changeNumberOfDesktops(int numberOfDesktops)
A Window Manager should subclass NETRootInfo and reimplement this function when it wants to know when...
void setDesktopGeometry(const NETSize &geometry)
Sets the desktop geometry to the specified geometry.
virtual void moveResize(xcb_window_t window, int x_root, int y_root, unsigned long direction, xcb_button_t button, RequestSource source)
A Window Manager should subclass NETRootInfo and reimplement this function when it wants to know when...
void setCurrentDesktop(int desktop, bool ignore_viewport=false)
Sets the current desktop to the specified desktop.
QSize desktopLayoutColumnsRows() const
Returns the desktop layout number of columns and rows.
const xcb_window_t * clientList() const
Returns an array of Window id's, which contain all managed windows.
void event(xcb_generic_event_t *event, NET::Properties *properties, NET::Properties2 *properties2=nullptr)
This function takes the passed xcb_generic_event_t and returns the updated properties in the passed i...
void setVirtualRoots(const xcb_window_t *windows, unsigned int count)
Sets the list of virtual root windows on the root window.
NET::Properties2 passedProperties2() const
void moveResizeWindowRequest(xcb_window_t window, int flags, int x, int y, int width, int height)
Clients (such as pagers/taskbars) that wish to move/resize a window using WM2MoveResizeWindow (_NET_M...
NET::WindowTypes supportedWindowTypes() const
In the Window Manager mode, this is equivalent to the windowTypes argument passed to the constructor.
void setNumberOfDesktops(int numberOfDesktops)
Sets the number of desktops to the specified number.
NETRect workArea(int desktop) const
Returns the workArea for the specified desktop.
NET::States supportedStates() const
In the Window Manager mode, this is equivalent to the states argument passed to the constructor.
virtual void changeCurrentDesktop(int desktop)
A Window Manager should subclass NETRootInfo and reimplement this function when it wants to know when...
bool isSupported(NET::Property property) const
Returns true if the given property is supported by the window manager.
NET::Actions passedActions() const
NET::Actions supportedActions() const
In the Window Manager mode, this is equivalent to the actions argument passed to the constructor.
void setActiveWindow(xcb_window_t window, NET::RequestSource src, xcb_timestamp_t timestamp, xcb_window_t active_window)
Requests that the specified window becomes the active (focused) one.
const NETRootInfo & operator=(const NETRootInfo &rootinfo)
Assignment operator.
void setClientListStacking(const xcb_window_t *windows, unsigned int count)
Sets the list of managed windows in stacking order on the Root/Desktop window.
const char * wmName() const
Returns the name of the Window Manager.
virtual void changeShowingDesktop(bool showing)
A Window Manager should subclass NETRootInfo and reimplement this function when it wants to know when...
int numberOfDesktops(bool ignore_viewport=false) const
Returns the number of desktops.
bool showingDesktop() const
Returns the status of _NET_SHOWING_DESKTOP.
Common API for application window properties/protocols.
bool supportsProtocol(NET::Protocol protocol) const
void setHandledIcons(bool handled)
Set whether this application window handles icons.
void setPid(int pid)
Set the application window's process id.
void setFrameOverlap(NETStrut strut)
Sets the window frame overlap strut, i.e.
bool hasWindowType() const
This function returns false if the window has not window type specified at all.
xcb_connection_t * xcbConnection() const
Returns the xcb connection used.
void event(xcb_generic_event_t *event, NET::Properties *properties, NET::Properties2 *properties2=nullptr)
This function takes the passed in xcb_generic_event_t and returns the updated properties in the passe...
void setOpacityF(qreal opacity)
Sets opacity (0 = transparent, 1 = opaque) on the window.
void setState(NET::States state, NET::States mask)
Set the state for the application window (see the NET base class documentation for a description of w...
const char * gtkApplicationId() const
void setOpacity(unsigned long opacity)
Sets opacity (0 = transparent, 0xffffffff = opaque ) on the window.
NET::Properties2 passedProperties2() const
void kdeGeometry(NETRect &frame, NETRect &window)
Places the window frame geometry in frame, and the application window geometry in window.
virtual void changeDesktop(int desktop)
A Window Manager should subclass NETWinInfo and reimplement this function when it wants to know when ...
const char * activities() const
returns a comma-separated list of the activities the window is associated with.
bool isBlockingCompositing() const
Returns whether the client wishes to block compositing (for better performance)
int desktop(bool ignore_viewport=false) const
Returns the desktop where the window is residing.
MappingState initialMappingState() const
Returns the initial mapping state as set in WM_HINTS.
const char * name() const
Returns the name of the window in UTF-8 format.
xcb_window_t transientFor() const
Returns the WM_TRANSIENT_FOR property for the window, i.e.
void setDesktopFileName(const char *name)
Sets the name as the desktop file name.
bool input() const
Returns whether the Input flag is set in WM_HINTS.
unsigned long opacity() const
Returns the opacity of the window.
MappingState mappingState() const
Returns the mapping state for the window (see the NET base class documentation for a description of m...
void setStrut(NETStrut strut)
virtual void changeState(NET::States state, NET::States mask)
A Window Manager should subclass NETWinInfo and reimplement this function when it wants to know when ...
const char * windowRole() const
Returns the window role for the window (i.e.
NET::Properties passedProperties() const
NETStrut frameExtents() const
Returns the frame decoration strut, i.e.
void setIconName(const char *name)
Sets the iconic name for the application window.
NETIcon icon(int width=-1, int height=-1) const
Returns an icon.
virtual void changeFullscreenMonitors(NETFullscreenMonitors topology)
A Window Manager should subclass NETWinInfo2 and reimplement this function when it wants to know when...
NET::Protocols protocols() const
xcb_pixmap_t icccmIconPixmapMask() const
Returns the mask for the icon pixmap as set in WM_HINTS.
WindowType windowType(WindowTypes supported_types) const
Returns the window type for this client (see the NET base class documentation for a description of th...
void setExtendedStrut(const NETExtendedStrut &extended_strut)
Set the extended (partial) strut for the application window.
void setGtkFrameExtents(NETStrut strut)
Sets the extents of the drop-shadow drawn by the client.
std::vector< NETRect > opaqueRegion() const
NETStrut gtkFrameExtents() const
Returns the extents of the drop-shadow drawn by a GTK client.
void setAppMenuServiceName(const char *name)
Sets the name as the D-BUS service name for the application menu.
NETExtendedStrut extendedStrut() const
Returns the extended (partial) strut specified by this client.
const char * appMenuObjectPath() const
const NETWinInfo & operator=(const NETWinInfo &wintinfo)
Assignment operator.
const char * visibleIconName() const
Returns the visible iconic name as set by the window manager in UTF-8 format.
const char * appMenuServiceName() const
const char * iconName() const
Returns the iconic name of the window in UTF-8 format.
const int * iconSizes() const
Returns a list of provided icon sizes.
void setActivities(const char *activities)
Sets the comma-separated list of activities the window is associated with.
xcb_pixmap_t icccmIconPixmap() const
Returns the icon pixmap as set in WM_HINTS.
const char * desktopFileName() const
NET::States state() const
Returns the state of the window (see the NET base class documentation for a description of the variou...
const char * startupId() const
Returns the startup notification id of the window.
void setFrameExtents(NETStrut strut)
Set the frame decoration strut, i.e.
qreal opacityF() const
Returns the opacity of the window.
void setWindowType(WindowType type)
Sets the window type for this client (see the NET base class documentation for a description of the v...
virtual void virtual_hook(int id, void *data)
Virtual hook, used to add new "virtual" functions while maintaining binary compatibility.
NETStrut frameOverlap() const
Returns the frame overlap strut, i.e.
const char * clientMachine() const
Returns the client machine for the window (i.e.
void setVisibleName(const char *visibleName)
For Window Managers only: set the visible name ( i.e.
void setBlockingCompositing(bool active)
Sets whether the client wishes to block compositing (for better performance)
bool handledIcons() const
Returns whether or not this client handles icons.
void setVisibleIconName(const char *name)
For Window Managers only: set the visible iconic name ( i.e.
void setDesktop(int desktop, bool ignore_viewport=false)
Set which window the desktop is (should be) on.
static const int OnAllDesktops
Sentinel value to indicate that the client wishes to be visible on all desktops.
const char * visibleName() const
Returns the visible name as set by the window manager in UTF-8 format.
xcb_window_t groupLeader() const
Returns the leader window for the group the window is in, if any.
void setStartupId(const char *startup_id)
Sets the startup notification id id on the window.
bool hasNETSupport() const
Returns true if the window has any window type set, even if the type itself is not known to this impl...
xcb_timestamp_t userTime() const
Returns the time of last user action on the window, or -1 if not set.
int pid() const
Returns the process id for the client window.
NETWinInfo(xcb_connection_t *connection, xcb_window_t window, xcb_window_t rootWindow, NET::Properties properties, NET::Properties2 properties2, Role role=Client)
Create a NETWinInfo object, which will be used to set/read/change information stored on an applicatio...
bool urgency() const
Returns whether the UrgencyHint is set in the WM_HINTS.flags.
void setFullscreenMonitors(NETFullscreenMonitors topology)
Sets the desired multiple-monitor topology (4 monitor indices indicating the top, bottom,...
virtual ~NETWinInfo()
Destroys the NETWinInfo object.
void setAppMenuObjectPath(const char *path)
Sets the name as the D-BUS object path for the application menu.
void setUserTime(xcb_timestamp_t time)
Sets user timestamp time on the window (property _NET_WM_USER_TIME).
void setIcon(NETIcon icon, bool replace=true)
Set icons for the application window.
NET::Actions allowedActions() const
Returns actions that the window manager allows for the window.
NETFullscreenMonitors fullscreenMonitors() const
Returns the desired fullscreen monitor topology for this client, should it be in fullscreen state.
const char * windowClassName() const
Returns the name component of the window class for the window (i.e.
void setAllowedActions(NET::Actions actions)
Sets actions that the window manager allows for the window.
const char * windowClassClass() const
Returns the class component of the window class for the window (i.e.
NETRect iconGeometry() const
Returns the icon geometry.
void setIconGeometry(NETRect geometry)
Set the icon geometry for the application window.
void setName(const char *name)
Sets the name for the application window.
Protocol
Protocols supported by the client.
@ DeleteWindowProtocol
WM_DELETE_WINDOW.
@ ContextHelpProtocol
_NET_WM_CONTEXT_HELP, NON STANDARD!
@ TakeFocusProtocol
WM_TAKE_FOCUS.
@ PingProtocol
_NET_WM_PING from EWMH
@ SyncRequestProtocol
_NET_WM_SYNC_REQUEST from EWMH
@ MaxHoriz
indicates that the window is horizontally maximized.
@ 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).
@ MaxVert
indicates that the window is vertically maximized.
@ DemandsAttention
there was an attempt to activate this window, but the window manager prevented this.
@ SkipTaskbar
indicates that a window should not be included on a taskbar.
@ FullScreen
indicates that a window should fill the entire screen and have no window decorations.
@ SkipSwitcher
indicates that a window should not be included on a switcher.
@ Modal
indicates that this is a modal dialog box.
@ KeepAbove
indicates that a window should on top of most windows (but below fullscreen windows).
@ Hidden
indicates that a window should not be visible on the screen (e.g.
@ SkipPager
indicates that a window should not be included on a pager.
@ KeepBelow
indicates that a window should be below most windows (but above any desktop windows).
@ Focused
indicates that a client should render as though it has focus Only the window manager is allowed to ch...
WindowTypeMask
Values for WindowType when they should be OR'ed together, e.g.
@ OnScreenDisplayMask
NON STANDARD.
@ CriticalNotificationMask
NON STANDARD.
@ AppletPopupMask
NON STANDARD.
QFlags< WindowTypeMask > WindowTypes
Stores a combination of WindowTypeMask values.
QFlags< State > States
Stores a combination of State values.
static bool typeMatchesMask(WindowType type, WindowTypes mask)
Returns true if the given window type matches the mask given using WindowTypeMask flags.
QFlags< Property2 > Properties2
Stores a combination of Property2 values.
DesktopLayoutCorner
Starting corner for desktop layout.
@ Splash
indicates that this window is a splash screen window.
@ Notification
indicates a notification window
@ Desktop
indicates a desktop feature.
@ DNDIcon
indicates a window that represents the dragged object during DND operation
@ Normal
indicates that this is a normal, top-level window
@ Unknown
indicates that the window did not define a window type.
@ OnScreenDisplay
indicates an On Screen Display window (such as volume feedback)
@ TopMenu
indicates a toplevel menu (AKA macmenu).
@ AppletPopup
indicates that this window is an applet.
@ Tooltip
indicates a tooltip window
@ Dialog
indicates that this is a dialog window
@ Toolbar
indicates a toolbar window
@ Menu
indicates a pinnable (torn-off) menu window
@ DropdownMenu
indicates a dropdown menu (from a menubar typically)
@ PopupMenu
indicates a popup menu (a context menu typically)
@ CriticalNotification
indicates a critical notification (such as battery is running out)
@ ComboBox
indicates that the window is a list for a combobox
@ Dock
indicates a dock or panel feature
@ Utility
indicates a utility window
@ Client
indicates that the application is a client application.
@ WindowManager
indicates that the application is a window manager application.
Property2
Supported properties.
QFlags< Property > Properties
Stores a combination of Property values.
static int timestampCompare(unsigned long time1, unsigned long time2)
Compares two X timestamps, taking into account wrapping and 64bit architectures.
QFlags< Action > Actions
Stores a combination of Action values.
Property
Supported properties.
RequestSource
Source of the request.
@ FromTool
indicated that the request comes from pager or similar tool
Direction
Direction for WMMoveResize.
static int timestampDiff(unsigned long time1, unsigned long time2)
Returns a difference of two X timestamps, time2 - time1, where time2 must be later than time1,...
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.
@ Visible
indicates the client window is visible to the user.
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
void init(KXmlGuiWindow *window, KGameDifficulty *difficulty=nullptr)
KIOCORE_EXPORT QStringList list(const QString &fileClass)
const char * constData() const const
qsizetype length() const const
QList< QByteArray > split(char sep) const const
void append(QList< T > &&value)
const_reference at(qsizetype i) const const
qsizetype count() const const
bool isEmpty() const const
void reserve(qsizetype size)
void resize(qsizetype size)
qsizetype size() 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 multiple monitor topology class for NET classes.
int right
Monitor index whose right border defines the right edge of the topology.
int top
Monitor index whose top border defines the top edge of the topology.
int left
Monitor index whose left border defines the left edge of the topology.
int bottom
Monitor index whose bottom border defines the bottom edge of the topology.
Simple icon class for NET classes.
NETSize size
Size of the icon.
unsigned char * data
Image data for the icon.
Simple point class for NET classes.
Simple rectangle class for NET classes.
NETPoint pos
Position of the rectangle.
NETSize size
Size of the rectangle.
Simple size class for NET classes.
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.