11 #include <xcb/xproto.h> 16 #if KWINDOWSYSTEM_HAVE_X11 //FIXME 18 #include <qx11info_x11.h> 20 #include <QGuiApplication> 22 #include <kwindowsystem.h> 23 #include <kxutils_p.h> 34 int32_t initial_state;
35 xcb_pixmap_t icon_pixmap;
36 xcb_window_t icon_window;
39 xcb_pixmap_t icon_mask;
40 xcb_window_t window_group;
44 Q_GLOBAL_STATIC(
AtomHash, s_gAtomsHash)
48 auto it = s_gAtomsHash->constFind(c);
49 if (it == s_gAtomsHash->constEnd()) {
51 s_gAtomsHash->insert(c, atom);
57 Atoms::Atoms(xcb_connection_t *c)
61 for (
int i = 0; i < KwsAtomCount; ++i) {
62 m_atoms[i] = XCB_ATOM_NONE;
67 static const uint32_t netwm_sendevent_mask =
68 (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY);
70 const long MAX_PROP_SIZE = 100000;
72 static char *nstrdup(
const char *s1)
75 return (
char *)
nullptr;
78 int l = strlen(s1) + 1;
79 char *s2 =
new char[l];
84 static char *nstrndup(
const char *s1,
int l)
87 return (
char *)
nullptr;
90 char *s2 =
new char[l + 1];
96 static xcb_window_t *nwindup(
const xcb_window_t *w1,
int n)
99 return (xcb_window_t *)
nullptr;
102 xcb_window_t *w2 =
new xcb_window_t[n];
109 static void refdec_nri(NETRootInfoPrivate *p)
112 fprintf(stderr,
"NET: decrementing NETRootInfoPrivate::ref (%d)\n", p->ref - 1);
117 fprintf(stderr,
"NET: \tno more references, deleting\n");
121 delete [] p->stacking;
122 delete [] p->clients;
123 delete [] p->virtual_roots;
124 delete [] p->temp_buf;
127 for (i = 0; i < p->desktop_names.size(); i++) {
128 delete [] p->desktop_names[i];
133 static void refdec_nwi(NETWinInfoPrivate *p)
137 fprintf(stderr,
"NET: decrementing NETWinInfoPrivate::ref (%d)\n", p->ref - 1);
143 fprintf(stderr,
"NET: \tno more references, deleting\n");
147 delete [] p->visible_name;
148 delete [] p->window_role;
149 delete [] p->icon_name;
150 delete [] p->visible_icon_name;
151 delete [] p->startup_id;
152 delete [] p->class_class;
153 delete [] p->class_name;
154 delete [] p->activities;
155 delete [] p->client_machine;
156 delete [] p->desktop_file;
157 delete [] p->appmenu_object_path;
158 delete [] p->appmenu_service_name;
161 for (i = 0; i < p->icons.size(); i++) {
162 delete [] p->icons[i].data;
164 delete [] p->icon_sizes;
168 template <
typename T>
169 T get_value_reply(xcb_connection_t *c,
const xcb_get_property_cookie_t cookie, xcb_atom_t type, T def,
bool *success =
nullptr)
173 xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie,
nullptr);
180 if (reply->type == type && reply->value_len == 1 && reply->format ==
sizeof(T) * 8) {
181 value = *
reinterpret_cast<T *
>(xcb_get_property_value(reply));
194 template <
typename T>
195 QVector<T> get_array_reply(xcb_connection_t *c,
const xcb_get_property_cookie_t cookie, xcb_atom_t type)
197 xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie,
nullptr);
204 if (reply->type == type && reply->value_len > 0 && reply->format ==
sizeof(T) * 8) {
205 T *data =
reinterpret_cast<T *
>(xcb_get_property_value(reply));
207 vector.
resize(reply->value_len);
208 memcpy((
void *)&vector.
first(), (
void *)data, reply->value_len *
sizeof(T));
215 static QByteArray get_string_reply(xcb_connection_t *c,
216 const xcb_get_property_cookie_t cookie,
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);
240 const xcb_get_property_cookie_t cookie,
243 xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie,
nullptr);
250 if (reply->type == type && reply->format == 8 && reply->value_len > 0) {
251 const char *data = (
const char *) xcb_get_property_value(reply);
252 int len = reply->value_len;
256 list = ba.
split(
'\0');
265 static QByteArray get_atom_name(xcb_connection_t *c, xcb_atom_t atom)
267 const xcb_get_atom_name_cookie_t cookie = xcb_get_atom_name(c, atom);
269 xcb_get_atom_name_reply_t *reply = xcb_get_atom_name_reply(c, cookie, 0);
283 #define ENUM_CREATE_CHAR_ARRAY 1 286 xcb_intern_atom_cookie_t cookies[KwsAtomCount];
287 for (
int i = 0; i < KwsAtomCount; ++i) {
288 cookies[i] = xcb_intern_atom(m_connection,
false, strlen(KwsAtomStrings[i]), KwsAtomStrings[i]);
292 for (
int i = 0; i < KwsAtomCount; ++i) {
293 xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(m_connection, cookies[i],
nullptr);
298 m_atoms[i] = reply->atom;
303 static void readIcon(xcb_connection_t *c,
const xcb_get_property_cookie_t cookie,
304 NETRArray<NETIcon> &icons,
int &icon_count)
307 fprintf(stderr,
"NET: readIcon\n");
311 for (
int i = 0; i < icons.size(); i++) {
312 delete [] icons[i].data;
318 xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie,
nullptr);
320 if (!reply || reply->value_len < 3 || reply->format != 32 || reply->type != XCB_ATOM_CARDINAL) {
328 uint32_t *data = (uint32_t *) xcb_get_property_value(reply);
330 for (
unsigned int i = 0, j = 0; j < reply->value_len - 2; i++) {
331 uint32_t width = data[j++];
332 uint32_t height = data[j++];
333 uint32_t size = width * height *
sizeof(uint32_t);
334 if (j + width * height > reply->value_len) {
335 fprintf(stderr,
"Ill-encoded icon data; proposed size leads to out of bounds access. Skipping. (%d x %d)\n", width, height);
338 if (width > 1024 || height > 1024) {
339 fprintf(stderr,
"Warning: found huge icon. The icon data may be ill-encoded. (%d x %d)\n", width, height);
343 icons[i].size.width = width;
344 icons[i].size.height = height;
345 icons[i].data =
new unsigned char[size];
347 memcpy((
void *)icons[i].data, (
const void *)&data[j], size);
356 fprintf(stderr,
"NET: readIcon got %d icons\n", icon_count);
360 static void send_client_message(xcb_connection_t *c, uint32_t mask,
361 xcb_window_t destination, xcb_window_t window,
362 xcb_atom_t message,
const uint32_t data[])
364 xcb_client_message_event_t
event;
365 event.response_type = XCB_CLIENT_MESSAGE;
368 event.window = window;
369 event.type = message;
371 for (
int i = 0; i < 5; i++) {
372 event.data.data32[i] = data[i];
375 xcb_send_event(c,
false, destination, mask, (
const char *) &event);
379 NETRArray<Z>::NETRArray()
382 d = (Z *) calloc(capacity,
sizeof(Z));
386 NETRArray<Z>::~NETRArray()
392 void NETRArray<Z>::reset()
396 d = (Z *) realloc(d,
sizeof(Z) * capacity);
397 memset((
void *) d, 0,
sizeof(Z)*capacity);
401 Z &NETRArray<Z>::operator[](
int index)
403 if (index >= capacity) {
407 int newcapacity = 2 * capacity > index + 1 ? 2 * capacity : index + 1;
409 d = (Z *) realloc(d,
sizeof(Z) * newcapacity);
410 memset((
void *) &d[capacity], 0,
sizeof(Z) * (newcapacity - capacity));
411 capacity = newcapacity;
435 int screen,
bool doActivate)
439 fprintf(stderr,
"NETRootInfo::NETRootInfo: using window manager constructor\n");
442 p =
new NETRootInfoPrivate;
444 p->atoms = atomsForConnection(connection);
446 p->name = nstrdup(wmName);
448 p->conn = connection;
450 p->temp_buf =
nullptr;
451 p->temp_buf_size = 0;
453 const xcb_setup_t *setup = xcb_get_setup(p->conn);
454 xcb_screen_iterator_t it = xcb_setup_roots_iterator(setup);
456 if (screen != -1 && screen < setup->roots_len) {
457 for (
int i = 0; i < screen; i++) {
458 xcb_screen_next(&it);
462 p->root = it.data->root;
463 p->supportwindow = supportWindow;
464 p->number_of_desktops = p->current_desktop = 0;
465 p->active = XCB_WINDOW_NONE;
466 p->clients = p->stacking = p->virtual_roots = (xcb_window_t *)
nullptr;
467 p->clients_count = p->stacking_count = p->virtual_roots_count = 0;
468 p->showing_desktop =
false;
469 p->desktop_layout_orientation = OrientationHorizontal;
470 p->desktop_layout_corner = DesktopLayoutCornerTopLeft;
471 p->desktop_layout_columns = p->desktop_layout_rows = 0;
472 setDefaultProperties();
473 p->properties = properties;
474 p->properties2 = properties2;
475 p->windowTypes = windowTypes;
477 p->actions = actions;
479 p->properties |= (Supported | SupportingWMCheck);
480 p->clientProperties = DesktopNames
482 p->clientProperties2 = WM2DesktopLayout;
484 p->role = WindowManager;
492 int screen,
bool doActivate)
496 fprintf(stderr,
"NETRootInfo::NETRootInfo: using Client constructor\n");
499 p =
new NETRootInfoPrivate;
501 p->atoms = atomsForConnection(connection);
505 p->conn = connection;
507 p->temp_buf =
nullptr;
508 p->temp_buf_size = 0;
510 const xcb_setup_t *setup = xcb_get_setup(p->conn);
511 xcb_screen_iterator_t it = xcb_setup_roots_iterator(setup);
513 if (screen != -1 && screen < setup->roots_len) {
514 for (
int i = 0; i < screen; i++) {
515 xcb_screen_next(&it);
519 p->root = it.data->root;
520 p->rootSize.width = it.data->width_in_pixels;
521 p->rootSize.height = it.data->height_in_pixels;
523 p->supportwindow = XCB_WINDOW_NONE;
524 p->number_of_desktops = p->current_desktop = 0;
525 p->active = XCB_WINDOW_NONE;
526 p->clients = p->stacking = p->virtual_roots = (xcb_window_t *)
nullptr;
527 p->clients_count = p->stacking_count = p->virtual_roots_count = 0;
528 p->showing_desktop =
false;
529 p->desktop_layout_orientation = OrientationHorizontal;
530 p->desktop_layout_corner = DesktopLayoutCornerTopLeft;
531 p->desktop_layout_columns = p->desktop_layout_rows = 0;
532 setDefaultProperties();
533 p->clientProperties = properties;
534 p->clientProperties2 = properties2;
556 fprintf(stderr,
"NETRootInfo::NETRootInfo: using copy constructor\n");
575 void NETRootInfo::setDefaultProperties()
577 p->properties = Supported | SupportingWMCheck;
578 p->windowTypes = NormalMask | DesktopMask | DockMask
579 | ToolbarMask | MenuMask | DialogMask;
580 p->states = Modal | Sticky | MaxVert | MaxHoriz | Shaded
581 | SkipTaskbar | KeepAbove;
590 if (p->role == WindowManager) {
594 "NETRootInfo::activate: setting supported properties on root\n");
598 update(p->clientProperties, p->clientProperties2);
602 fprintf(stderr,
"NETRootInfo::activate: updating client information\n");
605 update(p->clientProperties, p->clientProperties2);
611 if (p->role != WindowManager) {
615 p->clients_count = count;
617 delete [] p->clients;
618 p->clients = nwindup(windows, count);
621 fprintf(stderr,
"NETRootInfo::setClientList: setting list with %ld windows\n",
625 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->root, p->atom(_NET_CLIENT_LIST),
626 XCB_ATOM_WINDOW, 32, p->clients_count,
627 (
const void *) windows);
632 if (p->role != WindowManager) {
636 p->stacking_count = count;
637 delete [] p->stacking;
638 p->stacking = nwindup(windows, count);
642 "NETRootInfo::setClientListStacking: setting list with %ld windows\n",
646 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->root, p->atom(_NET_CLIENT_LIST_STACKING),
647 XCB_ATOM_WINDOW, 32, p->stacking_count,
648 (
const void *) windows);
655 "NETRootInfo::setNumberOfDesktops: setting desktop count to %d (%s)\n",
656 numberOfDesktops, (p->role == WindowManager) ?
"WM" :
"Client");
659 if (p->role == WindowManager) {
660 p->number_of_desktops = numberOfDesktops;
661 const uint32_t d = numberOfDesktops;
662 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->root, p->atom(_NET_NUMBER_OF_DESKTOPS),
663 XCB_ATOM_CARDINAL, 32, 1, (
const void *) &d);
665 const uint32_t data[5] = {
666 uint32_t(numberOfDesktops), 0, 0, 0, 0
669 send_client_message(p->conn, netwm_sendevent_mask, p->root,
670 p->root, p->atom(_NET_NUMBER_OF_DESKTOPS), data);
678 "NETRootInfo::setCurrentDesktop: setting current desktop = %d (%s)\n",
679 desktop, (p->role == WindowManager) ?
"WM" :
"Client");
682 if (p->role == WindowManager) {
683 p->current_desktop = desktop;
684 uint32_t d = p->current_desktop - 1;
685 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->root, p->atom(_NET_CURRENT_DESKTOP),
686 XCB_ATOM_CARDINAL, 32, 1, (
const void *) &d);
694 const uint32_t data[5] = {
695 uint32_t(desktop - 1), 0, 0, 0, 0
698 send_client_message(p->conn, netwm_sendevent_mask, p->root,
699 p->root, p->atom(_NET_CURRENT_DESKTOP), data);
710 delete [] p->desktop_names[desktop - 1];
711 p->desktop_names[desktop - 1] = nstrdup(desktopName);
713 unsigned int i, proplen,
714 num = ((p->number_of_desktops > p->desktop_names.size()) ?
715 p->number_of_desktops : p->desktop_names.size());
716 for (i = 0, proplen = 0; i < num; i++) {
717 proplen += (p->desktop_names[i] !=
nullptr ? strlen(p->desktop_names[i]) + 1 : 1);
720 char *prop =
new char[proplen], *propp = prop;
722 for (i = 0; i < num; i++)
723 if (p->desktop_names[i]) {
724 strcpy(propp, p->desktop_names[i]);
725 propp += strlen(p->desktop_names[i]) + 1;
732 "NETRootInfo::setDesktopName(%d, '%s')\n" 733 "NETRootInfo::setDesktopName: total property length = %d",
734 desktop, desktopName, proplen);
737 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->root, p->atom(_NET_DESKTOP_NAMES),
738 p->atom(UTF8_STRING), 8, proplen, (
const void *) prop);
746 fprintf(stderr,
"NETRootInfo::setDesktopGeometry( -- , { %d, %d }) (%s)\n",
747 geometry.
width, geometry.
height, (p->role == WindowManager) ?
"WM" :
"Client");
750 if (p->role == WindowManager) {
751 p->geometry = geometry;
754 data[0] = p->geometry.
width;
755 data[1] = p->geometry.height;
757 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->root, p->atom(_NET_DESKTOP_GEOMETRY),
758 XCB_ATOM_CARDINAL, 32, 2, (
const void *) data);
761 uint32_t(geometry.
width), uint32_t(geometry.
height), 0, 0, 0
764 send_client_message(p->conn, netwm_sendevent_mask, p->root,
765 p->root, p->atom(_NET_DESKTOP_GEOMETRY), data);
772 fprintf(stderr,
"NETRootInfo::setDesktopViewport(%d, { %d, %d }) (%s)\n",
773 desktop, viewport.
x, viewport.
y, (p->role == WindowManager) ?
"WM" :
"Client");
780 if (p->role == WindowManager) {
781 p->viewport[desktop - 1] = viewport;
784 l = p->number_of_desktops * 2;
785 uint32_t *data =
new uint32_t[l];
786 for (d = 0, i = 0; d < p->number_of_desktops; d++) {
787 data[i++] = p->viewport[d].x;
788 data[i++] = p->viewport[d].y;
791 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->root, p->atom(_NET_DESKTOP_VIEWPORT),
792 XCB_ATOM_CARDINAL, 32, l, (
const void *) data);
796 const uint32_t data[5] = {
797 uint32_t(viewport.
x), uint32_t(viewport.
y), 0, 0, 0
800 send_client_message(p->conn, netwm_sendevent_mask, p->root,
801 p->root, p->atom(_NET_DESKTOP_VIEWPORT), data);
807 if (p->role != WindowManager) {
809 fprintf(stderr,
"NETRootInfo::setSupported - role != WindowManager\n");
815 xcb_atom_t atoms[KwsAtomCount];
819 atoms[0] = p->atom(_NET_SUPPORTED);
820 atoms[1] = p->atom(_NET_SUPPORTING_WM_CHECK);
822 if (p->properties & ClientList) {
823 atoms[pnum++] = p->atom(_NET_CLIENT_LIST);
826 if (p->properties & ClientListStacking) {
827 atoms[pnum++] = p->atom(_NET_CLIENT_LIST_STACKING);
830 if (p->properties & NumberOfDesktops) {
831 atoms[pnum++] = p->atom(_NET_NUMBER_OF_DESKTOPS);
834 if (p->properties & DesktopGeometry) {
835 atoms[pnum++] = p->atom(_NET_DESKTOP_GEOMETRY);
838 if (p->properties & DesktopViewport) {
839 atoms[pnum++] = p->atom(_NET_DESKTOP_VIEWPORT);
842 if (p->properties & CurrentDesktop) {
843 atoms[pnum++] = p->atom(_NET_CURRENT_DESKTOP);
846 if (p->properties & DesktopNames) {
847 atoms[pnum++] = p->atom(_NET_DESKTOP_NAMES);
850 if (p->properties & ActiveWindow) {
851 atoms[pnum++] = p->atom(_NET_ACTIVE_WINDOW);
854 if (p->properties & WorkArea) {
855 atoms[pnum++] = p->atom(_NET_WORKAREA);
858 if (p->properties & VirtualRoots) {
859 atoms[pnum++] = p->atom(_NET_VIRTUAL_ROOTS);
862 if (p->properties2 & WM2DesktopLayout) {
863 atoms[pnum++] = p->atom(_NET_DESKTOP_LAYOUT);
866 if (p->properties & CloseWindow) {
867 atoms[pnum++] = p->atom(_NET_CLOSE_WINDOW);
870 if (p->properties2 & WM2RestackWindow) {
871 atoms[pnum++] = p->atom(_NET_RESTACK_WINDOW);
874 if (p->properties2 & WM2ShowingDesktop) {
875 atoms[pnum++] = p->atom(_NET_SHOWING_DESKTOP);
879 if (p->properties & WMMoveResize) {
880 atoms[pnum++] = p->atom(_NET_WM_MOVERESIZE);
883 if (p->properties2 & WM2MoveResizeWindow) {
884 atoms[pnum++] = p->atom(_NET_MOVERESIZE_WINDOW);
887 if (p->properties & WMName) {
888 atoms[pnum++] = p->atom(_NET_WM_NAME);
891 if (p->properties & WMVisibleName) {
892 atoms[pnum++] = p->atom(_NET_WM_VISIBLE_NAME);
895 if (p->properties & WMIconName) {
896 atoms[pnum++] = p->atom(_NET_WM_ICON_NAME);
899 if (p->properties & WMVisibleIconName) {
900 atoms[pnum++] = p->atom(_NET_WM_VISIBLE_ICON_NAME);
903 if (p->properties & WMDesktop) {
904 atoms[pnum++] = p->atom(_NET_WM_DESKTOP);
907 if (p->properties & WMWindowType) {
908 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE);
911 if (p->windowTypes & NormalMask) {
912 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE_NORMAL);
914 if (p->windowTypes & DesktopMask) {
915 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE_DESKTOP);
917 if (p->windowTypes & DockMask) {
918 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE_DOCK);
920 if (p->windowTypes & ToolbarMask) {
921 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE_TOOLBAR);
923 if (p->windowTypes & MenuMask) {
924 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE_MENU);
926 if (p->windowTypes & DialogMask) {
927 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE_DIALOG);
929 if (p->windowTypes & UtilityMask) {
930 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE_UTILITY);
932 if (p->windowTypes & SplashMask) {
933 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE_SPLASH);
935 if (p->windowTypes & DropdownMenuMask) {
936 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE_DROPDOWN_MENU);
938 if (p->windowTypes & PopupMenuMask) {
939 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE_POPUP_MENU);
941 if (p->windowTypes & TooltipMask) {
942 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE_TOOLTIP);
944 if (p->windowTypes & NotificationMask) {
945 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE_NOTIFICATION);
947 if (p->windowTypes & ComboBoxMask) {
948 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE_COMBO);
950 if (p->windowTypes & DNDIconMask) {
951 atoms[pnum++] = p->atom(_NET_WM_WINDOW_TYPE_DND);
954 if (p->windowTypes & OverrideMask) {
955 atoms[pnum++] = p->atom(_KDE_NET_WM_WINDOW_TYPE_OVERRIDE);
957 if (p->windowTypes & TopMenuMask) {
958 atoms[pnum++] = p->atom(_KDE_NET_WM_WINDOW_TYPE_TOPMENU);
960 if (p->windowTypes & OnScreenDisplayMask) {
961 atoms[pnum++] = p->atom(_KDE_NET_WM_WINDOW_TYPE_ON_SCREEN_DISPLAY);
963 if (p->windowTypes & CriticalNotificationMask) {
964 atoms[pnum++] = p->atom(_KDE_NET_WM_WINDOW_TYPE_CRITICAL_NOTIFICATION);
968 if (p->properties & WMState) {
969 atoms[pnum++] = p->atom(_NET_WM_STATE);
972 if (p->states & Modal) {
973 atoms[pnum++] = p->atom(_NET_WM_STATE_MODAL);
975 if (p->states & Sticky) {
976 atoms[pnum++] = p->atom(_NET_WM_STATE_STICKY);
978 if (p->states & MaxVert) {
979 atoms[pnum++] = p->atom(_NET_WM_STATE_MAXIMIZED_VERT);
981 if (p->states & MaxHoriz) {
982 atoms[pnum++] = p->atom(_NET_WM_STATE_MAXIMIZED_HORZ);
984 if (p->states & Shaded) {
985 atoms[pnum++] = p->atom(_NET_WM_STATE_SHADED);
987 if (p->states & SkipTaskbar) {
988 atoms[pnum++] = p->atom(_NET_WM_STATE_SKIP_TASKBAR);
990 if (p->states & SkipPager) {
991 atoms[pnum++] = p->atom(_NET_WM_STATE_SKIP_PAGER);
993 if (p->states & SkipSwitcher) {
994 atoms[pnum++] = p->atom(_KDE_NET_WM_STATE_SKIP_SWITCHER);
996 if (p->states & Hidden) {
997 atoms[pnum++] = p->atom(_NET_WM_STATE_HIDDEN);
999 if (p->states & FullScreen) {
1000 atoms[pnum++] = p->atom(_NET_WM_STATE_FULLSCREEN);
1002 if (p->states & KeepAbove) {
1003 atoms[pnum++] = p->atom(_NET_WM_STATE_ABOVE);
1005 atoms[pnum++] = p->atom(_NET_WM_STATE_STAYS_ON_TOP);
1007 if (p->states & KeepBelow) {
1008 atoms[pnum++] = p->atom(_NET_WM_STATE_BELOW);
1010 if (p->states & DemandsAttention) {
1011 atoms[pnum++] = p->atom(_NET_WM_STATE_DEMANDS_ATTENTION);
1014 if (p->states & Focused) {
1015 atoms[pnum++] = p->atom(_NET_WM_STATE_FOCUSED);
1019 if (p->properties & WMStrut) {
1020 atoms[pnum++] = p->atom(_NET_WM_STRUT);
1023 if (p->properties2 & WM2ExtendedStrut) {
1024 atoms[pnum++] = p->atom(_NET_WM_STRUT_PARTIAL);
1027 if (p->properties & WMIconGeometry) {
1028 atoms[pnum++] = p->atom(_NET_WM_ICON_GEOMETRY);
1031 if (p->properties & WMIcon) {
1032 atoms[pnum++] = p->atom(_NET_WM_ICON);
1035 if (p->properties & WMPid) {
1036 atoms[pnum++] = p->atom(_NET_WM_PID);
1039 if (p->properties & WMHandledIcons) {
1040 atoms[pnum++] = p->atom(_NET_WM_HANDLED_ICONS);
1043 if (p->properties & WMPing) {
1044 atoms[pnum++] = p->atom(_NET_WM_PING);
1047 if (p->properties2 & WM2UserTime) {
1048 atoms[pnum++] = p->atom(_NET_WM_USER_TIME);
1051 if (p->properties2 & WM2StartupId) {
1052 atoms[pnum++] = p->atom(_NET_STARTUP_ID);
1055 if (p->properties2 & WM2Opacity) {
1056 atoms[pnum++] = p->atom(_NET_WM_WINDOW_OPACITY);
1059 if (p->properties2 & WM2FullscreenMonitors) {
1060 atoms[pnum++] = p->atom(_NET_WM_FULLSCREEN_MONITORS);
1063 if (p->properties2 & WM2AllowedActions) {
1064 atoms[pnum++] = p->atom(_NET_WM_ALLOWED_ACTIONS);
1067 if (p->actions & ActionMove) {
1068 atoms[pnum++] = p->atom(_NET_WM_ACTION_MOVE);
1070 if (p->actions & ActionResize) {
1071 atoms[pnum++] = p->atom(_NET_WM_ACTION_RESIZE);
1073 if (p->actions & ActionMinimize) {
1074 atoms[pnum++] = p->atom(_NET_WM_ACTION_MINIMIZE);
1076 if (p->actions & ActionShade) {
1077 atoms[pnum++] = p->atom(_NET_WM_ACTION_SHADE);
1079 if (p->actions & ActionStick) {
1080 atoms[pnum++] = p->atom(_NET_WM_ACTION_STICK);
1082 if (p->actions & ActionMaxVert) {
1083 atoms[pnum++] = p->atom(_NET_WM_ACTION_MAXIMIZE_VERT);
1085 if (p->actions & ActionMaxHoriz) {
1086 atoms[pnum++] = p->atom(_NET_WM_ACTION_MAXIMIZE_HORZ);
1088 if (p->actions & ActionFullScreen) {
1089 atoms[pnum++] = p->atom(_NET_WM_ACTION_FULLSCREEN);
1091 if (p->actions & ActionChangeDesktop) {
1092 atoms[pnum++] = p->atom(_NET_WM_ACTION_CHANGE_DESKTOP);
1094 if (p->actions & ActionClose) {
1095 atoms[pnum++] = p->atom(_NET_WM_ACTION_CLOSE);
1099 if (p->properties & WMFrameExtents) {
1100 atoms[pnum++] = p->atom(_NET_FRAME_EXTENTS);
1101 atoms[pnum++] = p->atom(_KDE_NET_WM_FRAME_STRUT);
1104 if (p->properties2 & WM2FrameOverlap) {
1105 atoms[pnum++] = p->atom(_NET_WM_FRAME_OVERLAP);
1108 if (p->properties2 & WM2KDETemporaryRules) {
1109 atoms[pnum++] = p->atom(_KDE_NET_WM_TEMPORARY_RULES);
1111 if (p->properties2 & WM2FullPlacement) {
1112 atoms[pnum++] = p->atom(_NET_WM_FULL_PLACEMENT);
1115 if (p->properties2 & WM2Activities) {
1116 atoms[pnum++] = p->atom(_KDE_NET_WM_ACTIVITIES);
1119 if (p->properties2 & WM2BlockCompositing) {
1120 atoms[pnum++] = p->atom(_KDE_NET_WM_BLOCK_COMPOSITING);
1121 atoms[pnum++] = p->atom(_NET_WM_BYPASS_COMPOSITOR);
1124 if (p->properties2 & WM2KDEShadow) {
1125 atoms[pnum++] = p->atom(_KDE_NET_WM_SHADOW);
1128 if (p->properties2 & WM2OpaqueRegion) {
1129 atoms[pnum++] = p->atom(_NET_WM_OPAQUE_REGION);
1132 if (p->properties2 & WM2GTKFrameExtents) {
1133 atoms[pnum++] = p->atom(_GTK_FRAME_EXTENTS);
1136 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->root, p->atom(_NET_SUPPORTED),
1137 XCB_ATOM_ATOM, 32, pnum, (
const void *) atoms);
1139 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->root, p->atom(_NET_SUPPORTING_WM_CHECK),
1140 XCB_ATOM_WINDOW, 32, 1, (
const void *) & (p->supportwindow));
1144 "NETRootInfo::setSupported: _NET_SUPPORTING_WM_CHECK = 0x%lx on 0x%lx\n" 1145 " : _NET_WM_NAME = '%s' on 0x%lx\n",
1146 p->supportwindow, p->supportwindow, p->name, p->supportwindow);
1149 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->supportwindow,
1150 p->atom(_NET_SUPPORTING_WM_CHECK), XCB_ATOM_WINDOW, 32,
1151 1, (
const void *) & (p->supportwindow));
1153 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->supportwindow,
1154 p->atom(_NET_WM_NAME), p->atom(UTF8_STRING), 8, strlen(p->name),
1155 (
const void *) p->name);
1158 void NETRootInfo::updateSupportedProperties(xcb_atom_t atom)
1160 if (atom == p->atom(_NET_SUPPORTED)) {
1161 p->properties |= Supported;
1164 else if (atom == p->atom(_NET_SUPPORTING_WM_CHECK)) {
1165 p->properties |= SupportingWMCheck;
1168 else if (atom == p->atom(_NET_CLIENT_LIST)) {
1169 p->properties |= ClientList;
1172 else if (atom == p->atom(_NET_CLIENT_LIST_STACKING)) {
1173 p->properties |= ClientListStacking;
1176 else if (atom == p->atom(_NET_NUMBER_OF_DESKTOPS)) {
1177 p->properties |= NumberOfDesktops;
1180 else if (atom == p->atom(_NET_DESKTOP_GEOMETRY)) {
1181 p->properties |= DesktopGeometry;
1184 else if (atom == p->atom(_NET_DESKTOP_VIEWPORT)) {
1185 p->properties |= DesktopViewport;
1188 else if (atom == p->atom(_NET_CURRENT_DESKTOP)) {
1189 p->properties |= CurrentDesktop;
1192 else if (atom == p->atom(_NET_DESKTOP_NAMES)) {
1193 p->properties |= DesktopNames;
1196 else if (atom == p->atom(_NET_ACTIVE_WINDOW)) {
1197 p->properties |= ActiveWindow;
1200 else if (atom == p->atom(_NET_WORKAREA)) {
1201 p->properties |= WorkArea;
1204 else if (atom == p->atom(_NET_VIRTUAL_ROOTS)) {
1205 p->properties |= VirtualRoots;
1208 else if (atom == p->atom(_NET_DESKTOP_LAYOUT)) {
1209 p->properties2 |= WM2DesktopLayout;
1212 else if (atom == p->atom(_NET_CLOSE_WINDOW)) {
1213 p->properties |= CloseWindow;
1216 else if (atom == p->atom(_NET_RESTACK_WINDOW)) {
1217 p->properties2 |= WM2RestackWindow;
1220 else if (atom == p->atom(_NET_SHOWING_DESKTOP)) {
1221 p->properties2 |= WM2ShowingDesktop;
1225 else if (atom == p->atom(_NET_WM_MOVERESIZE)) {
1226 p->properties |= WMMoveResize;
1229 else if (atom == p->atom(_NET_MOVERESIZE_WINDOW)) {
1230 p->properties2 |= WM2MoveResizeWindow;
1233 else if (atom == p->atom(_NET_WM_NAME)) {
1234 p->properties |= WMName;
1237 else if (atom == p->atom(_NET_WM_VISIBLE_NAME)) {
1238 p->properties |= WMVisibleName;
1241 else if (atom == p->atom(_NET_WM_ICON_NAME)) {
1242 p->properties |= WMIconName;
1245 else if (atom == p->atom(_NET_WM_VISIBLE_ICON_NAME)) {
1246 p->properties |= WMVisibleIconName;
1249 else if (atom == p->atom(_NET_WM_DESKTOP)) {
1250 p->properties |= WMDesktop;
1253 else if (atom == p->atom(_NET_WM_WINDOW_TYPE)) {
1254 p->properties |= WMWindowType;
1258 else if (atom == p->atom(_NET_WM_WINDOW_TYPE_NORMAL)) {
1259 p->windowTypes |= NormalMask;
1260 }
else if (atom == p->atom(_NET_WM_WINDOW_TYPE_DESKTOP)) {
1261 p->windowTypes |= DesktopMask;
1262 }
else if (atom == p->atom(_NET_WM_WINDOW_TYPE_DOCK)) {
1263 p->windowTypes |= DockMask;
1264 }
else if (atom == p->atom(_NET_WM_WINDOW_TYPE_TOOLBAR)) {
1265 p->windowTypes |= ToolbarMask;
1266 }
else if (atom == p->atom(_NET_WM_WINDOW_TYPE_MENU)) {
1267 p->windowTypes |= MenuMask;
1268 }
else if (atom == p->atom(_NET_WM_WINDOW_TYPE_DIALOG)) {
1269 p->windowTypes |= DialogMask;
1270 }
else if (atom == p->atom(_NET_WM_WINDOW_TYPE_UTILITY)) {
1271 p->windowTypes |= UtilityMask;
1272 }
else if (atom == p->atom(_NET_WM_WINDOW_TYPE_SPLASH)) {
1273 p->windowTypes |= SplashMask;
1274 }
else if (atom == p->atom(_NET_WM_WINDOW_TYPE_DROPDOWN_MENU)) {
1275 p->windowTypes |= DropdownMenuMask;
1276 }
else if (atom == p->atom(_NET_WM_WINDOW_TYPE_POPUP_MENU)) {
1277 p->windowTypes |= PopupMenuMask;
1278 }
else if (atom == p->atom(_NET_WM_WINDOW_TYPE_TOOLTIP)) {
1279 p->windowTypes |= TooltipMask;
1280 }
else if (atom == p->atom(_NET_WM_WINDOW_TYPE_NOTIFICATION)) {
1281 p->windowTypes |= NotificationMask;
1282 }
else if (atom == p->atom(_NET_WM_WINDOW_TYPE_COMBO)) {
1283 p->windowTypes |= ComboBoxMask;
1284 }
else if (atom == p->atom(_NET_WM_WINDOW_TYPE_DND)) {
1285 p->windowTypes |= DNDIconMask;
1288 else if (atom == p->atom(_KDE_NET_WM_WINDOW_TYPE_OVERRIDE)) {
1289 p->windowTypes |= OverrideMask;
1290 }
else if (atom == p->atom(_KDE_NET_WM_WINDOW_TYPE_TOPMENU)) {
1291 p->windowTypes |= TopMenuMask;
1292 }
else if (atom == p->atom(_KDE_NET_WM_WINDOW_TYPE_ON_SCREEN_DISPLAY)) {
1293 p->windowTypes |= OnScreenDisplayMask;
1294 }
else if (atom == p->atom(_KDE_NET_WM_WINDOW_TYPE_CRITICAL_NOTIFICATION)) {
1295 p->windowTypes |= CriticalNotificationMask;
1298 else if (atom == p->atom(_NET_WM_STATE)) {
1299 p->properties |= WMState;
1303 else if (atom == p->atom(_NET_WM_STATE_MODAL)) {
1305 }
else if (atom == p->atom(_NET_WM_STATE_STICKY)) {
1306 p->states |= Sticky;
1307 }
else if (atom == p->atom(_NET_WM_STATE_MAXIMIZED_VERT)) {
1308 p->states |= MaxVert;
1309 }
else if (atom == p->atom(_NET_WM_STATE_MAXIMIZED_HORZ)) {
1310 p->states |= MaxHoriz;
1311 }
else if (atom == p->atom(_NET_WM_STATE_SHADED)) {
1312 p->states |= Shaded;
1313 }
else if (atom == p->atom(_NET_WM_STATE_SKIP_TASKBAR)) {
1314 p->states |= SkipTaskbar;
1315 }
else if (atom == p->atom(_NET_WM_STATE_SKIP_PAGER)) {
1316 p->states |= SkipPager;
1317 }
else if (atom == p->atom(_KDE_NET_WM_STATE_SKIP_SWITCHER)) {
1318 p->states |= SkipSwitcher;
1319 }
else if (atom == p->atom(_NET_WM_STATE_HIDDEN)) {
1320 p->states |= Hidden;
1321 }
else if (atom == p->atom(_NET_WM_STATE_FULLSCREEN)) {
1322 p->states |= FullScreen;
1323 }
else if (atom == p->atom(_NET_WM_STATE_ABOVE)) {
1324 p->states |= KeepAbove;
1325 }
else if (atom == p->atom(_NET_WM_STATE_BELOW)) {
1326 p->states |= KeepBelow;
1327 }
else if (atom == p->atom(_NET_WM_STATE_DEMANDS_ATTENTION)) {
1328 p->states |= DemandsAttention;
1329 }
else if (atom == p->atom(_NET_WM_STATE_STAYS_ON_TOP)) {
1330 p->states |= KeepAbove;
1331 }
else if (atom == p->atom(_NET_WM_STATE_FOCUSED)) {
1332 p->states |= Focused;
1335 else if (atom == p->atom(_NET_WM_STRUT)) {
1336 p->properties |= WMStrut;
1339 else if (atom == p->atom(_NET_WM_STRUT_PARTIAL)) {
1340 p->properties2 |= WM2ExtendedStrut;
1343 else if (atom == p->atom(_NET_WM_ICON_GEOMETRY)) {
1344 p->properties |= WMIconGeometry;
1347 else if (atom == p->atom(_NET_WM_ICON)) {
1348 p->properties |= WMIcon;
1351 else if (atom == p->atom(_NET_WM_PID)) {
1352 p->properties |= WMPid;
1355 else if (atom == p->atom(_NET_WM_HANDLED_ICONS)) {
1356 p->properties |= WMHandledIcons;
1359 else if (atom == p->atom(_NET_WM_PING)) {
1360 p->properties |= WMPing;
1363 else if (atom == p->atom(_NET_WM_USER_TIME)) {
1364 p->properties2 |= WM2UserTime;
1367 else if (atom == p->atom(_NET_STARTUP_ID)) {
1368 p->properties2 |= WM2StartupId;
1371 else if (atom == p->atom(_NET_WM_WINDOW_OPACITY)) {
1372 p->properties2 |= WM2Opacity;
1375 else if (atom == p->atom(_NET_WM_FULLSCREEN_MONITORS)) {
1376 p->properties2 |= WM2FullscreenMonitors;
1379 else if (atom == p->atom(_NET_WM_ALLOWED_ACTIONS)) {
1380 p->properties2 |= WM2AllowedActions;
1384 else if (atom == p->atom(_NET_WM_ACTION_MOVE)) {
1385 p->actions |= ActionMove;
1386 }
else if (atom == p->atom(_NET_WM_ACTION_RESIZE)) {
1387 p->actions |= ActionResize;
1388 }
else if (atom == p->atom(_NET_WM_ACTION_MINIMIZE)) {
1389 p->actions |= ActionMinimize;
1390 }
else if (atom == p->atom(_NET_WM_ACTION_SHADE)) {
1391 p->actions |= ActionShade;
1392 }
else if (atom == p->atom(_NET_WM_ACTION_STICK)) {
1393 p->actions |= ActionStick;
1394 }
else if (atom == p->atom(_NET_WM_ACTION_MAXIMIZE_VERT)) {
1395 p->actions |= ActionMaxVert;
1396 }
else if (atom == p->atom(_NET_WM_ACTION_MAXIMIZE_HORZ)) {
1397 p->actions |= ActionMaxHoriz;
1398 }
else if (atom == p->atom(_NET_WM_ACTION_FULLSCREEN)) {
1399 p->actions |= ActionFullScreen;
1400 }
else if (atom == p->atom(_NET_WM_ACTION_CHANGE_DESKTOP)) {
1401 p->actions |= ActionChangeDesktop;
1402 }
else if (atom == p->atom(_NET_WM_ACTION_CLOSE)) {
1403 p->actions |= ActionClose;
1406 else if (atom == p->atom(_NET_FRAME_EXTENTS)) {
1407 p->properties |= WMFrameExtents;
1408 }
else if (atom == p->atom(_KDE_NET_WM_FRAME_STRUT)) {
1409 p->properties |= WMFrameExtents;
1410 }
else if (atom == p->atom(_NET_WM_FRAME_OVERLAP)) {
1411 p->properties2 |= WM2FrameOverlap;
1414 else if (atom == p->atom(_KDE_NET_WM_TEMPORARY_RULES)) {
1415 p->properties2 |= WM2KDETemporaryRules;
1416 }
else if (atom == p->atom(_NET_WM_FULL_PLACEMENT)) {
1417 p->properties2 |= WM2FullPlacement;
1420 else if (atom == p->atom(_KDE_NET_WM_ACTIVITIES)) {
1421 p->properties2 |= WM2Activities;
1424 else if (atom == p->atom(_KDE_NET_WM_BLOCK_COMPOSITING) ||
1425 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(_KDE_NET_WM_APPMENU_OBJECT_PATH)) {
1442 p->properties2 |= WM2AppMenuObjectPath;
1445 else if (atom == p->atom(_KDE_NET_WM_APPMENU_SERVICE_NAME)) {
1446 p->properties2 |= WM2AppMenuServiceName;
1452 setActiveWindow(window, FromUnknown, QX11Info::appUserTime(), XCB_WINDOW_NONE);
1456 xcb_timestamp_t timestamp, xcb_window_t active_window)
1459 fprintf(stderr,
"NETRootInfo::setActiveWindow(0x%lx) (%s)\n",
1460 window, (p->role == WindowManager) ?
"WM" :
"Client");
1463 if (p->role == WindowManager) {
1466 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->root, p->atom(_NET_ACTIVE_WINDOW),
1467 XCB_ATOM_WINDOW, 32, 1, (
const void *) & (p->active));
1469 const uint32_t data[5] = {
1470 src, timestamp, active_window, 0, 0
1473 send_client_message(p->conn, netwm_sendevent_mask, p->root,
1474 window, p->atom(_NET_ACTIVE_WINDOW), data);
1481 fprintf(stderr,
"NETRootInfo::setWorkArea(%d, { %d, %d, %d, %d }) (%s)\n",
1483 (p->role == WindowManager) ?
"WM" :
"Client");
1486 if (p->role != WindowManager || desktop < 1) {
1490 p->workarea[desktop - 1] = workarea;
1492 uint32_t *wa =
new uint32_t[p->number_of_desktops * 4];
1494 for (i = 0, o = 0; i < p->number_of_desktops; i++) {
1495 wa[o++] = p->workarea[i].
pos.
x;
1496 wa[o++] = p->workarea[i].pos.y;
1497 wa[o++] = p->workarea[i].size.width;
1498 wa[o++] = p->workarea[i].size.height;
1501 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->root, p->atom(_NET_WORKAREA),
1502 XCB_ATOM_CARDINAL, 32, p->number_of_desktops * 4,
1510 if (p->role != WindowManager) {
1514 p->virtual_roots_count = count;
1515 delete[] p->virtual_roots;
1516 p->virtual_roots = nwindup(windows, count);
1519 fprintf(stderr,
"NETRootInfo::setVirtualRoots: setting list with %ld windows\n",
1520 p->virtual_roots_count);
1523 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->root, p->atom(_NET_VIRTUAL_ROOTS),
1524 XCB_ATOM_WINDOW, 32, p->virtual_roots_count,
1525 (
const void *) windows);
1531 p->desktop_layout_orientation = orientation;
1532 p->desktop_layout_columns = columns;
1533 p->desktop_layout_rows = rows;
1534 p->desktop_layout_corner = corner;
1537 fprintf(stderr,
"NETRootInfo::setDesktopLayout: %d %d %d %d\n",
1538 orientation, columns, rows, corner);
1542 data[0] = orientation;
1547 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->root, p->atom(_NET_DESKTOP_LAYOUT),
1548 XCB_ATOM_CARDINAL, 32, 4, (
const void *) data);
1553 if (p->role == WindowManager) {
1554 uint32_t d = p->showing_desktop = showing;
1555 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->root, p->atom(_NET_SHOWING_DESKTOP),
1556 XCB_ATOM_CARDINAL, 32, 1, (
const void *) &d);
1559 uint32_t data[5] = {
1560 uint32_t(showing ? 1 : 0), 0, 0, 0, 0
1562 send_client_message(p->conn, netwm_sendevent_mask, p->root, p->root, p->atom(_NET_SHOWING_DESKTOP), data);
1568 return p->showing_desktop;
1574 fprintf(stderr,
"NETRootInfo::closeWindowRequest: requesting close for 0x%lx\n",
1578 const uint32_t data[5] = { 0, 0, 0, 0, 0 };
1579 send_client_message(p->conn, netwm_sendevent_mask, p->root, window, p->atom(_NET_CLOSE_WINDOW), data);
1587 "NETRootInfo::moveResizeRequest: requesting resize/move for 0x%lx (%d, %d, %d)\n",
1588 window, x_root, y_root, direction);
1591 const uint32_t data[5] = {
1592 uint32_t(x_root), uint32_t(y_root), uint32_t(direction), 0, 0
1595 send_client_message(p->conn, netwm_sendevent_mask, p->root, window, p->atom(_NET_WM_MOVERESIZE), data);
1602 "NETRootInfo::moveResizeWindowRequest: resizing/moving 0x%lx (%d, %d, %d, %d, %d)\n",
1603 window, flags, x, y, width, height);
1606 const uint32_t data[5] = {
1607 uint32_t(flags), uint32_t(x), uint32_t(y), uint32_t(width), uint32_t(height)
1610 send_client_message(p->conn, netwm_sendevent_mask, p->root, window, p->atom(_NET_MOVERESIZE_WINDOW), data);
1617 "NETRootInfo::restackRequest: requesting restack for 0x%lx (%lx, %d)\n",
1618 window, above, detail);
1621 const uint32_t data[5] = {
1622 uint32_t(src), uint32_t(above), uint32_t(detail), uint32_t(timestamp), 0
1625 send_client_message(p->conn, netwm_sendevent_mask, p->root, window, p->atom(_NET_RESTACK_WINDOW), data);
1630 if (p->role != WindowManager) {
1635 fprintf(stderr,
"NETRootInfo::setPing: window 0x%lx, timestamp %lu\n",
1639 const uint32_t data[5] = {
1640 p->atom(_NET_WM_PING), timestamp, window, 0, 0
1643 send_client_message(p->conn, 0, window, window, p->atom(WM_PROTOCOLS), data);
1652 fprintf(stderr,
"NETRootInfo::operator=()\n");
1655 if (p != rootinfo.p) {
1676 #if KWINDOWSYSTEM_BUILD_DEPRECATED_SINCE(5, 0) 1679 unsigned long props[ PROPERTIES_SIZE ] = { 0, 0, 0, 0, 0 };
1680 assert(PROPERTIES_SIZE == 5);
1684 props[ PROTOCOLS ] = p;
1685 props[ PROTOCOLS2 ] = p2;
1687 if (properties_size > PROPERTIES_SIZE) {
1688 properties_size = PROPERTIES_SIZE;
1691 i < properties_size;
1693 properties[ i ] = props[ i ];
1702 bool do_update =
false;
1703 const uint8_t eventType =
event->response_type & ~0x80;
1707 if (p->role == WindowManager && eventType == XCB_CLIENT_MESSAGE &&
1708 reinterpret_cast<xcb_client_message_event_t *>(event)->format == 32) {
1709 xcb_client_message_event_t *message =
reinterpret_cast<xcb_client_message_event_t *
>(
event);
1711 fprintf(stderr,
"NETRootInfo::event: handling ClientMessage event\n");
1714 if (message->type == p->atom(_NET_NUMBER_OF_DESKTOPS)) {
1715 dirty = NumberOfDesktops;
1718 fprintf(stderr,
"NETRootInfo::event: changeNumberOfDesktops(%ld)\n",
1719 message->data.data32[0]);
1722 changeNumberOfDesktops(message->data.data32[0]);
1723 }
else if (message->type == p->atom(_NET_DESKTOP_GEOMETRY)) {
1724 dirty = DesktopGeometry;
1727 sz.
width = message->data.data32[0];
1728 sz.
height = message->data.data32[1];
1731 fprintf(stderr,
"NETRootInfo::event: changeDesktopGeometry( -- , { %d, %d })\n",
1735 changeDesktopGeometry(~0, sz);
1736 }
else if (message->type == p->atom(_NET_DESKTOP_VIEWPORT)) {
1737 dirty = DesktopViewport;
1740 pt.
x = message->data.data32[0];
1741 pt.
y = message->data.data32[1];
1744 fprintf(stderr,
"NETRootInfo::event: changeDesktopViewport(%d, { %d, %d })\n",
1745 p->current_desktop, pt.
x, pt.
y);
1748 changeDesktopViewport(p->current_desktop, pt);
1749 }
else if (message->type == p->atom(_NET_CURRENT_DESKTOP)) {
1750 dirty = CurrentDesktop;
1753 fprintf(stderr,
"NETRootInfo::event: changeCurrentDesktop(%ld)\n",
1754 message->data.data32[0] + 1);
1757 changeCurrentDesktop(message->data.data32[0] + 1);
1758 }
else if (message->type == p->atom(_NET_ACTIVE_WINDOW)) {
1759 dirty = ActiveWindow;
1762 fprintf(stderr,
"NETRootInfo::event: changeActiveWindow(0x%lx)\n",
1767 xcb_timestamp_t timestamp = XCB_TIME_CURRENT_TIME;
1768 xcb_window_t active_window = XCB_WINDOW_NONE;
1770 if (message->data.data32[0] >= FromUnknown
1771 && message->data.data32[0] <= FromTool) {
1772 src =
static_cast< RequestSource >(message->data.data32[0]);
1773 timestamp = message->data.data32[1];
1774 active_window = message->data.data32[2];
1776 changeActiveWindow(message->window, src, timestamp, active_window);
1777 }
else if (message->type == p->atom(_NET_WM_MOVERESIZE)) {
1780 fprintf(stderr,
"NETRootInfo::event: moveResize(%ld, %ld, %ld, %ld)\n",
1782 message->data.data32[0],
1783 message->data.data32[1],
1784 message->data.data32[2]
1788 moveResize(message->window,
1789 message->data.data32[0],
1790 message->data.data32[1],
1791 message->data.data32[2]);
1792 }
else if (message->type == p->atom(_NET_MOVERESIZE_WINDOW)) {
1795 fprintf(stderr,
"NETRootInfo::event: moveResizeWindow(%ld, %ld, %ld, %ld, %ld, %ld)\n",
1797 message->data.data32[0],
1798 message->data.data32[1],
1799 message->data.data32[2],
1800 message->data.data32[3],
1801 message->data.data32[4]
1805 moveResizeWindow(message->window,
1806 message->data.data32[0],
1807 message->data.data32[1],
1808 message->data.data32[2],
1809 message->data.data32[3],
1810 message->data.data32[4]);
1811 }
else if (message->type == p->atom(_NET_CLOSE_WINDOW)) {
1814 fprintf(stderr,
"NETRootInfo::event: closeWindow(0x%lx)\n",
1818 closeWindow(message->window);
1819 }
else if (message->type == p->atom(_NET_RESTACK_WINDOW)) {
1822 fprintf(stderr,
"NETRootInfo::event: restackWindow(0x%lx)\n",
1827 xcb_timestamp_t timestamp = XCB_TIME_CURRENT_TIME;
1829 if (message->data.data32[0] >= FromUnknown
1830 && message->data.data32[0] <= FromTool) {
1831 src =
static_cast< RequestSource >(message->data.data32[0]);
1832 timestamp = message->data.data32[3];
1834 restackWindow(message->window, src,
1835 message->data.data32[1], message->data.data32[2], timestamp);
1836 }
else if (message->type == p->atom(WM_PROTOCOLS)
1837 && (xcb_atom_t)message->data.data32[ 0 ] == p->atom(_NET_WM_PING)) {
1841 fprintf(stderr,
"NETRootInfo::event: gotPing(0x%lx,%lu)\n",
1842 message->window, message->data.data32[1]);
1844 gotPing(message->data.data32[2], message->data.data32[1]);
1845 }
else if (message->type == p->atom(_NET_SHOWING_DESKTOP)) {
1846 dirty2 = WM2ShowingDesktop;
1849 fprintf(stderr,
"NETRootInfo::event: changeShowingDesktop(%ld)\n",
1850 message->data.data32[0]);
1853 changeShowingDesktop(message->data.data32[0]);
1857 if (eventType == XCB_PROPERTY_NOTIFY) {
1860 fprintf(stderr,
"NETRootInfo::event: handling PropertyNotify event\n");
1863 xcb_property_notify_event_t *pe =
reinterpret_cast<xcb_property_notify_event_t *
>(
event);
1864 if (pe->atom == p->atom(_NET_CLIENT_LIST)) {
1865 dirty |= ClientList;
1866 }
else if (pe->atom == p->atom(_NET_CLIENT_LIST_STACKING)) {
1867 dirty |= ClientListStacking;
1868 }
else if (pe->atom == p->atom(_NET_DESKTOP_NAMES)) {
1869 dirty |= DesktopNames;
1870 }
else if (pe->atom == p->atom(_NET_WORKAREA)) {
1872 }
else if (pe->atom == p->atom(_NET_NUMBER_OF_DESKTOPS)) {
1873 dirty |= NumberOfDesktops;
1874 }
else if (pe->atom == p->atom(_NET_DESKTOP_GEOMETRY)) {
1875 dirty |= DesktopGeometry;
1876 }
else if (pe->atom == p->atom(_NET_DESKTOP_VIEWPORT)) {
1877 dirty |= DesktopViewport;
1878 }
else if (pe->atom == p->atom(_NET_CURRENT_DESKTOP)) {
1879 dirty |= CurrentDesktop;
1880 }
else if (pe->atom == p->atom(_NET_ACTIVE_WINDOW)) {
1881 dirty |= ActiveWindow;
1882 }
else if (pe->atom == p->atom(_NET_SHOWING_DESKTOP)) {
1883 dirty2 |= WM2ShowingDesktop;
1884 }
else if (pe->atom == p->atom(_NET_SUPPORTED)) {
1886 }
else if (pe->atom == p->atom(_NET_SUPPORTING_WM_CHECK)) {
1887 dirty |= SupportingWMCheck;
1888 }
else if (pe->atom == p->atom(_NET_VIRTUAL_ROOTS)) {
1889 dirty |= VirtualRoots;
1890 }
else if (pe->atom == p->atom(_NET_DESKTOP_LAYOUT)) {
1891 dirty2 |= WM2DesktopLayout;
1898 update(dirty, dirty2);
1902 fprintf(stderr,
"NETRootInfo::event: handled events, returning dirty = 0x%lx, 0x%lx\n",
1907 *properties = dirty;
1910 *properties2 = dirty2;
1921 xcb_get_property_cookie_t cookies[255];
1922 xcb_get_property_cookie_t wm_name_cookie;
1926 if (dirty & Supported) {
1927 cookies[c++] = xcb_get_property(p->conn,
false, p->root, p->atom(_NET_SUPPORTED), XCB_ATOM_ATOM, 0, MAX_PROP_SIZE);
1930 if (dirty & ClientList) {
1931 cookies[c++] = xcb_get_property(p->conn,
false, p->root, p->atom(_NET_CLIENT_LIST), XCB_ATOM_WINDOW, 0, MAX_PROP_SIZE);
1934 if (dirty & ClientListStacking) {
1935 cookies[c++] = xcb_get_property(p->conn,
false, p->root, p->atom(_NET_CLIENT_LIST_STACKING), XCB_ATOM_WINDOW, 0, MAX_PROP_SIZE);
1938 if (dirty & NumberOfDesktops) {
1939 cookies[c++] = xcb_get_property(p->conn,
false, p->root, p->atom(_NET_NUMBER_OF_DESKTOPS), XCB_ATOM_CARDINAL, 0, 1);
1942 if (dirty & DesktopGeometry) {
1943 cookies[c++] = xcb_get_property(p->conn,
false, p->root, p->atom(_NET_DESKTOP_GEOMETRY), XCB_ATOM_CARDINAL, 0, 2);
1946 if (dirty & DesktopViewport) {
1947 cookies[c++] = xcb_get_property(p->conn,
false, p->root, p->atom(_NET_DESKTOP_VIEWPORT), XCB_ATOM_CARDINAL, 0, MAX_PROP_SIZE);
1950 if (dirty & CurrentDesktop) {
1951 cookies[c++] = xcb_get_property(p->conn,
false, p->root, p->atom(_NET_CURRENT_DESKTOP), XCB_ATOM_CARDINAL, 0, 1);
1954 if (dirty & DesktopNames) {
1955 cookies[c++] = xcb_get_property(p->conn,
false, p->root, p->atom(_NET_DESKTOP_NAMES), p->atom(UTF8_STRING), 0, MAX_PROP_SIZE);
1958 if (dirty & ActiveWindow) {
1959 cookies[c++] = xcb_get_property(p->conn,
false, p->root, p->atom(_NET_ACTIVE_WINDOW), XCB_ATOM_WINDOW, 0, 1);
1962 if (dirty & WorkArea) {
1963 cookies[c++] = xcb_get_property(p->conn,
false, p->root, p->atom(_NET_WORKAREA), XCB_ATOM_CARDINAL, 0, MAX_PROP_SIZE);
1966 if (dirty & SupportingWMCheck) {
1967 cookies[c++] = xcb_get_property(p->conn,
false, p->root, p->atom(_NET_SUPPORTING_WM_CHECK), XCB_ATOM_WINDOW, 0, 1);
1970 if (dirty & VirtualRoots) {
1971 cookies[c++] = xcb_get_property(p->conn,
false, p->root, p->atom(_NET_VIRTUAL_ROOTS), XCB_ATOM_WINDOW, 0, 1);
1974 if (dirty2 & WM2DesktopLayout) {
1975 cookies[c++] = xcb_get_property(p->conn,
false, p->root, p->atom(_NET_DESKTOP_LAYOUT), XCB_ATOM_CARDINAL, 0, MAX_PROP_SIZE);
1978 if (dirty2 & WM2ShowingDesktop) {
1979 cookies[c++] = xcb_get_property(p->conn,
false, p->root, p->atom(_NET_SHOWING_DESKTOP), XCB_ATOM_CARDINAL, 0, 1);
1985 if (dirty & Supported) {
1993 const QVector<xcb_atom_t> atoms = get_array_reply<xcb_atom_t>(p->conn, cookies[c++], XCB_ATOM_ATOM);
1994 for (
const xcb_atom_t atom : atoms) {
1995 updateSupportedProperties(atom);
1999 if (dirty & ClientList) {
2003 QVector<xcb_window_t> clients = get_array_reply<xcb_window_t>(p->conn, cookies[c++], XCB_ATOM_WINDOW);
2004 std::sort(clients.
begin(), clients.
end());
2007 if (p->role == Client) {
2008 int new_index = 0, old_index = 0;
2009 int old_count = p->clients_count;
2010 int new_count = clients.
count();
2012 while (old_index < old_count || new_index < new_count) {
2013 if (old_index == old_count) {
2014 clientsToAdd.
append(clients[new_index++]);
2015 }
else if (new_index == new_count) {
2016 clientsToRemove.
append(p->clients[old_index++]);
2018 if (p->clients[old_index] < clients[new_index]) {
2019 clientsToRemove.
append(p->clients[old_index++]);
2020 }
else if (clients[new_index] <
2021 p->clients[old_index]) {
2022 clientsToAdd.
append(clients[new_index++]);
2031 delete [] p->clients;
2032 p->clients =
nullptr;
2035 fprintf(stderr,
"NETRootInfo::update: client list null, creating\n");
2039 for (
int i = 0; i < clients.
count(); i++) {
2040 clientsToAdd.
append(clients[i]);
2045 p->clients_count = clients.
count();
2046 p->clients =
new xcb_window_t[clients.
count()];
2047 for (
int i = 0; i < clients.
count(); i++) {
2048 p->clients[i] = clients.
at(i);
2053 fprintf(stderr,
"NETRootInfo::update: client list updated (%ld clients)\n",
2057 for (
int i = 0; i < clientsToRemove.
size(); ++i) {
2058 removeClient(clientsToRemove.
at(i));
2061 for (
int i = 0; i < clientsToAdd.
size(); ++i) {
2062 addClient(clientsToAdd.
at(i));
2066 if (dirty & ClientListStacking) {
2067 p->stacking_count = 0;
2069 delete[] p->stacking;
2070 p->stacking =
nullptr;
2072 const QVector<xcb_window_t> wins = get_array_reply<xcb_window_t>(p->conn, cookies[c++], XCB_ATOM_WINDOW);
2075 p->stacking_count = wins.
count();
2076 p->stacking =
new xcb_window_t[wins.
count()];
2077 for (
int i = 0; i < wins.
count(); i++) {
2078 p->stacking[i] = wins.
at(i);
2083 fprintf(stderr,
"NETRootInfo::update: client stacking updated (%ld clients)\n",
2088 if (dirty & NumberOfDesktops) {
2089 p->number_of_desktops = get_value_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL, 0);
2092 fprintf(stderr,
"NETRootInfo::update: number of desktops = %d\n",
2093 p->number_of_desktops);
2097 if (dirty & DesktopGeometry) {
2098 p->geometry = p->rootSize;
2100 const QVector<uint32_t> data = get_array_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL);
2101 if (data.
count() == 2) {
2102 p->geometry.width = data.
at(0);
2103 p->geometry.height = data.
at(1);
2107 fprintf(stderr,
"NETRootInfo::update: desktop geometry updated\n");
2111 if (dirty & DesktopViewport) {
2112 for (
int i = 0; i < p->viewport.size(); i++) {
2113 p->viewport[i].x = p->viewport[i].y = 0;
2116 const QVector<uint32_t> data = get_array_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL);
2118 if (data.
count() >= 2) {
2119 int n = data.
count() / 2;
2120 for (
int d = 0, i = 0; d < n; d++) {
2121 p->viewport[d].x = data[i++];
2122 p->viewport[d].y = data[i++];
2127 "NETRootInfo::update: desktop viewport array updated (%d entries)\n",
2128 p->viewport.size());
2130 if (data.
count() % 2 != 0) {
2132 "NETRootInfo::update(): desktop viewport array " 2133 "size not a multiple of 2\n");
2139 if (dirty & CurrentDesktop) {
2140 p->current_desktop = get_value_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL, 0) + 1;
2143 fprintf(stderr,
"NETRootInfo::update: current desktop = %d\n",
2144 p->current_desktop);
2148 if (dirty & DesktopNames) {
2149 for (
int i = 0; i < p->desktop_names.size(); ++i) {
2150 delete[] p->desktop_names[i];
2153 p->desktop_names.reset();
2155 const QList<QByteArray> names = get_stringlist_reply(p->conn, cookies[c++], p->atom(UTF8_STRING));
2156 for (
int i = 0; i < names.
count(); i++) {
2157 p->desktop_names[i] = nstrndup(names[i].constData(), names[i].length());
2161 fprintf(stderr,
"NETRootInfo::update: desktop names array updated (%d entries)\n",
2162 p->desktop_names.size());
2166 if (dirty & ActiveWindow) {
2167 p->active = get_value_reply<xcb_window_t>(p->conn, cookies[c++], XCB_ATOM_WINDOW, 0);
2170 fprintf(stderr,
"NETRootInfo::update: active window = 0x%lx\n", p->active);
2174 if (dirty & WorkArea) {
2175 p->workarea.reset();
2177 const QVector<uint32_t> data = get_array_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL);
2178 if (data.
count() == p->number_of_desktops * 4) {
2179 for (
int i = 0, j = 0; i < p->number_of_desktops; i++) {
2180 p->workarea[i].pos.x = data[j++];
2181 p->workarea[i].pos.y = data[j++];
2182 p->workarea[i].
size.width = data[j++];
2183 p->workarea[i].
size.height = data[j++];
2188 fprintf(stderr,
"NETRootInfo::update: work area array updated (%d entries)\n",
2189 p->workarea.size());
2193 if (dirty & SupportingWMCheck) {
2197 p->supportwindow = get_value_reply<xcb_window_t>(p->conn, cookies[c++], XCB_ATOM_WINDOW, 0);
2201 if (p->supportwindow)
2202 wm_name_cookie = xcb_get_property(p->conn,
false, p->supportwindow, p->atom(_NET_WM_NAME),
2203 p->atom(UTF8_STRING), 0, MAX_PROP_SIZE);
2206 if (dirty & VirtualRoots) {
2207 p->virtual_roots_count = 0;
2209 delete[] p->virtual_roots;
2210 p->virtual_roots =
nullptr;
2212 const QVector<xcb_window_t> wins = get_array_reply<xcb_window_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL);
2215 p->virtual_roots_count = wins.
count();
2216 p->virtual_roots =
new xcb_window_t[wins.
count()];
2217 for (
int i = 0; i < wins.
count(); i++) {
2218 p->virtual_roots[i] = wins.
at(i);
2223 fprintf(stderr,
"NETRootInfo::updated: virtual roots updated (%ld windows)\n",
2224 p->virtual_roots_count);
2228 if (dirty2 & WM2DesktopLayout) {
2229 p->desktop_layout_orientation = OrientationHorizontal;
2230 p->desktop_layout_corner = DesktopLayoutCornerTopLeft;
2231 p->desktop_layout_columns = p->desktop_layout_rows = 0;
2233 const QVector<uint32_t> data = get_array_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL);
2235 if (data.
count() >= 4 && data[3] <= 3) {
2239 if (data.
count() >= 3) {
2244 p->desktop_layout_columns = data[1];
2245 p->desktop_layout_rows = data[2];
2249 fprintf(stderr,
"NETRootInfo::updated: desktop layout updated (%d %d %d %d)\n",
2250 p->desktop_layout_orientation, p->desktop_layout_columns,
2251 p->desktop_layout_rows, p->desktop_layout_corner);
2255 if (dirty2 & WM2ShowingDesktop) {
2256 const uint32_t val = get_value_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL, 0);
2257 p->showing_desktop = bool(val);
2260 fprintf(stderr,
"NETRootInfo::update: showing desktop = %d\n",
2261 p->showing_desktop);
2265 if ((dirty & SupportingWMCheck) && p->supportwindow) {
2266 const QByteArray ba = get_string_reply(p->conn, wm_name_cookie, p->atom(UTF8_STRING));
2272 fprintf(stderr,
"NETRootInfo::update: supporting window manager = '%s'\n", p->name);
2289 return p->supportwindow;
2299 return p->properties;
2304 return p->properties2;
2314 return p->windowTypes;
2324 return p->role == WindowManager
2326 : p->clientProperties;
2331 return p->role == WindowManager
2333 : p->clientProperties2;
2338 return p->role == WindowManager
2345 return p->role == WindowManager
2352 return p->role == WindowManager
2359 if (p->role != WindowManager) {
2367 p->properties &= ~property;
2374 if (p->role != WindowManager) {
2382 p->properties2 &= ~property;
2389 if (p->role != WindowManager) {
2397 p->windowTypes &= ~property;
2404 if (p->role != WindowManager) {
2412 p->states &= ~property;
2419 if (p->role != WindowManager) {
2427 p->actions &= ~property;
2444 return p->windowTypes & type;
2449 return p->states & state;
2454 return p->actions & action;
2464 return p->clients_count;
2474 return p->stacking_count;
2479 return p->geometry.
width != 0 ? p->geometry : p->rootSize;
2489 return p->viewport[desktop - 1];
2499 return p->workarea[desktop - 1];
2508 return p->desktop_names[desktop - 1];
2513 return p->virtual_roots;
2518 return p->virtual_roots_count;
2523 return p->desktop_layout_orientation;
2528 return QSize(p->desktop_layout_columns, p->desktop_layout_rows);
2533 return p->desktop_layout_corner;
2541 return p->number_of_desktops == 0 ? 1 : p->number_of_desktops;
2549 return p->current_desktop == 0 ? 1 : p->current_desktop;
2567 fprintf(stderr,
"NETWinInfo::NETWinInfo: constructing object with role '%s'\n",
2568 (role == WindowManager) ?
"WindowManager" :
"Client");
2571 p =
new NETWinInfoPrivate;
2573 p->atoms = atomsForConnection(connection);
2575 p->conn = connection;
2577 p->root = rootWindow;
2578 p->mapping_state = Withdrawn;
2579 p->mapping_state_dirty =
true;
2581 p->types[ 0 ] = Unknown;
2582 p->name = (
char *)
nullptr;
2583 p->visible_name = (
char *)
nullptr;
2584 p->icon_name = (
char *)
nullptr;
2585 p->visible_icon_name = (
char *)
nullptr;
2586 p->desktop = p->pid = 0;
2587 p->handled_icons =
false;
2589 p->startup_id =
nullptr;
2590 p->transient_for = XCB_NONE;
2591 p->opacity = 0xffffffffU;
2592 p->window_group = XCB_NONE;
2593 p->icon_pixmap = XCB_PIXMAP_NONE;
2594 p->icon_mask = XCB_PIXMAP_NONE;
2596 p->has_net_support =
false;
2597 p->class_class = (
char *)
nullptr;
2598 p->class_name = (
char *)
nullptr;
2599 p->window_role = (
char *)
nullptr;
2600 p->client_machine = (
char *)
nullptr;
2601 p->icon_sizes =
nullptr;
2602 p->activities = (
char *)
nullptr;
2603 p->desktop_file =
nullptr;
2604 p->appmenu_object_path =
nullptr;
2605 p->appmenu_service_name =
nullptr;
2606 p->blockCompositing =
false;
2610 p->protocols = NET::NoProtocol;
2616 p->properties = properties;
2617 p->properties2 = properties2;
2623 update(p->properties, p->properties2);
2626 #if KWINDOWSYSTEM_BUILD_DEPRECATED_SINCE(5, 0) 2632 fprintf(stderr,
"NETWinInfo::NETWinInfo: constructing object with role '%s'\n",
2633 (role == WindowManager) ?
"WindowManager" :
"Client");
2636 p =
new NETWinInfoPrivate;
2638 p->atoms = atomsForConnection(connection);
2640 p->conn = connection;
2642 p->root = rootWindow;
2643 p->mapping_state = Withdrawn;
2644 p->mapping_state_dirty =
true;
2646 p->types[ 0 ] = Unknown;
2647 p->name = (
char *)
nullptr;
2648 p->visible_name = (
char *)
nullptr;
2649 p->icon_name = (
char *)
nullptr;
2650 p->visible_icon_name = (
char *)
nullptr;
2651 p->desktop = p->pid = 0;
2652 p->handled_icons =
false;
2654 p->startup_id =
nullptr;
2655 p->transient_for = XCB_NONE;
2656 p->opacity = 0xffffffffU;
2657 p->window_group = XCB_NONE;
2658 p->icon_pixmap = XCB_PIXMAP_NONE;
2659 p->icon_mask = XCB_PIXMAP_NONE;
2661 p->has_net_support =
false;
2662 p->class_class = (
char *)
nullptr;
2663 p->class_name = (
char *)
nullptr;
2664 p->window_role = (
char *)
nullptr;
2665 p->client_machine = (
char *)
nullptr;
2666 p->icon_sizes =
nullptr;
2667 p->activities = (
char *)
nullptr;
2668 p->desktop_file =
nullptr;
2669 p->appmenu_object_path =
nullptr;
2670 p->appmenu_service_name =
nullptr;
2671 p->blockCompositing =
false;
2675 p->protocols = NET::NoProtocol;
2681 p->properties = properties;
2688 update(p->properties);
2713 fprintf(stderr,
"NETWinInfo::operator=()\n");
2716 if (p != wininfo.p) {
2732 setIconInternal(p->icons, p->icon_count, p->atom(_NET_WM_ICON), icon, replace);
2735 void NETWinInfo::setIconInternal(NETRArray<NETIcon> &icons,
int &icon_count, xcb_atom_t
property,
NETIcon icon,
bool replace)
2737 if (p->role != Client) {
2742 for (
int i = 0; i < icons.size(); i++) {
2743 delete [] icons[i].data;
2745 icons[i].data =
nullptr;
2746 icons[i].size.width = 0;
2747 icons[i].size.height = 0;
2754 icons[icon_count] = icon;
2758 NETIcon &ni = icons[icon_count - 1];
2760 uint32_t *d =
new uint32_t[sz];
2761 ni.
data = (
unsigned char *) d;
2762 memcpy(d, icon.
data, sz *
sizeof(uint32_t));
2766 for (
int i = 0; i < icon_count; i++) {
2767 proplen += 2 + (icons[i].size.width *
2768 icons[i].size.height);
2771 uint32_t *prop =
new uint32_t[proplen], *pprop = prop;
2772 for (
int i = 0; i < icon_count; i++) {
2774 *pprop++ = icons[i].size.width;
2775 *pprop++ = icons[i].size.height;
2778 sz = (icons[i].size.width * icons[i].size.height);
2779 uint32_t *d32 = (uint32_t *) icons[i].data;
2780 for (
int j = 0; j < sz; j++) {
2785 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, property,
2786 XCB_ATOM_CARDINAL, 32, proplen, (
const void *) prop);
2789 delete [] p->icon_sizes;
2790 p->icon_sizes =
nullptr;
2795 if (p->role != Client) {
2799 const qreal scaleFactor = qApp->devicePixelRatio();
2800 geometry.
pos.
x *= scaleFactor;
2801 geometry.
pos.
y *= scaleFactor;
2805 p->icon_geom = geometry;
2808 xcb_delete_property(p->conn, p->window, p->atom(_NET_WM_ICON_GEOMETRY));
2811 data[0] = geometry.
pos.
x;
2812 data[1] = geometry.
pos.
y;
2816 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_ICON_GEOMETRY),
2817 XCB_ATOM_CARDINAL, 32, 4, (
const void *) data);
2823 if (p->role != Client) {
2827 p->extended_strut = extended_strut;
2834 data[4] = extended_strut.left_start;
2835 data[5] = extended_strut.left_end;
2836 data[6] = extended_strut.right_start;
2837 data[7] = extended_strut.right_end;
2838 data[8] = extended_strut.top_start;
2839 data[9] = extended_strut.top_end;
2840 data[10] = extended_strut.bottom_start;
2841 data[11] = extended_strut.bottom_end;
2843 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_STRUT_PARTIAL),
2844 XCB_ATOM_CARDINAL, 32, 12, (
const void *) data);
2849 if (p->role != Client) {
2856 data[0] = strut.
left;
2857 data[1] = strut.
right;
2858 data[2] = strut.
top;
2861 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_STRUT),
2862 XCB_ATOM_CARDINAL, 32, 4, (
const void *) data);
2867 if (p->role == Client) {
2868 const uint32_t data[5] = {
2869 uint32_t(topology.
top), uint32_t(topology.
bottom), uint32_t(topology.
left), uint32_t(topology.
right), 1
2872 send_client_message(p->conn, netwm_sendevent_mask, p->root, p->window, p->atom(_NET_WM_FULLSCREEN_MONITORS), data);
2874 p->fullscreen_monitors = topology;
2877 data[0] = topology.
top;
2878 data[1] = topology.
bottom;
2879 data[2] = topology.
left;
2880 data[3] = topology.
right;
2882 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_FULLSCREEN_MONITORS),
2883 XCB_ATOM_CARDINAL, 32, 4, (
const void *) data);
2889 if (p->mapping_state_dirty) {
2894 if ((p->properties & WMState) == 0) {
2895 p->properties |= WMState;
2899 p->properties &= ~WMState;
2902 if (p->role == Client && p->mapping_state != Withdrawn) {
2905 fprintf(stderr,
"NETWinInfo::setState (0x%lx, 0x%lx) (Client)\n",
2907 #endif // NETWMDEBUG 2909 xcb_client_message_event_t
event;
2910 event.response_type = XCB_CLIENT_MESSAGE;
2913 event.window = p->window;
2914 event.type = p->atom(_NET_WM_STATE);
2915 event.data.data32[3] = 0;
2916 event.data.data32[4] = 0;
2918 if ((mask & Modal) && ((p->state & Modal) != (state & Modal))) {
2919 event.data.data32[0] = (state & Modal) ? 1 : 0;
2920 event.data.data32[1] = p->atom(_NET_WM_STATE_MODAL);
2921 event.data.data32[2] = 0l;
2923 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask, (
const char *) &event);
2926 if ((mask & Sticky) && ((p->state & Sticky) != (state & Sticky))) {
2927 event.data.data32[0] = (state & Sticky) ? 1 : 0;
2928 event.data.data32[1] = p->atom(_NET_WM_STATE_STICKY);
2929 event.data.data32[2] = 0l;
2931 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask, (
const char *) &event);
2934 if ((mask & Max) && (((p->state & mask) & Max) != (state & Max))) {
2936 NET::States wishstate = (p->state & ~mask) | (state & mask);
2937 if (((wishstate & MaxHoriz) != (p->state & MaxHoriz))
2938 && ((wishstate & MaxVert) != (p->state & MaxVert))) {
2939 if ((wishstate & Max) == Max) {
2940 event.data.data32[0] = 1;
2941 event.data.data32[1] = p->atom(_NET_WM_STATE_MAXIMIZED_HORZ);
2942 event.data.data32[2] = p->atom(_NET_WM_STATE_MAXIMIZED_VERT);
2943 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask, (
const char *) &event);
2944 }
else if ((wishstate & Max) == 0) {
2945 event.data.data32[0] = 0;
2946 event.data.data32[1] = p->atom(_NET_WM_STATE_MAXIMIZED_HORZ);
2947 event.data.data32[2] = p->atom(_NET_WM_STATE_MAXIMIZED_VERT);
2948 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask, (
const char *) &event);
2950 event.data.data32[0] = (wishstate & MaxHoriz) ? 1 : 0;
2951 event.data.data32[1] = p->atom(_NET_WM_STATE_MAXIMIZED_HORZ);
2952 event.data.data32[2] = 0;
2953 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask, (
const char *) &event);
2955 event.data.data32[0] = (wishstate & MaxVert) ? 1 : 0;
2956 event.data.data32[1] = p->atom(_NET_WM_STATE_MAXIMIZED_VERT);
2957 event.data.data32[2] = 0;
2958 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask, (
const char *) &event);
2960 }
else if ((wishstate & MaxVert) != (p->state & MaxVert)) {
2961 event.data.data32[0] = (wishstate & MaxVert) ? 1 : 0;
2962 event.data.data32[1] = p->atom(_NET_WM_STATE_MAXIMIZED_VERT);
2963 event.data.data32[2] = 0;
2965 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask, (
const char *) &event);
2966 }
else if ((wishstate & MaxHoriz) != (p->state & MaxHoriz)) {
2967 event.data.data32[0] = (wishstate & MaxHoriz) ? 1 : 0;
2968 event.data.data32[1] = p->atom(_NET_WM_STATE_MAXIMIZED_HORZ);
2969 event.data.data32[2] = 0;
2971 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask, (
const char *) &event);
2975 if ((mask & Shaded) && ((p->state & Shaded) != (state & Shaded))) {
2976 event.data.data32[0] = (state & Shaded) ? 1 : 0;
2977 event.data.data32[1] = p->atom(_NET_WM_STATE_SHADED);
2978 event.data.data32[2] = 0l;
2980 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask, (
const char *) &event);
2983 if ((mask & SkipTaskbar) && ((p->state & SkipTaskbar) != (state & SkipTaskbar))) {
2984 event.data.data32[0] = (state & SkipTaskbar) ? 1 : 0;
2985 event.data.data32[1] = p->atom(_NET_WM_STATE_SKIP_TASKBAR);
2986 event.data.data32[2] = 0l;
2988 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask, (
const char *) &event);
2991 if ((mask & SkipPager) && ((p->state & SkipPager) != (state & SkipPager))) {
2992 event.data.data32[0] = (state & SkipPager) ? 1 : 0;
2993 event.data.data32[1] = p->atom(_NET_WM_STATE_SKIP_PAGER);
2994 event.data.data32[2] = 0l;
2996 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask, (
const char *) &event);
2999 if ((mask & SkipSwitcher) && ((p->state & SkipSwitcher) != (state & SkipSwitcher))) {
3000 event.data.data32[0] = (state & SkipSwitcher) ? 1 : 0;
3001 event.data.data32[1] = p->atom(_KDE_NET_WM_STATE_SKIP_SWITCHER);
3002 event.data.data32[2] = 0l;
3004 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask, (
const char *) &event);
3007 if ((mask & Hidden) && ((p->state & Hidden) != (state & Hidden))) {
3008 event.data.data32[0] = (state & Hidden) ? 1 : 0;
3009 event.data.data32[1] = p->atom(_NET_WM_STATE_HIDDEN);
3010 event.data.data32[2] = 0l;
3012 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask, (
const char *) &event);
3015 if ((mask & FullScreen) && ((p->state & FullScreen) != (state & FullScreen))) {
3016 event.data.data32[0] = (state & FullScreen) ? 1 : 0;
3017 event.data.data32[1] = p->atom(_NET_WM_STATE_FULLSCREEN);
3018 event.data.data32[2] = 0l;
3020 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask, (
const char *) &event);
3023 if ((mask & KeepAbove) && ((p->state & KeepAbove) != (state & KeepAbove))) {
3024 event.data.data32[0] = (state & KeepAbove) ? 1 : 0;
3025 event.data.data32[1] = p->atom(_NET_WM_STATE_ABOVE);
3026 event.data.data32[2] = 0l;
3028 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask, (
const char *) &event);
3031 event.data.data32[0] = (state & KeepAbove) ? 1 : 0;
3032 event.data.data32[1] = p->atom(_NET_WM_STATE_STAYS_ON_TOP);
3033 event.data.data32[2] = 0l;
3035 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask, (
const char *) &event);
3038 if ((mask & KeepBelow) && ((p->state & KeepBelow) != (state & KeepBelow))) {
3039 event.data.data32[0] = (state & KeepBelow) ? 1 : 0;
3040 event.data.data32[1] = p->atom(_NET_WM_STATE_BELOW);
3041 event.data.data32[2] = 0l;
3043 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask, (
const char *) &event);
3046 if ((mask & DemandsAttention) && ((p->state & DemandsAttention) != (state & DemandsAttention))) {
3047 event.data.data32[0] = (state & DemandsAttention) ? 1 : 0;
3048 event.data.data32[1] = p->atom(_NET_WM_STATE_DEMANDS_ATTENTION);
3049 event.data.data32[2] = 0l;
3051 xcb_send_event(p->conn,
false, p->root, netwm_sendevent_mask, (
const char *) &event);
3063 if (p->state & Modal) {
3064 data[count++] = p->atom(_NET_WM_STATE_MODAL);
3066 if (p->state & MaxVert) {
3067 data[count++] = p->atom(_NET_WM_STATE_MAXIMIZED_VERT);
3069 if (p->state & MaxHoriz) {
3070 data[count++] = p->atom(_NET_WM_STATE_MAXIMIZED_HORZ);
3072 if (p->state & Shaded) {
3073 data[count++] = p->atom(_NET_WM_STATE_SHADED);
3075 if (p->state & Hidden) {
3076 data[count++] = p->atom(_NET_WM_STATE_HIDDEN);
3078 if (p->state & FullScreen) {
3079 data[count++] = p->atom(_NET_WM_STATE_FULLSCREEN);
3081 if (p->state & DemandsAttention) {
3082 data[count++] = p->atom(_NET_WM_STATE_DEMANDS_ATTENTION);
3084 if (p->state & Focused) {
3085 data[count++] = p->atom(_NET_WM_STATE_FOCUSED);
3089 if (p->state & KeepAbove) {
3090 data[count++] = p->atom(_NET_WM_STATE_ABOVE);
3092 data[count++] = p->atom(_NET_WM_STATE_STAYS_ON_TOP);
3094 if (p->state & KeepBelow) {
3095 data[count++] = p->atom(_NET_WM_STATE_BELOW);
3097 if (p->state & Sticky) {
3098 data[count++] = p->atom(_NET_WM_STATE_STICKY);
3100 if (p->state & SkipTaskbar) {
3101 data[count++] = p->atom(_NET_WM_STATE_SKIP_TASKBAR);
3103 if (p->state & SkipPager) {
3104 data[count++] = p->atom(_NET_WM_STATE_SKIP_PAGER);
3106 if (p->state & SkipSwitcher) {
3107 data[count++] = p->atom(_KDE_NET_WM_STATE_SKIP_SWITCHER);
3111 fprintf(stderr,
"NETWinInfo::setState: setting state property (%d)\n", count);
3112 for (
int i = 0; i < count; i++) {
3113 const QByteArray ba = get_atom_name(p->conn, data[i]);
3114 fprintf(stderr,
"NETWinInfo::setState: state %ld '%s'\n",
3119 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_STATE),
3120 XCB_ATOM_ATOM, 32, count, (
const void *) data);
3126 if (p->role != Client) {
3137 data[0] = p->atom(_KDE_NET_WM_WINDOW_TYPE_OVERRIDE);
3138 data[1] = p->atom(_NET_WM_WINDOW_TYPE_NORMAL);
3143 data[0] = p->atom(_NET_WM_WINDOW_TYPE_DIALOG);
3149 data[0] = p->atom(_NET_WM_WINDOW_TYPE_MENU);
3157 data[0] = p->atom(_KDE_NET_WM_WINDOW_TYPE_TOPMENU);
3158 data[1] = p->atom(_NET_WM_WINDOW_TYPE_DOCK);
3163 data[0] = p->atom(_NET_WM_WINDOW_TYPE_TOOLBAR);
3169 data[0] = p->atom(_NET_WM_WINDOW_TYPE_DOCK);
3175 data[0] = p->atom(_NET_WM_WINDOW_TYPE_DESKTOP);
3181 data[0] = p->atom(_NET_WM_WINDOW_TYPE_UTILITY);
3182 data[1] = p->atom(_NET_WM_WINDOW_TYPE_DIALOG);
3187 data[0] = p->atom(_NET_WM_WINDOW_TYPE_SPLASH);
3188 data[1] = p->atom(_NET_WM_WINDOW_TYPE_DOCK);
3193 data[0] = p->atom(_NET_WM_WINDOW_TYPE_DROPDOWN_MENU);
3194 data[1] = p->atom(_NET_WM_WINDOW_TYPE_MENU);
3199 data[0] = p->atom(_NET_WM_WINDOW_TYPE_POPUP_MENU);
3200 data[1] = p->atom(_NET_WM_WINDOW_TYPE_MENU);
3205 data[0] = p->atom(_NET_WM_WINDOW_TYPE_TOOLTIP);
3211 data[0] = p->atom(_NET_WM_WINDOW_TYPE_NOTIFICATION);
3212 data[1] = p->atom(_NET_WM_WINDOW_TYPE_UTILITY);
3217 data[0] = p->atom(_NET_WM_WINDOW_TYPE_COMBO);
3223 data[0] = p->atom(_NET_WM_WINDOW_TYPE_DND);
3228 case OnScreenDisplay:
3229 data[0] = p->atom(_KDE_NET_WM_WINDOW_TYPE_ON_SCREEN_DISPLAY);
3230 data[1] = p->atom(_NET_WM_WINDOW_TYPE_NOTIFICATION);
3234 case CriticalNotification:
3235 data[0] = p->atom(_KDE_NET_WM_WINDOW_TYPE_CRITICAL_NOTIFICATION);
3236 data[1] = p->atom(_NET_WM_WINDOW_TYPE_NOTIFICATION);
3242 data[0] = p->atom(_NET_WM_WINDOW_TYPE_NORMAL);
3248 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_WINDOW_TYPE),
3249 XCB_ATOM_ATOM, 32, len, (
const void *) &data);
3254 if (p->role != Client) {
3259 p->name = nstrdup(name);
3261 if (p->name[0] !=
'\0')
3262 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_NAME),
3263 p->atom(UTF8_STRING), 8, strlen(p->name), (
const void *) p->name);
3265 xcb_delete_property(p->conn, p->window, p->atom(_NET_WM_NAME));
3271 if (p->role != WindowManager) {
3275 delete [] p->visible_name;
3276 p->visible_name = nstrdup(visibleName);
3278 if (p->visible_name[0] !=
'\0')
3279 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_VISIBLE_NAME),
3280 p->atom(UTF8_STRING), 8, strlen(p->visible_name),
3281 (
const void *) p->visible_name);
3283 xcb_delete_property(p->conn, p->window, p->atom(_NET_WM_VISIBLE_NAME));
3289 if (p->role != Client) {
3293 delete [] p->icon_name;
3294 p->icon_name = nstrdup(iconName);
3296 if (p->icon_name[0] !=
'\0')
3297 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_ICON_NAME),
3298 p->atom(UTF8_STRING), 8, strlen(p->icon_name),
3299 (
const void *) p->icon_name);
3301 xcb_delete_property(p->conn, p->window, p->atom(_NET_WM_ICON_NAME));
3307 if (p->role != WindowManager) {
3311 delete [] p->visible_icon_name;
3312 p->visible_icon_name = nstrdup(visibleIconName);
3314 if (p->visible_icon_name[0] !=
'\0')
3315 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_VISIBLE_ICON_NAME),
3316 p->atom(UTF8_STRING), 8, strlen(p->visible_icon_name),
3317 (
const void *) p->visible_icon_name);
3319 xcb_delete_property(p->conn, p->window, p->atom(_NET_WM_VISIBLE_ICON_NAME));
3325 if (p->mapping_state_dirty) {
3329 if (p->role == Client && p->mapping_state != Withdrawn) {
3341 const uint32_t data[5] = {
3342 desktop == OnAllDesktops ? 0xffffffff : desktop - 1, 0, 0, 0, 0
3345 send_client_message(p->conn, netwm_sendevent_mask, p->root, p->window, p->atom(_NET_WM_DESKTOP), data);
3348 p->desktop = desktop;
3351 xcb_delete_property(p->conn, p->window, p->atom(_NET_WM_DESKTOP));
3353 uint32_t d = (desktop == OnAllDesktops ? 0xffffffff : desktop - 1);
3354 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_DESKTOP),
3355 XCB_ATOM_CARDINAL, 32, 1, (
const void *) &d);
3362 if (p->role != Client) {
3368 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_PID),
3369 XCB_ATOM_CARDINAL, 32, 1, (
const void *) &d);
3374 if (p->role != Client) {
3378 p->handled_icons = handled;
3379 uint32_t d = handled;
3380 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_HANDLED_ICONS),
3381 XCB_ATOM_CARDINAL, 32, 1, (
const void *) &d);
3386 if (p->role != Client) {
3390 delete[] p->startup_id;
3391 p->startup_id = nstrdup(
id);
3393 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_STARTUP_ID),
3394 p->atom(UTF8_STRING), 8, strlen(p->startup_id),
3395 (
const void *) p->startup_id);
3402 p->opacity = opacity;
3403 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_WINDOW_OPACITY),
3404 XCB_ATOM_CARDINAL, 32, 1, (
const void *) &p->opacity);
3409 if (p->role != WindowManager) {
3416 p->allowed_actions = actions;
3417 if (p->allowed_actions & ActionMove) {
3418 data[count++] = p->atom(_NET_WM_ACTION_MOVE);
3420 if (p->allowed_actions & ActionResize) {
3421 data[count++] = p->atom(_NET_WM_ACTION_RESIZE);
3423 if (p->allowed_actions & ActionMinimize) {
3424 data[count++] = p->atom(_NET_WM_ACTION_MINIMIZE);
3426 if (p->allowed_actions & ActionShade) {
3427 data[count++] = p->atom(_NET_WM_ACTION_SHADE);
3429 if (p->allowed_actions & ActionStick) {
3430 data[count++] = p->atom(_NET_WM_ACTION_STICK);
3432 if (p->allowed_actions & ActionMaxVert) {
3433 data[count++] = p->atom(_NET_WM_ACTION_MAXIMIZE_VERT);
3435 if (p->allowed_actions & ActionMaxHoriz) {
3436 data[count++] = p->atom(_NET_WM_ACTION_MAXIMIZE_HORZ);
3438 if (p->allowed_actions & ActionFullScreen) {
3439 data[count++] = p->atom(_NET_WM_ACTION_FULLSCREEN);
3441 if (p->allowed_actions & ActionChangeDesktop) {
3442 data[count++] = p->atom(_NET_WM_ACTION_CHANGE_DESKTOP);
3444 if (p->allowed_actions & ActionClose) {
3445 data[count++] = p->atom(_NET_WM_ACTION_CLOSE);
3449 fprintf(stderr,
"NETWinInfo::setAllowedActions: setting property (%d)\n", count);
3450 for (
int i = 0; i < count; i++) {
3451 const QByteArray ba = get_atom_name(p->conn, data[i]);
3452 fprintf(stderr,
"NETWinInfo::setAllowedActions: action %ld '%s'\n",
3457 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_ALLOWED_ACTIONS),
3458 XCB_ATOM_ATOM, 32, count, (
const void *) data);
3463 if (p->role != WindowManager) {
3467 p->frame_strut = strut;
3475 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_FRAME_EXTENTS),
3476 XCB_ATOM_CARDINAL, 32, 4, (
const void *) d);
3477 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_KDE_NET_WM_FRAME_STRUT),
3478 XCB_ATOM_CARDINAL, 32, 4, (
const void *) d);
3483 return p->frame_strut;
3488 if (strut.
left != -1 || strut.
top != -1 || strut.
right != -1 || strut.
bottom != -1) {
3490 strut.
top = qMax(0, strut.
top);
3495 p->frame_overlap = strut;
3503 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_FRAME_OVERLAP),
3504 XCB_ATOM_CARDINAL, 32, 4, (
const void *) d);
3509 return p->frame_overlap;
3514 p->gtk_frame_extents = strut;
3522 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_GTK_FRAME_EXTENTS),
3523 XCB_ATOM_CARDINAL, 32, 4, (
const void *) d);
3528 return p->gtk_frame_extents;
3533 if (p->role != Client) {
3537 delete[] p->appmenu_object_path;
3538 p->appmenu_object_path = nstrdup(name);
3540 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_KDE_NET_WM_APPMENU_OBJECT_PATH),
3541 XCB_ATOM_STRING, 8, strlen(p->appmenu_object_path),
3542 (
const void *) p->appmenu_object_path);
3547 if (p->role != Client) {
3551 delete[] p->appmenu_service_name;
3552 p->appmenu_service_name = nstrdup(name);
3554 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_KDE_NET_WM_APPMENU_SERVICE_NAME),
3555 XCB_ATOM_STRING, 8, strlen(p->appmenu_service_name),
3556 (
const void *) p->appmenu_service_name);
3561 return p->appmenu_object_path;
3566 return p->appmenu_service_name;
3571 if (p->win_geom.size.width == 0 || p->win_geom.size.height == 0) {
3572 const xcb_get_geometry_cookie_t geometry_cookie
3573 = xcb_get_geometry(p->conn, p->window);
3575 const xcb_translate_coordinates_cookie_t translate_cookie
3576 = xcb_translate_coordinates(p->conn, p->window, p->root, 0, 0);
3578 xcb_get_geometry_reply_t *geometry = xcb_get_geometry_reply(p->conn, geometry_cookie,
nullptr);
3579 xcb_translate_coordinates_reply_t *translated
3580 = xcb_translate_coordinates_reply(p->conn, translate_cookie,
nullptr);
3582 if (geometry && translated) {
3583 p->win_geom.pos.x = translated->dst_x;
3584 p->win_geom.pos.y = translated->dst_y;
3586 p->win_geom.size.width = geometry->width;
3587 p->win_geom.size.height = geometry->height;
3600 window = p->win_geom;
3602 frame.
pos.
x = window.
pos.
x - p->frame_strut.left;
3603 frame.
pos.
y = window.
pos.
y - p->frame_strut.top;
3610 return iconInternal(p->icons, p->icon_count, width, height);
3615 if (p->icon_sizes ==
nullptr) {
3616 p->icon_sizes =
new int[ p->icon_count * 2 + 2 ];
3620 p->icon_sizes[ i * 2 ] = p->icons[ i ].size.width;
3621 p->icon_sizes[ i * 2 + 1 ] = p->icons[ i ].size.height;
3623 p->icon_sizes[ p->icon_count * 2 ] = 0;
3624 p->icon_sizes[ p->icon_count * 2 + 1 ] = 0;
3626 return p->icon_sizes;
3629 NETIcon NETWinInfo::iconInternal(NETRArray<NETIcon> &icons,
int icon_count,
int width,
int height)
const 3636 result.
data =
nullptr;
3642 for (
int i = 1; i < icons.size(); i++) {
3643 if (icons[i].size.width >= result.
size.
width &&
3644 icons[i].size.height >= result.
size.
height) {
3650 if (width == -1 && height == -1) {
3655 for (
int i = 0; i < icons.size(); i++) {
3656 if ((icons[i].size.width >= width &&
3657 icons[i].size.width < result.
size.
width) &&
3658 (icons[i].size.height >= height &&
3659 icons[i].size.height < result.
size.
height)) {
3669 if (p->role != Client) {
3673 p->user_time = time;
3676 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_USER_TIME),
3677 XCB_ATOM_CARDINAL, 32, 1, (
const void *) &d);
3683 event(ev, &properties);
3691 bool do_update =
false;
3692 const uint8_t eventType =
event->response_type & ~0x80;
3694 if (p->role == WindowManager && eventType == XCB_CLIENT_MESSAGE &&
3695 reinterpret_cast<xcb_client_message_event_t *>(event)->format == 32) {
3696 xcb_client_message_event_t *message =
reinterpret_cast<xcb_client_message_event_t *
>(
event);
3698 fprintf(stderr,
"NETWinInfo::event: handling ClientMessage event\n");
3699 #endif // NETWMDEBUG 3701 if (message->type == p->atom(_NET_WM_STATE)) {
3708 "NETWinInfo::event: state client message, getting new state/mask\n");
3714 for (i = 1; i < 3; i++) {
3716 const QByteArray ba = get_atom_name(p->conn, (xcb_atom_t) message->data.data32[i]);
3717 fprintf(stderr,
"NETWinInfo::event: message %ld '%s'\n",
3718 message->data.data32[i], ba.
constData());
3721 if ((xcb_atom_t) message->data.data32[i] == p->atom(_NET_WM_STATE_MODAL)) {
3723 }
else if ((xcb_atom_t) message->data.data32[i] == p->atom(_NET_WM_STATE_STICKY)) {
3725 }
else if ((xcb_atom_t) message->data.data32[i] == p->atom(_NET_WM_STATE_MAXIMIZED_VERT)) {
3727 }
else if ((xcb_atom_t) message->data.data32[i] == p->atom(_NET_WM_STATE_MAXIMIZED_HORZ)) {
3729 }
else if ((xcb_atom_t) message->data.data32[i] == p->atom(_NET_WM_STATE_SHADED)) {
3731 }
else if ((xcb_atom_t) message->data.data32[i] == p->atom(_NET_WM_STATE_SKIP_TASKBAR)) {
3732 mask |= SkipTaskbar;
3733 }
else if ((xcb_atom_t) message->data.data32[i] == p->atom(_NET_WM_STATE_SKIP_PAGER)) {
3735 }
else if ((xcb_atom_t) message->data.data32[i] == p->atom(_KDE_NET_WM_STATE_SKIP_SWITCHER)) {
3736 mask |= SkipSwitcher;
3737 }
else if ((xcb_atom_t) message->data.data32[i] == p->atom(_NET_WM_STATE_HIDDEN)) {
3739 }
else if ((xcb_atom_t) message->data.data32[i] == p->atom(_NET_WM_STATE_FULLSCREEN)) {
3741 }
else if ((xcb_atom_t) message->data.data32[i] == p->atom(_NET_WM_STATE_ABOVE)) {
3743 }
else if ((xcb_atom_t) message->data.data32[i] == p->atom(_NET_WM_STATE_BELOW)) {
3745 }
else if ((xcb_atom_t) message->data.data32[i] == p->atom(_NET_WM_STATE_DEMANDS_ATTENTION)) {
3746 mask |= DemandsAttention;
3747 }
else if ((xcb_atom_t) message->data.data32[i] == p->atom(_NET_WM_STATE_STAYS_ON_TOP)) {
3749 }
else if ((xcb_atom_t) message->data.data32[i] == p->atom(_NET_WM_STATE_FOCUSED)) {
3755 switch (message->data.data32[0]) {
3763 state = (p->state & mask) ^ mask;
3772 fprintf(stderr,
"NETWinInfo::event: calling changeState(%lx, %lx)\n",
3776 changeState(state, mask);
3777 }
else if (message->type == p->atom(_NET_WM_DESKTOP)) {
3780 if (message->data.data32[0] == OnAllDesktops) {
3781 changeDesktop(OnAllDesktops);
3783 changeDesktop(message->data.data32[0] + 1);
3785 }
else if (message->type == p->atom(_NET_WM_FULLSCREEN_MONITORS)) {
3786 dirty2 = WM2FullscreenMonitors;
3789 topology.
top = message->data.data32[0];
3790 topology.
bottom = message->data.data32[1];
3791 topology.
left = message->data.data32[2];
3792 topology.
right = message->data.data32[3];
3795 fprintf(stderr,
"NETWinInfo2::event: calling changeFullscreenMonitors" 3796 "(%ld, %ld, %ld, %ld, %ld)\n",
3798 message->data.data32[0],
3799 message->data.data32[1],
3800 message->data.data32[2],
3801 message->data.data32[3]
3804 changeFullscreenMonitors(topology);
3808 if (eventType == XCB_PROPERTY_NOTIFY) {
3811 fprintf(stderr,
"NETWinInfo::event: handling PropertyNotify event\n");
3814 xcb_property_notify_event_t *pe =
reinterpret_cast<xcb_property_notify_event_t *
>(
event);
3816 if (pe->atom == p->atom(_NET_WM_NAME)) {
3818 }
else if (pe->atom == p->atom(_NET_WM_VISIBLE_NAME)) {
3819 dirty |= WMVisibleName;
3820 }
else if (pe->atom == p->atom(_NET_WM_DESKTOP)) {
3822 }
else if (pe->atom == p->atom(_NET_WM_WINDOW_TYPE)) {
3823 dirty |= WMWindowType;
3824 }
else if (pe->atom == p->atom(_NET_WM_STATE)) {
3826 }
else if (pe->atom == p->atom(_NET_WM_STRUT)) {
3828 }
else if (pe->atom == p->atom(_NET_WM_STRUT_PARTIAL)) {
3829 dirty2 |= WM2ExtendedStrut;
3830 }
else if (pe->atom == p->atom(_NET_WM_ICON_GEOMETRY)) {
3831 dirty |= WMIconGeometry;
3832 }
else if (pe->atom == p->atom(_NET_WM_ICON)) {
3834 }
else if (pe->atom == p->atom(_NET_WM_PID)) {
3836 }
else if (pe->atom == p->atom(_NET_WM_HANDLED_ICONS)) {
3837 dirty |= WMHandledIcons;
3838 }
else if (pe->atom == p->atom(_NET_STARTUP_ID)) {
3839 dirty2 |= WM2StartupId;
3840 }
else if (pe->atom == p->atom(_NET_WM_WINDOW_OPACITY)) {
3841 dirty2 |= WM2Opacity;
3842 }
else if (pe->atom == p->atom(_NET_WM_ALLOWED_ACTIONS)) {
3843 dirty2 |= WM2AllowedActions;
3844 }
else if (pe->atom == p->atom(WM_STATE)) {
3846 }
else if (pe->atom == p->atom(_NET_FRAME_EXTENTS)) {
3847 dirty |= WMFrameExtents;
3848 }
else if (pe->atom == p->atom(_KDE_NET_WM_FRAME_STRUT)) {
3849 dirty |= WMFrameExtents;
3850 }
else if (pe->atom == p->atom(_NET_WM_FRAME_OVERLAP)) {
3851 dirty2 |= WM2FrameOverlap;
3852 }
else if (pe->atom == p->atom(_NET_WM_ICON_NAME)) {
3853 dirty |= WMIconName;
3854 }
else if (pe->atom == p->atom(_NET_WM_VISIBLE_ICON_NAME)) {
3855 dirty |= WMVisibleIconName;
3856 }
else if (pe->atom == p->atom(_NET_WM_USER_TIME)) {
3857 dirty2 |= WM2UserTime;
3858 }
else if (pe->atom == XCB_ATOM_WM_HINTS) {
3859 dirty2 |= WM2GroupLeader;
3860 dirty2 |= WM2Urgency;
3862 dirty2 |= WM2InitialMappingState;
3863 dirty2 |= WM2IconPixmap;
3864 }
else if (pe->atom == XCB_ATOM_WM_TRANSIENT_FOR) {
3865 dirty2 |= WM2TransientFor;
3866 }
else if (pe->atom == XCB_ATOM_WM_CLASS) {
3867 dirty2 |= WM2WindowClass;
3868 }
else if (pe->atom == p->atom(WM_WINDOW_ROLE)) {
3869 dirty2 |= WM2WindowRole;
3870 }
else if (pe->atom == XCB_ATOM_WM_CLIENT_MACHINE) {
3871 dirty2 |= WM2ClientMachine;
3872 }
else if (pe->atom == p->atom(_KDE_NET_WM_ACTIVITIES)) {
3873 dirty2 |= WM2Activities;
3874 }
else if (pe->atom == p->atom(_KDE_NET_WM_BLOCK_COMPOSITING) ||
3875 pe->atom == p->atom(_NET_WM_BYPASS_COMPOSITOR)) {
3876 dirty2 |= WM2BlockCompositing;
3877 }
else if (pe->atom == p->atom(_KDE_NET_WM_SHADOW)) {
3878 dirty2 |= WM2KDEShadow;
3879 }
else if (pe->atom == p->atom(WM_PROTOCOLS)) {
3880 dirty2 |= WM2Protocols;
3881 }
else if (pe->atom == p->atom(_NET_WM_OPAQUE_REGION)) {
3882 dirty2 |= WM2OpaqueRegion;
3883 }
else if (pe->atom == p->atom(_KDE_NET_WM_DESKTOP_FILE)) {
3884 dirty2 = WM2DesktopFileName;
3885 }
else if (pe->atom == p->atom(_NET_WM_FULLSCREEN_MONITORS)) {
3886 dirty2 = WM2FullscreenMonitors;
3887 }
else if (pe->atom == p->atom(_GTK_FRAME_EXTENTS)) {
3888 dirty2 |= WM2GTKFrameExtents;
3889 }
else if (pe->atom == p->atom(_KDE_NET_WM_APPMENU_SERVICE_NAME)) {
3890 dirty2 |= WM2AppMenuServiceName;
3891 }
else if (pe->atom == p->atom(_KDE_NET_WM_APPMENU_OBJECT_PATH)) {
3892 dirty2 |= WM2AppMenuObjectPath;
3896 }
else if (eventType == XCB_CONFIGURE_NOTIFY) {
3899 fprintf(stderr,
"NETWinInfo::event: handling ConfigureNotify event\n");
3902 dirty |= WMGeometry;
3905 xcb_configure_notify_event_t *configure =
reinterpret_cast<xcb_configure_notify_event_t *
>(
event);
3906 p->win_geom.pos.x = configure->x;
3907 p->win_geom.pos.y = configure->y;
3908 p->win_geom.size.width = configure->width;
3909 p->win_geom.size.height = configure->height;
3913 update(dirty, dirty2);
3917 *properties = dirty;
3920 *properties2 = dirty2;
3924 #if KWINDOWSYSTEM_BUILD_DEPRECATED_SINCE(5, 0) 3930 unsigned long props[ PROPERTIES_SIZE ] = { p, p2 };
3931 assert(PROPERTIES_SIZE == 2);
3933 if (properties_size > PROPERTIES_SIZE) {
3934 properties_size = PROPERTIES_SIZE;
3937 i < properties_size;
3939 properties[ i ] = props[ i ];
3944 void NETWinInfo::updateWMState()
3951 Properties dirty = dirtyProperties & p->properties;
3952 Properties2 dirty2 = dirtyProperties2 & p->properties2;
3955 if (dirtyProperties & XAWMState) {
3959 xcb_get_property_cookie_t cookies[255];
3962 if (dirty & XAWMState) {
3963 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(WM_STATE), p->atom(WM_STATE), 0, 1);
3966 if (dirty & WMState) {
3967 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_STATE), XCB_ATOM_ATOM, 0, 2048);
3970 if (dirty & WMDesktop) {
3971 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_DESKTOP), XCB_ATOM_CARDINAL, 0, 1);
3974 if (dirty & WMName) {
3975 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_NAME), p->atom(UTF8_STRING), 0, MAX_PROP_SIZE);
3978 if (dirty & WMVisibleName) {
3979 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_VISIBLE_NAME), p->atom(UTF8_STRING), 0, MAX_PROP_SIZE);
3982 if (dirty & WMIconName) {
3983 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_ICON_NAME), p->atom(UTF8_STRING), 0, MAX_PROP_SIZE);
3986 if (dirty & WMVisibleIconName) {
3987 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);
3990 if (dirty & WMWindowType) {
3991 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_WINDOW_TYPE), XCB_ATOM_ATOM, 0, 2048);
3994 if (dirty & WMStrut) {
3995 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_STRUT), XCB_ATOM_CARDINAL, 0, 4);
3998 if (dirty2 & WM2ExtendedStrut) {
3999 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_STRUT_PARTIAL), XCB_ATOM_CARDINAL, 0, 12);
4002 if (dirty2 & WM2FullscreenMonitors) {
4003 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_FULLSCREEN_MONITORS), XCB_ATOM_CARDINAL, 0, 4);
4006 if (dirty & WMIconGeometry) {
4007 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_ICON_GEOMETRY), XCB_ATOM_CARDINAL, 0, 4);
4010 if (dirty & WMIcon) {
4011 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_ICON), XCB_ATOM_CARDINAL, 0, 0xffffffff);
4014 if (dirty & WMFrameExtents) {
4015 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_FRAME_EXTENTS), XCB_ATOM_CARDINAL, 0, 4);
4016 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_KDE_NET_WM_FRAME_STRUT), XCB_ATOM_CARDINAL, 0, 4);
4019 if (dirty2 & WM2FrameOverlap) {
4020 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_FRAME_OVERLAP), XCB_ATOM_CARDINAL, 0, 4);
4023 if (dirty2 & WM2Activities) {
4024 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_KDE_NET_WM_ACTIVITIES), XCB_ATOM_STRING, 0, MAX_PROP_SIZE);
4027 if (dirty2 & WM2BlockCompositing) {
4028 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_KDE_NET_WM_BLOCK_COMPOSITING), XCB_ATOM_CARDINAL, 0, 1);
4029 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_BYPASS_COMPOSITOR), XCB_ATOM_CARDINAL, 0, 1);
4032 if (dirty & WMPid) {
4033 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_PID), XCB_ATOM_CARDINAL, 0, 1);
4036 if (dirty2 & WM2StartupId) {
4037 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_STARTUP_ID), p->atom(UTF8_STRING), 0, MAX_PROP_SIZE);
4040 if (dirty2 & WM2Opacity) {
4041 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_WINDOW_OPACITY), XCB_ATOM_CARDINAL, 0, 1);
4044 if (dirty2 & WM2AllowedActions) {
4045 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_ALLOWED_ACTIONS), XCB_ATOM_ATOM, 0, 2048);
4048 if (dirty2 & WM2UserTime) {
4049 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_USER_TIME), XCB_ATOM_CARDINAL, 0, 1);
4052 if (dirty2 & WM2TransientFor) {
4053 cookies[c++] = xcb_get_property(p->conn,
false, p->window, XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 0, 1);
4056 if (dirty2 & (WM2GroupLeader | WM2Urgency | WM2Input | WM2InitialMappingState | WM2IconPixmap)) {
4057 cookies[c++] = xcb_get_property(p->conn,
false, p->window, XCB_ATOM_WM_HINTS, XCB_ATOM_WM_HINTS, 0, 9);
4060 if (dirty2 & WM2WindowClass) {
4061 cookies[c++] = xcb_get_property(p->conn,
false, p->window, XCB_ATOM_WM_CLASS, XCB_ATOM_STRING, 0, MAX_PROP_SIZE);
4064 if (dirty2 & WM2WindowRole) {
4065 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(WM_WINDOW_ROLE), XCB_ATOM_STRING, 0, MAX_PROP_SIZE);
4068 if (dirty2 & WM2ClientMachine) {
4069 cookies[c++] = xcb_get_property(p->conn,
false, p->window, XCB_ATOM_WM_CLIENT_MACHINE, XCB_ATOM_STRING, 0, MAX_PROP_SIZE);
4072 if (dirty2 & WM2Protocols) {
4073 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(WM_PROTOCOLS), XCB_ATOM_ATOM, 0, 2048);
4076 if (dirty2 & WM2OpaqueRegion) {
4077 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_NET_WM_OPAQUE_REGION), XCB_ATOM_CARDINAL, 0, MAX_PROP_SIZE);
4080 if (dirty2 & WM2DesktopFileName) {
4081 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);
4084 if (dirty2 & WM2GTKFrameExtents) {
4085 cookies[c++] = xcb_get_property(p->conn,
false, p->window, p->atom(_GTK_FRAME_EXTENTS), XCB_ATOM_CARDINAL, 0, 4);
4088 if (dirty2 & WM2AppMenuObjectPath) {
4089 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);
4092 if (dirty2 & WM2AppMenuServiceName) {
4093 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);
4098 if (dirty & XAWMState) {
4099 p->mapping_state = Withdrawn;
4102 uint32_t state = get_value_reply<uint32_t>(p->conn, cookies[c++], p->atom(WM_STATE), 0, &success);
4107 p->mapping_state = Iconic;
4111 p->mapping_state = Visible;
4116 p->mapping_state = Withdrawn;
4120 p->mapping_state_dirty =
false;
4124 if (dirty & WMState) {
4126 const QVector<xcb_atom_t> states = get_array_reply<xcb_atom_t>(p->conn, cookies[c++], XCB_ATOM_ATOM);
4129 fprintf(stderr,
"NETWinInfo::update: updating window state (%ld)\n", states.
count());
4132 for (
const xcb_atom_t state : states) {
4134 const QByteArray ba = get_atom_name(p->conn, state);
4135 fprintf(stderr,
"NETWinInfo::update: adding window state %ld '%s'\n",
4138 if (state == p->atom(_NET_WM_STATE_MODAL)) {
4142 else if (state == p->atom(_NET_WM_STATE_STICKY)) {
4146 else if (state == p->atom(_NET_WM_STATE_MAXIMIZED_VERT)) {
4147 p->state |= MaxVert;
4150 else if (state == p->atom(_NET_WM_STATE_MAXIMIZED_HORZ)) {
4151 p->state |= MaxHoriz;
4154 else if (state == p->atom(_NET_WM_STATE_SHADED)) {
4158 else if (state == p->atom(_NET_WM_STATE_SKIP_TASKBAR)) {
4159 p->state |= SkipTaskbar;
4162 else if (state == p->atom(_NET_WM_STATE_SKIP_PAGER)) {
4163 p->state |= SkipPager;
4166 else if (state == p->atom(_KDE_NET_WM_STATE_SKIP_SWITCHER)) {
4167 p->state |= SkipSwitcher;
4170 else if (state == p->atom(_NET_WM_STATE_HIDDEN)) {
4174 else if (state == p->atom(_NET_WM_STATE_FULLSCREEN)) {
4175 p->state |= FullScreen;
4178 else if (state == p->atom(_NET_WM_STATE_ABOVE)) {
4179 p->state |= KeepAbove;
4182 else if (state == p->atom(_NET_WM_STATE_BELOW)) {
4183 p->state |= KeepBelow;
4186 else if (state == p->atom(_NET_WM_STATE_DEMANDS_ATTENTION)) {
4187 p->state |= DemandsAttention;
4190 else if (state == p->atom(_NET_WM_STATE_STAYS_ON_TOP)) {
4191 p->state |= KeepAbove;
4194 else if (state == p->atom(_NET_WM_STATE_FOCUSED)) {
4195 p->state |= Focused;
4200 if (dirty & WMDesktop) {
4204 uint32_t desktop = get_value_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL, 0, &success);
4207 if (desktop != 0xffffffff) {
4208 p->desktop = desktop + 1;
4210 p->desktop = OnAllDesktops;
4215 if (dirty & WMName) {
4219 const QByteArray str = get_string_reply(p->conn, cookies[c++], p->atom(UTF8_STRING));
4225 if (dirty & WMVisibleName) {
4226 delete[] p->visible_name;
4227 p->visible_name =
nullptr;
4229 const QByteArray str = get_string_reply(p->conn, cookies[c++], p->atom(UTF8_STRING));
4235 if (dirty & WMIconName) {
4236 delete[] p->icon_name;
4237 p->icon_name =
nullptr;
4239 const QByteArray str = get_string_reply(p->conn, cookies[c++], p->atom(UTF8_STRING));
4245 if (dirty & WMVisibleIconName) {
4246 delete[] p->visible_icon_name;
4247 p->visible_icon_name =
nullptr;
4249 const QByteArray str = get_string_reply(p->conn, cookies[c++], p->atom(UTF8_STRING));
4255 if (dirty & WMWindowType) {
4257 p->types[0] = Unknown;
4258 p->has_net_support =
false;
4260 const QVector<xcb_atom_t> types = get_array_reply<xcb_atom_t>(p->conn, cookies[c++], XCB_ATOM_ATOM);
4264 fprintf(stderr,
"NETWinInfo::update: getting window type (%ld)\n", types.
count());
4266 p->has_net_support =
true;
4269 for (
const xcb_atom_t type : types) {
4271 const QByteArray name = get_atom_name(p->conn, type);
4272 fprintf(stderr,
"NETWinInfo::update: examining window type %ld %s\n",
4275 if (type == p->atom(_NET_WM_WINDOW_TYPE_NORMAL)) {
4276 p->types[pos++] = Normal;
4279 else if (type == p->atom(_NET_WM_WINDOW_TYPE_DESKTOP)) {
4280 p->types[pos++] = Desktop;
4283 else if (type == p->atom(_NET_WM_WINDOW_TYPE_DOCK)) {
4284 p->types[pos++] = Dock;
4287 else if (type == p->atom(_NET_WM_WINDOW_TYPE_TOOLBAR)) {
4288 p->types[pos++] = Toolbar;
4291 else if (type == p->atom(_NET_WM_WINDOW_TYPE_MENU)) {
4292 p->types[pos++] =
Menu;
4295 else if (type == p->atom(_NET_WM_WINDOW_TYPE_DIALOG)) {
4296 p->types[pos++] = Dialog;
4299 else if (type == p->atom(_NET_WM_WINDOW_TYPE_UTILITY)) {
4300 p->types[ pos++ ] = Utility;
4303 else if (type == p->atom(_NET_WM_WINDOW_TYPE_SPLASH)) {
4304 p->types[pos++] = Splash;
4307 else if (type == p->atom(_NET_WM_WINDOW_TYPE_DROPDOWN_MENU)) {
4308 p->types[pos++] = DropdownMenu;
4311 else if (type == p->atom(_NET_WM_WINDOW_TYPE_POPUP_MENU)) {
4312 p->types[pos++] = PopupMenu;
4315 else if (type == p->atom(_NET_WM_WINDOW_TYPE_TOOLTIP)) {
4316 p->types[pos++] = Tooltip;
4319 else if (type == p->atom(_NET_WM_WINDOW_TYPE_NOTIFICATION)) {
4320 p->types[pos++] = Notification;
4323 else if (type == p->atom(_NET_WM_WINDOW_TYPE_COMBO)) {
4324 p->types[pos++] = ComboBox;
4327 else if (type == p->atom(_NET_WM_WINDOW_TYPE_DND)) {
4328 p->types[pos++] = DNDIcon;
4331 else if (type == p->atom(_KDE_NET_WM_WINDOW_TYPE_OVERRIDE)) {
4332 p->types[pos++] = Override;
4335 else if (type == p->atom(_KDE_NET_WM_WINDOW_TYPE_TOPMENU)) {
4336 p->types[pos++] = TopMenu;
4339 else if (type == p->atom(_KDE_NET_WM_WINDOW_TYPE_ON_SCREEN_DISPLAY)) {
4340 p->types[pos++] = OnScreenDisplay;
4343 else if (type == p->atom(_KDE_NET_WM_WINDOW_TYPE_CRITICAL_NOTIFICATION)) {
4344 p->types[pos++] = CriticalNotification;
4350 if (dirty & WMStrut) {
4353 QVector<uint32_t> data = get_array_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL);
4354 if (data.
count() == 4) {
4355 p->strut.left = data[0];
4356 p->strut.right = data[1];
4357 p->strut.top = data[2];
4358 p->strut.bottom = data[3];
4362 if (dirty2 & WM2ExtendedStrut) {
4365 QVector<uint32_t> data = get_array_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL);
4366 if (data.
count() == 12) {
4367 p->extended_strut.left_width = data[0];
4368 p->extended_strut.right_width = data[1];
4369 p->extended_strut.top_width = data[2];
4370 p->extended_strut.bottom_width = data[3];
4371 p->extended_strut.left_start = data[4];
4372 p->extended_strut.left_end = data[5];
4373 p->extended_strut.right_start = data[6];
4374 p->extended_strut.right_end = data[7];
4375 p->extended_strut.top_start = data[8];
4376 p->extended_strut.top_end = data[9];
4377 p->extended_strut.bottom_start = data[10];
4378 p->extended_strut.bottom_end = data[11];
4382 if (dirty2 & WM2FullscreenMonitors) {
4385 QVector<uint32_t> data = get_array_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL);
4386 if (data.
count() == 4) {
4387 p->fullscreen_monitors.top = data[0];
4388 p->fullscreen_monitors.bottom = data[1];
4389 p->fullscreen_monitors.left = data[2];
4390 p->fullscreen_monitors.right = data[3];
4394 if (dirty & WMIconGeometry) {
4397 QVector<uint32_t> data = get_array_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL);
4398 if (data.
count() == 4) {
4399 p->icon_geom.pos.x = data[0];
4400 p->icon_geom.pos.y = data[1];
4401 p->icon_geom.
size.width = data[2];
4402 p->icon_geom.
size.height = data[3];
4406 if (dirty & WMIcon) {
4407 readIcon(p->conn, cookies[c++], p->icons, p->icon_count);
4408 delete[] p->icon_sizes;
4409 p->icon_sizes =
nullptr;
4412 if (dirty & WMFrameExtents) {
4415 QVector<uint32_t> data = get_array_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL);
4418 data = get_array_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL);
4420 xcb_discard_reply(p->conn, cookies[c++].sequence);
4423 if (data.
count() == 4) {
4424 p->frame_strut.left = data[0];
4425 p->frame_strut.right = data[1];
4426 p->frame_strut.top = data[2];
4427 p->frame_strut.bottom = data[3];
4431 if (dirty2 & WM2FrameOverlap) {
4434 QVector<uint32_t> data = get_array_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL);
4435 if (data.
count() == 4) {
4436 p->frame_overlap.left = data[0];
4437 p->frame_overlap.right = data[1];
4438 p->frame_overlap.top = data[2];
4439 p->frame_overlap.bottom = data[3];
4443 if (dirty2 & WM2Activities) {
4444 delete[] p->activities;
4445 p->activities =
nullptr;
4447 const QByteArray activities = get_string_reply(p->conn, cookies[c++], XCB_ATOM_STRING);
4448 if (activities.
length() > 0) {
4449 p->activities = nstrndup(activities.
constData(), activities.
length());
4453 if (dirty2 & WM2BlockCompositing) {
4455 p->blockCompositing =
false;
4458 uint32_t data = get_value_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL, 0, &success);
4460 p->blockCompositing = bool(data);
4463 data = get_value_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL, 0, &success);
4466 case 1: p->blockCompositing =
true;
break;
4467 case 2: p->blockCompositing =
false;
break;
4473 if (dirty & WMPid) {
4474 p->pid = get_value_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL, 0);
4477 if (dirty2 & WM2StartupId) {
4478 delete[] p->startup_id;
4479 p->startup_id =
nullptr;
4481 const QByteArray id = get_string_reply(p->conn, cookies[c++], p->atom(UTF8_STRING));
4482 if (
id.length() > 0) {
4483 p->startup_id = nstrndup(
id.constData(),
id.length());
4487 if (dirty2 & WM2Opacity) {
4488 p->opacity = get_value_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL, 0xffffffff);
4491 if (dirty2 & WM2AllowedActions) {
4494 const QVector<xcb_atom_t> actions = get_array_reply<xcb_atom_t>(p->conn, cookies[c++], XCB_ATOM_ATOM);
4497 fprintf(stderr,
"NETWinInfo::update: updating allowed actions (%ld)\n", actions.
count());
4500 for (
const xcb_atom_t action : actions) {
4502 const QByteArray name = get_atom_name(p->conn, action);
4504 "NETWinInfo::update: adding allowed action %ld '%s'\n",
4507 if (action == p->atom(_NET_WM_ACTION_MOVE)) {
4508 p->allowed_actions |= ActionMove;
4511 else if (action == p->atom(_NET_WM_ACTION_RESIZE)) {
4512 p->allowed_actions |= ActionResize;
4515 else if (action == p->atom(_NET_WM_ACTION_MINIMIZE)) {
4516 p->allowed_actions |= ActionMinimize;
4519 else if (action == p->atom(_NET_WM_ACTION_SHADE)) {
4520 p->allowed_actions |= ActionShade;
4523 else if (action == p->atom(_NET_WM_ACTION_STICK)) {
4524 p->allowed_actions |= ActionStick;
4527 else if (action == p->atom(_NET_WM_ACTION_MAXIMIZE_VERT)) {
4528 p->allowed_actions |= ActionMaxVert;
4531 else if (action == p->atom(_NET_WM_ACTION_MAXIMIZE_HORZ)) {
4532 p->allowed_actions |= ActionMaxHoriz;
4535 else if (action == p->atom(_NET_WM_ACTION_FULLSCREEN)) {
4536 p->allowed_actions |= ActionFullScreen;
4539 else if (action == p->atom(_NET_WM_ACTION_CHANGE_DESKTOP)) {
4540 p->allowed_actions |= ActionChangeDesktop;
4543 else if (action == p->atom(_NET_WM_ACTION_CLOSE)) {
4544 p->allowed_actions |= ActionClose;
4550 if (dirty2 & WM2UserTime) {
4554 uint32_t value = get_value_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL, 0, &success);
4557 p->user_time = value;
4561 if (dirty2 & WM2TransientFor) {
4562 p->transient_for = get_value_reply<xcb_window_t>(p->conn, cookies[c++], XCB_ATOM_WINDOW, 0);
4565 if (dirty2 & (WM2GroupLeader | WM2Urgency | WM2Input | WM2InitialMappingState | WM2IconPixmap)) {
4566 xcb_get_property_reply_t *reply = xcb_get_property_reply(p->conn, cookies[c++],
nullptr);
4568 if (reply && reply->format == 32 && reply->value_len == 9 && reply->type == XCB_ATOM_WM_HINTS) {
4569 kde_wm_hints *hints =
reinterpret_cast<kde_wm_hints *
>(xcb_get_property_value(reply));
4571 if (hints->flags & (1 << 0)) {
4572 p->input = hints->input;
4574 if (hints->flags & (1 << 1)) {
4575 switch (hints->initial_state) {
4577 p->initialMappingState = Iconic;
4581 p->initialMappingState = Visible;
4586 p->initialMappingState = Withdrawn;
4590 if (hints->flags & (1 << 2)) {
4591 p->icon_pixmap = hints->icon_pixmap;
4593 if (hints->flags & (1 << 5)) {
4594 p->icon_mask = hints->icon_mask;
4596 if (hints->flags & (1 << 6)) {
4597 p->window_group = hints->window_group;
4599 p->urgency = (hints->flags & (1 << 8));
4607 if (dirty2 & WM2WindowClass) {
4608 delete[] p->class_name;
4609 delete[] p->class_class;
4610 p->class_name =
nullptr;
4611 p->class_class =
nullptr;
4613 const QList<QByteArray> list = get_stringlist_reply(p->conn, cookies[c++], XCB_ATOM_STRING);
4614 if (list.
count() == 2) {
4615 p->class_name = nstrdup(list.
at(0).constData());
4616 p->class_class = nstrdup(list.
at(1).constData());
4620 if (dirty2 & WM2WindowRole) {
4621 delete[] p->window_role;
4622 p->window_role =
nullptr;
4624 const QByteArray role = get_string_reply(p->conn, cookies[c++], XCB_ATOM_STRING);
4630 if (dirty2 & WM2ClientMachine) {
4631 delete[] p->client_machine;
4632 p->client_machine =
nullptr;
4634 const QByteArray value = get_string_reply(p->conn, cookies[c++], XCB_ATOM_STRING);
4635 if (value.
length() > 0) {
4640 if (dirty2 & WM2Protocols) {
4641 const QVector<xcb_atom_t> protocols = get_array_reply<xcb_atom_t>(p->conn, cookies[c++], XCB_ATOM_ATOM);
4642 p->protocols = NET::NoProtocol;
4643 for (
auto it = protocols.
begin(); it != protocols.
end(); ++it) {
4644 if ((*it) == p->atom(WM_TAKE_FOCUS)) {
4645 p->protocols |= TakeFocusProtocol;
4646 }
else if ((*it) == p->atom(WM_DELETE_WINDOW)) {
4647 p->protocols |= DeleteWindowProtocol;
4648 }
else if ((*it) == p->atom(_NET_WM_PING)) {
4649 p->protocols |= PingProtocol;
4650 }
else if ((*it) == p->atom(_NET_WM_SYNC_REQUEST)) {
4651 p->protocols |= SyncRequestProtocol;
4652 }
else if ((*it) == p->atom(_NET_WM_CONTEXT_HELP)) {
4653 p->protocols |= ContextHelpProtocol;
4658 if (dirty2 & WM2OpaqueRegion) {
4660 p->opaqueRegion.clear();
4661 p->opaqueRegion.reserve(values.
count() / 4);
4662 for (
int i = 0; i < values.
count() - 3; i += 4) {
4664 rect.
pos.
x = values.
at(i);
4665 rect.
pos.
y = values.
at(i + 1);
4668 p->opaqueRegion.push_back(rect);
4672 if (dirty2 & WM2DesktopFileName) {
4673 delete[] p->desktop_file;
4674 p->desktop_file =
nullptr;
4676 const QByteArray id = get_string_reply(p->conn, cookies[c++], p->atom(UTF8_STRING));
4677 if (
id.length() > 0) {
4678 p->desktop_file = nstrndup(
id.constData(),
id.length());
4682 if (dirty2 & WM2GTKFrameExtents) {
4685 QVector<uint32_t> data = get_array_reply<uint32_t>(p->conn, cookies[c++], XCB_ATOM_CARDINAL);
4686 if (data.
count() == 4) {
4687 p->gtk_frame_extents.left = data[0];
4688 p->gtk_frame_extents.right = data[1];
4689 p->gtk_frame_extents.top = data[2];
4690 p->gtk_frame_extents.bottom = data[3];
4694 if (dirty2 & WM2AppMenuObjectPath) {
4695 delete[] p->appmenu_object_path;
4696 p->appmenu_object_path =
nullptr;
4698 const QByteArray id = get_string_reply(p->conn, cookies[c++], XCB_ATOM_STRING);
4699 if (
id.length() > 0) {
4700 p->appmenu_object_path = nstrndup(
id.constData(),
id.length());
4704 if (dirty2 & WM2AppMenuServiceName) {
4705 delete[] p->appmenu_service_name;
4706 p->appmenu_service_name =
nullptr;
4708 const QByteArray id = get_string_reply(p->conn, cookies[c++], XCB_ATOM_STRING);
4709 if (
id.length() > 0) {
4710 p->appmenu_service_name = nstrndup(
id.constData(),
id.length());
4717 return p->icon_geom;
4732 return p->extended_strut;
4737 return p->fullscreen_monitors;
4743 #define CHECK_TYPE_MASK( type ) \ 4745 if( mask & type##Mask ) \ 4748 CHECK_TYPE_MASK(Normal)
4749 CHECK_TYPE_MASK(Desktop)
4750 CHECK_TYPE_MASK(Dock)
4751 CHECK_TYPE_MASK(Toolbar)
4752 CHECK_TYPE_MASK(
Menu)
4753 CHECK_TYPE_MASK(Dialog)
4754 CHECK_TYPE_MASK(Override)
4755 CHECK_TYPE_MASK(TopMenu)
4756 CHECK_TYPE_MASK(Utility)
4757 CHECK_TYPE_MASK(Splash)
4758 CHECK_TYPE_MASK(DropdownMenu)
4759 CHECK_TYPE_MASK(PopupMenu)
4760 CHECK_TYPE_MASK(Tooltip)
4761 CHECK_TYPE_MASK(Notification)
4762 CHECK_TYPE_MASK(ComboBox)
4763 CHECK_TYPE_MASK(DNDIcon)
4764 CHECK_TYPE_MASK(OnScreenDisplay)
4765 CHECK_TYPE_MASK(CriticalNotification)
4766 #undef CHECK_TYPE_MASK 4776 i < p->types.size();
4779 if (typeMatchesMask(p->types[ i ], supported_types)) {
4780 return p->types[ i ];
4788 return p->types.size() > 0;
4798 return p->visible_name;
4803 return p->icon_name;
4808 return p->visible_icon_name;
4814 const KWindowInfo info(p->window, NET::WMDesktop);
4827 return p->user_time;
4832 return p->startup_id;
4842 return p->allowed_actions;
4847 return p->has_net_support;
4852 return p->transient_for;
4857 return p->window_group;
4872 return p->initialMappingState;
4877 return p->icon_pixmap;
4882 return p->icon_mask;
4887 return p->class_class;
4892 return p->class_name;
4897 return p->window_role;
4902 return p->client_machine;
4907 return p->activities;
4912 delete [] p->activities;
4914 if (activities == (
char *)
nullptr || activities[0] ==
'\0') {
4916 static const char nulluuid[] = KDE_ALL_ACTIVITIES_UUID;
4918 p->activities = nstrdup(nulluuid);
4921 p->activities = nstrdup(activities);
4925 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_KDE_NET_WM_ACTIVITIES),
4926 XCB_ATOM_STRING, 8, strlen(p->activities), p->activities);
4931 if (p->role != Client) {
4935 p->blockCompositing = active;
4938 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_KDE_NET_WM_BLOCK_COMPOSITING),
4939 XCB_ATOM_CARDINAL, 32, 1, (
const void *) &d);
4940 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_NET_WM_BYPASS_COMPOSITOR),
4941 XCB_ATOM_CARDINAL, 32, 1, (
const void *) &d);
4943 xcb_delete_property(p->conn, p->window, p->atom(_KDE_NET_WM_BLOCK_COMPOSITING));
4944 xcb_delete_property(p->conn, p->window, p->atom(_NET_WM_BYPASS_COMPOSITOR));
4950 return p->blockCompositing;
4955 return p->handled_icons;
4960 return p->properties;
4965 return p->properties2;
4970 return p->mapping_state;
4975 return p->protocols;
4980 return p->protocols.testFlag(protocol);
4985 return p->opaqueRegion;
4995 if (p->role != Client) {
4999 delete[] p->desktop_file;
5000 p->desktop_file = nstrdup(name);
5002 xcb_change_property(p->conn, XCB_PROP_MODE_REPLACE, p->window, p->atom(_KDE_NET_WM_DESKTOP_FILE),
5003 p->atom(UTF8_STRING), 8, strlen(p->desktop_file),
5004 (
const void *) p->desktop_file);
5009 return p->desktop_file;
5024 return KXUtils::timestampCompare(time1, time2);
5029 return KXUtils::timestampDiff(time1, time2);
QFlags< State > States
Stores a combination of State values.
Simple icon class for NET classes.
int numberOfDesktops(bool ignore_viewport=false) const
Returns the number of desktops.
const xcb_window_t * clientListStacking() const
Returns an array of Window id's, which contain all managed windows in stacking order.
Protocol
Protocols supported by the client.
void setAllowedActions(NET::Actions actions)
Sets actions that the window manager allows for the window.
virtual ~NETRootInfo()
Destroys the NETRootInfo object.
void setSupported(NET::Property property, bool on=true)
Sets the given property if on is true, and clears the property otherwise.
const char * clientMachine() const
Returns the client machine for the window (i.e.
void setDesktopFileName(const char *name)
Sets the name as the desktop file name.
void setActivities(const char *activities)
Sets the comma-separated list of activities the window is associated with.
void setCurrentDesktop(int desktop, bool ignore_viewport=false)
Sets the current desktop to the specified desktop.
int bottom
Bottom border of the strut.
NETPoint desktopViewport(int desktop) const
Returns the viewport 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.
void setFullscreenMonitors(NETFullscreenMonitors topology)
Sets the desired multiple-monitor topology (4 monitor indices indicating the top, bottom...
void setWindowType(WindowType type)
Sets the window type for this client (see the NET base class documentation for a description of the v...
const char * desktopFileName() const
int bottom_width
Bottom border of the strut, width and range.
Property2
Supported properties.
const xcb_window_t * virtualRoots() const
Returns an array of Window id's, which contain the virtual root windows.
int virtualRootsCount() const
Returns the number of window in the virtualRoots array.
void setShowingDesktop(bool showing)
Sets the _NET_SHOWING_DESKTOP status (whether desktop is being shown).
QList< QByteArray > split(char sep) const const
QSize desktopLayoutColumnsRows() const
Returns the desktop layout number of columns and rows.
int clientListStackingCount() const
Returns the number of managed windows in the clientListStacking array.
const NETRootInfo & operator=(const NETRootInfo &rootinfo)
Assignment operator.
QVector::iterator begin()
unsigned char * data
Image data for the icon.
xcb_window_t groupLeader() const
Returns the leader window for the group the window is in, if any.
QFlags< WindowTypeMask > WindowTypes
Stores a combination of WindowTypeMask values.
NET::Properties2 passedProperties2() const
MappingState mappingState() const
Returns the mapping state for the window (see the NET base class documentation for a description of m...
bool urgency() const
Returns whether the UrgencyHint is set in the WM_HINTS.flags.
static void setOnDesktop(WId win, int desktop)
Moves window win to desktop desktop.
NETExtendedStrut extendedStrut() const
Returns the extended (partial) strut specified by this client.
Simple multiple monitor topology class for NET classes.
void event(xcb_generic_event_t *event, unsigned long *properties, int properties_size)
This function takes the passed XEvent and returns an OR'ed list of NETRootInfo properties that have c...
NET::Actions allowedActions() const
Returns actions that the window manager allows for the window.
int right
Right border of the strut.
void activate()
Window Managers must call this after creating the NETRootInfo object, and before using any other meth...
void moveResizeRequest(xcb_window_t window, int x_root, int y_root, Direction direction)
Clients (such as pagers/taskbars) that wish to start a WMMoveResize (where the window manager control...
std::vector< NETRect > opaqueRegion() const
const T & at(int i) const const
NET::DesktopLayoutCorner desktopLayoutCorner() const
Returns the desktop layout starting corner.
void setAppMenuServiceName(const char *name)
Sets the name as the D-BUS service name for the application menu.
const char * windowClassName() const
Returns the name component of the window class for the window (i.e.
void setDesktopLayout(NET::Orientation orientation, int columns, int rows, NET::DesktopLayoutCorner corner)
Sets the desktop layout.
int clientListCount() const
Returns the number of managed windows in clientList array.
NET::Properties supportedProperties() const
In the Window Manager mode, this is equivalent to the properties argument passed to the constructor...
This class provides information about a given window in the platform specific windowing system...
bool showingDesktop() const
Returns the status of _NET_SHOWING_DESKTOP.
void setBlockingCompositing(bool active)
Sets whether the client wishes to block compositing (for better performance)
Partial strut class for NET classes.
int currentDesktop(bool ignore_viewport=false) const
Returns the current desktop.
int bottom
Monitor index whose bottom border defines the bottom edge of the topology.
NET::WindowTypes supportedWindowTypes() const
In the Window Manager mode, this is equivalent to the windowTypes argument passed to the constructor...
bool hasWindowType() const
This function returns false if the window has not window type specified at all.
void setClientList(const xcb_window_t *windows, unsigned int count)
Sets the list of managed windows on the Root/Desktop window.
xcb_timestamp_t userTime() const
Returns the time of last user action on the window, or -1 if not set.
Common API for root window properties/protocols.
QFlags< Property2 > Properties2
Stores a combination of Property2 values.
void setGtkFrameExtents(NETStrut strut)
Sets the extents of the drop-shadow drawn by the client.
NET::Properties2 passedProperties2() const
int left
Left border of the strut.
Direction
Direction for WMMoveResize.
void closeWindowRequest(xcb_window_t window)
Clients (such as pagers/taskbars) that wish to close a window should call this function.
virtual bool event(QEvent *e)
static bool typeMatchesMask(WindowType type, WindowTypes mask)
Returns true if the given window type matches the mask given using WindowTypeMask flags...
bool hasNETSupport() const
Returns true if the window has any window type set, even if the type itself is not known to this impl...
QVector< V > values(const QMultiHash< K, V > &c)
MappingState
Client window mapping state.
xcb_connection_t * xcbConnection() const
Returns the xcb connection used.
indicates that neither the client window nor its icon is visible.
int pid() const
Returns the process id for the client window.
int right
Monitor index whose right border defines the right edge of the topology.
NETIcon icon(int width=-1, int height=-1) const
Returns an icon.
void kdeGeometry(NETRect &frame, NETRect &window)
Places the window frame geometry in frame, and the application window geometry in window...
static int timestampCompare(unsigned long time1, unsigned long time2)
Compares two X timestamps, taking into account wrapping and 64bit architectures.
QFlags< Property > Properties
Stores a combination of Property values.
static int currentDesktop()
Returns the current virtual desktop.
NETFullscreenMonitors fullscreenMonitors() const
Returns the desired fullscreen monitor topology for this client, should it be in fullscreen state...
NETSize desktopGeometry() const
Returns the desktop geometry size.
int count(const T &value) const const
NETSize size
Size of the rectangle.
void append(const T &value)
void setWorkArea(int desktop, const NETRect &workArea)
Sets the workarea for the specified desktop.
void setIconGeometry(NETRect geometry)
Set the icon geometry for the application window.
xcb_connection_t * xcbConnection() const
Returns the xcb connection used.
NET::Actions supportedActions() const
In the Window Manager mode, this is equivalent to the actions argument passed to the constructor...
const NETWinInfo & operator=(const NETWinInfo &wintinfo)
Assignment operator.
QVariant property(const char *name) const const
const int * iconSizes() const
Returns a list of provided icon sizes.
void setOpacity(unsigned long opacity)
Sets opacity (0 = transparent, 0xffffffff = opaque ) on the window.
QCA_EXPORT bool isSupported(const char *features, const QString &provider=QString())
NETSize size
Size of the icon.
Property
Supported properties.
xcb_window_t rootWindow() const
Returns the Window id of the rootWindow.
NET::Protocols protocols() const
const char * wmName() const
Returns the name of the Window Manager.
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...
void event(xcb_generic_event_t *event, unsigned long *properties, int properties_size)
This function takes the passed XEvent and returns an OR'ed list of NETWinInfo properties that have ch...
const char * constData() const const
NETPoint pos
Position of the rectangle.
Simple point class for NET classes.
NET::States passedStates() const
int top
Monitor index whose top border defines the top edge of the topology.
xcb_window_t supportWindow() const
Returns the Window id of the supportWindow.
unsigned long opacity() const
Returns the opacity of the window.
NET::States supportedStates() const
In the Window Manager mode, this is equivalent to the states argument passed to the constructor...
const char * windowRole() const
Returns the window role for the window (i.e.
int top_width
Top border of the strut, width and range.
void setFrameExtents(NETStrut strut)
Set the frame decoration strut, i.e.
void setDesktopGeometry(const NETSize &geometry)
Sets the desktop geometry to the specified geometry.
bool isSupported(NET::Property property) const
Returns true if the given property is supported by the window manager.
static void setCurrentDesktop(int desktop)
Convenience function to set the current desktop to desktop.
virtual void virtual_hook(int id, void *data)
Virtual hook, used to add new "virtual" functions while maintaining binary compatibility.
const char * appMenuObjectPath() const
NET::Properties2 supportedProperties2() const
In the Window Manager mode, this is equivalent to the properties2 argument passed to the constructor...
NET::States state() const
Returns the state of the window (see the NET base class documentation for a description of the variou...
bool supportsProtocol(NET::Protocol protocol) const
int left
Monitor index whose left border defines the left edge of the topology.
xcb_pixmap_t icccmIconPixmapMask() const
Returns the mask for the icon pixmap as set in WM_HINTS.
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...
NETStrut frameExtents() const
Returns the frame decoration strut, i.e.
Simple rectangle class for NET classes.
void setFrameOverlap(NETStrut strut)
Sets the window frame overlap strut, i.e.
const char * startupId() const
Returns the startup notification id of the window.
NET::Properties passedProperties() const
void setIconName(const char *name)
Sets the iconic name for the application window.
void restackRequest(xcb_window_t window, RequestSource source, xcb_window_t above, int detail, xcb_timestamp_t timestamp)
Sends the _NET_RESTACK_WINDOW request.
int desktop(bool ignore_viewport=false) const
Returns the desktop where the window is residing.
const char * appMenuServiceName() const
void setAppMenuObjectPath(const char *path)
Sets the name as the D-BUS object path for the application menu.
void setExtendedStrut(const NETExtendedStrut &extended_strut)
Set the extended (partial) strut for the application window.
const T & at(int i) const const
NETRect workArea(int desktop) const
Returns the workArea for the specified desktop.
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...
bool input() const
Returns whether the Input flag is set in WM_HINTS.
bool isBlockingCompositing() const
Returns whether the client wishes to block compositing (for better performance)
static bool mapViewport()
NETStrut frameOverlap() const
Returns the frame overlap strut, i.e.
const char * activities() const
returns a comma-separated list of the activities the window is associated with.
const xcb_window_t * clientList() const
Returns an array of Window id's, which contain all managed windows.
NET::Orientation desktopLayoutOrientation() const
Returns the desktop layout orientation.
bool isEmpty() const const
static const int OnAllDesktops
Sentinel value to indicate that the client wishes to be visible on all desktops.
void setDesktopViewport(int desktop, const NETPoint &viewport)
Sets the viewport for the current desktop to the specified point.
const char * visibleIconName() const
Returns the visible iconic name as set by the window manager in UTF-8 format.
static int numberOfDesktops()
Returns the number of virtual desktops.
const char * name() const
Returns the name of the window in UTF-8 format.
virtual ~NETWinInfo()
Destroys the NETWinInfo object.
void setStartupId(const char *startup_id)
Sets the startup notification id id on the window.
void setNumberOfDesktops(int numberOfDesktops)
Sets the number of desktops to the specified number.
const char * iconName() const
Returns the iconic name of the window in UTF-8 format.
void setStrut(NETStrut strut)
int count(const T &value) const const
NET::Properties passedProperties() const
int right_width
Right border of the strut, width and range.
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 char * desktopName(int desktop) const
Returns the name for the specified desktop.
virtual void virtual_hook(int id, void *data)
Virtual hook, used to add new "virtual" functions while maintaining binary compatibility.
Action
Actions that can be done with a window (_NET_WM_ALLOWED_ACTIONS).
void setUserTime(xcb_timestamp_t time)
Sets user timestamp time on the window (property _NET_WM_USER_TIME).
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...
Common API for application window properties/protocols.
QFlags< Action > Actions
Stores a combination of Action values.
int left_width
Left border of the strut, width and range.
WindowTypeMask
Values for WindowType when they should be OR'ed together, e.g.
void setClientListStacking(const xcb_window_t *windows, unsigned int count)
Sets the list of managed windows in stacking order on the Root/Desktop window.
int desktop() const
Returns the virtual desktop this window is on.
bool handledIcons() const
Returns whether or not this client handles icons.
void setPid(int pid)
Set the application window's process id.
void setDesktop(int desktop, bool ignore_viewport=false)
Set which window the desktop is (should be) on.
void setIcon(NETIcon icon, bool replace=true)
Set icons for the application window.
NET::Actions passedActions() const
const char * windowClassClass() const
Returns the class component of the window class for the window (i.e.
NETRect iconGeometry() const
Returns the icon geometry.
MappingState initialMappingState() const
Returns the initial mapping state as set in WM_HINTS.
void setName(const char *name)
Sets the name for the application window.
const char * visibleName() const
Returns the visible name as set by the window manager in UTF-8 format.
DesktopLayoutCorner
Starting corner for desktop layout.
WindowType windowType(WindowTypes supported_types) const
Returns the window type for this client (see the NET base class documentation for a description of th...
xcb_pixmap_t icccmIconPixmap() const
Returns the icon pixmap as set in WM_HINTS.
xcb_window_t activeWindow() const
Returns the active (focused) window.
int top
Top border of the strut.
void setVisibleName(const char *visibleName)
For Window Managers only: set the visible name ( i.e.
void setVirtualRoots(const xcb_window_t *windows, unsigned int count)
Sets the list of virtual root windows on the root window.
RequestSource
Source of the request.
xcb_window_t transientFor() const
Returns the WM_TRANSIENT_FOR property for the window, i.e.
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...
Simple size class for NET classes.
NET::WindowTypes passedWindowTypes() const
KIOFILEWIDGETS_EXPORT QStringList list(const QString &fileClass)
void setVisibleIconName(const char *name)
For Window Managers only: set the visible iconic name ( i.e.
NETStrut gtkFrameExtents() const
Returns the extents of the drop-shadow drawn by a GTK client.
void setDesktopName(int desktop, const char *desktopName)
Sets the name of the specified desktop.
void setHandledIcons(bool handled)
Set whether this application window handles icons.