1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2 // EWMH.cc for Blackbox - an X11 Window manager
3 // Copyright (c) 2001 - 2005 Sean 'Shaleh' Perry <shaleh@debian.org>
4 // Copyright (c) 1997 - 2000, 2002 - 2005
5 // Bradley T Hughes <bhughes at trolltech.com>
7 // Permission is hereby granted, free of charge, to any person obtaining a
8 // copy of this software and associated documentation files (the "Software"),
9 // to deal in the Software without restriction, including without limitation
10 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 // and/or sell copies of the Software, and to permit persons to whom the
12 // Software is furnished to do so, subject to the following conditions:
14 // The above copyright notice and this permission notice shall be included in
15 // all copies or substantial portions of the Software.
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 // DEALINGS IN THE SOFTWARE.
27 #include <X11/Xatom.h>
33 bt::EWMH::EWMH(const Display
&_display
)
36 const struct AtomRef
{
40 { "UTF8_STRING", &utf8_string
},
41 { "_NET_SUPPORTED", &net_supported
},
42 { "_NET_CLIENT_LIST", &net_client_list
},
43 { "_NET_CLIENT_LIST_STACKING", &net_client_list_stacking
},
44 { "_NET_NUMBER_OF_DESKTOPS", &net_number_of_desktops
},
45 { "_NET_DESKTOP_GEOMETRY", &net_desktop_geometry
},
46 { "_NET_DESKTOP_VIEWPORT", &net_desktop_viewport
},
47 { "_NET_CURRENT_DESKTOP", &net_current_desktop
},
48 { "_NET_DESKTOP_NAMES", &net_desktop_names
},
49 { "_NET_ACTIVE_WINDOW", &net_active_window
},
50 { "_NET_WORKAREA", &net_workarea
},
51 { "_NET_SUPPORTING_WM_CHECK", &net_supporting_wm_check
},
52 { "_NET_VIRTUAL_ROOTS", &net_virtual_roots
},
53 { "_NET_DESKTOP_LAYOUT", &net_desktop_layout
},
54 { "_NET_SHOWING_DESKTOP", &net_showing_desktop
},
55 { "_NET_CLOSE_WINDOW", &net_close_window
},
56 { "_NET_MOVERESIZE_WINDOW", &net_moveresize_window
},
57 { "_NET_WM_MOVERESIZE", &net_wm_moveresize
},
58 { "_NET_RESTACK_WINDOW", &net_restack_window
},
59 { "_NET_REQUEST_FRAME_EXTENTS", &net_request_frame_extents
},
60 { "_NET_WM_NAME", &net_wm_name
},
61 { "_NET_WM_VISIBLE_NAME", &net_wm_visible_name
},
62 { "_NET_WM_ICON_NAME", &net_wm_icon_name
},
63 { "_NET_WM_VISIBLE_ICON_NAME", &net_wm_visible_icon_name
},
64 { "_NET_WM_DESKTOP", &net_wm_desktop
},
65 { "_NET_WM_WINDOW_TYPE", &net_wm_window_type
},
66 { "_NET_WM_WINDOW_TYPE_DESKTOP", &net_wm_window_type_desktop
},
67 { "_NET_WM_WINDOW_TYPE_DOCK", &net_wm_window_type_dock
},
68 { "_NET_WM_WINDOW_TYPE_TOOLBAR", &net_wm_window_type_toolbar
},
69 { "_NET_WM_WINDOW_TYPE_MENU", &net_wm_window_type_menu
},
70 { "_NET_WM_WINDOW_TYPE_UTILITY", &net_wm_window_type_utility
},
71 { "_NET_WM_WINDOW_TYPE_SPLASH", &net_wm_window_type_splash
},
72 { "_NET_WM_WINDOW_TYPE_DIALOG", &net_wm_window_type_dialog
},
73 { "_NET_WM_WINDOW_TYPE_NORMAL", &net_wm_window_type_normal
},
74 { "_NET_WM_STATE", &net_wm_state
},
75 { "_NET_WM_STATE_MODAL", &net_wm_state_modal
},
76 { "_NET_WM_STATE_STICKY", &net_wm_state_sticky
},
77 { "_NET_WM_STATE_MAXIMIZED_VERT", &net_wm_state_maximized_vert
},
78 { "_NET_WM_STATE_MAXIMIZED_HORZ", &net_wm_state_maximized_horz
},
79 { "_NET_WM_STATE_SHADED", &net_wm_state_shaded
},
80 { "_NET_WM_STATE_SKIP_TASKBAR", &net_wm_state_skip_taskbar
},
81 { "_NET_WM_STATE_SKIP_PAGER", &net_wm_state_skip_pager
},
82 { "_NET_WM_STATE_HIDDEN", &net_wm_state_hidden
},
83 { "_NET_WM_STATE_FULLSCREEN", &net_wm_state_fullscreen
},
84 { "_NET_WM_STATE_ABOVE", &net_wm_state_above
},
85 { "_NET_WM_STATE_BELOW", &net_wm_state_below
},
86 { "_NET_WM_STATE_DEMANDS_ATTENTION", &net_wm_state_demands_attention
},
87 { "_NET_WM_ALLOWED_ACTIONS", &net_wm_allowed_actions
},
88 { "_NET_WM_ACTION_MOVE", &net_wm_action_move
},
89 { "_NET_WM_ACTION_RESIZE", &net_wm_action_resize
},
90 { "_NET_WM_ACTION_MINIMIZE", &net_wm_action_minimize
},
91 { "_NET_WM_ACTION_SHADE", &net_wm_action_shade
},
92 { "_NET_WM_ACTION_STICK", &net_wm_action_stick
},
93 { "_NET_WM_ACTION_MAXIMIZE_HORZ", &net_wm_action_maximize_horz
},
94 { "_NET_WM_ACTION_MAXIMIZE_VERT", &net_wm_action_maximize_vert
},
95 { "_NET_WM_ACTION_FULLSCREEN", &net_wm_action_fullscreen
},
96 { "_NET_WM_ACTION_CHANGE_DESKTOP", &net_wm_action_change_desktop
},
97 { "_NET_WM_ACTION_CLOSE", &net_wm_action_close
},
98 { "_NET_WM_STRUT", &net_wm_strut
},
99 { "_NET_WM_STRUT_PARTIAL", &net_wm_strut_partial
},
100 { "_NET_WM_ICON_GEOMETRY", &net_wm_icon_geometry
},
101 { "_NET_WM_ICON", &net_wm_icon
},
102 { "_NET_WM_PID", &net_wm_pid
},
103 { "_NET_WM_HANDLED_ICONS", &net_wm_handled_icons
},
104 { "_NET_WM_USER_TIME", &net_wm_user_time
},
105 { "_NET_FRAME_EXTENTS", &net_frame_extents
},
106 { "_NET_WM_PING", &net_wm_ping
},
107 { "_NET_WM_SYNC_REQUEST", &net_wm_sync_request
}
110 static const int AtomCount
=
111 sizeof(refs
) / (sizeof(const char *) + sizeof(Atom
*));
112 char *names
[AtomCount
];
113 Atom atoms
[AtomCount
];
115 for (int i
= 0; i
< AtomCount
; ++i
)
116 names
[i
] = const_cast<char *>(refs
[i
].name
);
118 XInternAtoms(display
.XDisplay(), names
, AtomCount
, false, atoms
);
120 for (int i
= 0; i
< AtomCount
; ++i
)
121 *refs
[i
].atom
= atoms
[i
];
125 // root window properties
127 void bt::EWMH::setSupported(Window target
, Atom atoms
[],
128 unsigned int count
) const {
129 setProperty(target
, XA_ATOM
, net_supported
,
130 reinterpret_cast<unsigned char *>(atoms
), count
);
134 bool bt::EWMH::readSupported(Window target
, AtomList
& atoms
) const {
135 unsigned char* data
= 0;
136 unsigned long nitems
;
137 if (getListProperty(target
, XA_ATOM
, net_supported
, &data
, &nitems
)) {
138 Atom
* values
= reinterpret_cast<Atom
*>(data
);
140 atoms
.reserve(nitems
);
141 atoms
.assign(values
, values
+ nitems
);
146 return (!atoms
.empty());
150 void bt::EWMH::setClientList(Window target
, WindowList
& windows
) const {
151 setProperty(target
, XA_WINDOW
, net_client_list
,
152 reinterpret_cast<unsigned char *>(&windows
[0]), windows
.size());
156 bool bt::EWMH::readClientList(Window target
, WindowList
& windows
) const {
157 unsigned char* data
= 0;
158 unsigned long nitems
;
159 if (getListProperty(target
, XA_WINDOW
, net_client_list
, &data
, &nitems
)) {
160 Window
* values
= reinterpret_cast<Window
*>(data
);
162 windows
.reserve(nitems
);
163 windows
.assign(values
, values
+ nitems
);
168 return (!windows
.empty());
172 void bt::EWMH::setClientListStacking(Window target
,
173 WindowList
& windows
) const {
174 setProperty(target
, XA_WINDOW
, net_client_list_stacking
,
175 reinterpret_cast<unsigned char *>(&windows
[0]), windows
.size());
179 bool bt::EWMH::readClientListStacking(Window target
,
180 WindowList
& windows
) const {
181 unsigned char* data
= 0;
182 unsigned long nitems
;
183 if (getListProperty(target
, XA_WINDOW
, net_client_list_stacking
,
185 Window
* values
= reinterpret_cast<Window
*>(data
);
187 windows
.reserve(nitems
);
188 windows
.assign(values
, values
+ nitems
);
193 return (!windows
.empty());
197 void bt::EWMH::setNumberOfDesktops(Window target
, unsigned int number
) const {
198 const unsigned long x
= number
;
199 setProperty(target
, XA_CARDINAL
, net_number_of_desktops
,
200 reinterpret_cast<const unsigned char *>(&x
), 1);
204 bool bt::EWMH::readNumberOfDesktops(Window target
,
205 unsigned int* number
) const {
206 unsigned char* data
= 0;
207 if (getProperty(target
, XA_CARDINAL
, net_number_of_desktops
, &data
)) {
209 static_cast<unsigned int>(*(reinterpret_cast<unsigned long *>(data
)));
218 void bt::EWMH::setDesktopGeometry(Window target
,
220 unsigned int height
) const {
221 const unsigned long geometry
[] =
222 { static_cast<unsigned long>(width
), static_cast<unsigned long> (height
) };
223 setProperty(target
, XA_CARDINAL
, net_desktop_geometry
,
224 reinterpret_cast<const unsigned char *>(geometry
), 2);
228 bool bt::EWMH::readDesktopGeometry(Window target
,
230 unsigned int* height
) const {
231 unsigned char* data
= 0;
232 unsigned long nitems
;
233 if (getListProperty(target
, XA_CARDINAL
, net_desktop_geometry
,
234 &data
, &nitems
) && nitems
== 2) {
235 unsigned long *values
= reinterpret_cast<unsigned long *>(data
);
237 *width
= static_cast<unsigned int>(values
[0]);
238 *height
= static_cast<unsigned int>(values
[1]);
248 void bt::EWMH::setDesktopViewport(Window target
, int x
, int y
) const {
249 const unsigned long viewport
[] =
250 { static_cast<long>(x
), static_cast<long>(y
) };
251 setProperty(target
, XA_CARDINAL
, net_desktop_viewport
,
252 reinterpret_cast<const unsigned char *>(viewport
), 2);
256 bool bt::EWMH::readDesktopViewport(Window target
, int *x
, int *y
) const {
257 unsigned char* data
= 0;
258 unsigned long nitems
;
259 if (getListProperty(target
, XA_CARDINAL
, net_desktop_viewport
,
260 &data
, &nitems
) && nitems
== 2) {
261 const long * const values
= reinterpret_cast<long *>(data
);
263 *x
= static_cast<int>(values
[0]);
264 *y
= static_cast<int>(values
[1]);
274 void bt::EWMH::setWorkarea(Window target
, unsigned long workareas
[],
275 unsigned int count
) const {
276 setProperty(target
, XA_CARDINAL
, net_workarea
,
277 reinterpret_cast<unsigned char *>(workareas
), count
* 4);
281 void bt::EWMH::setCurrentDesktop(Window target
, unsigned int number
) const {
282 const unsigned long x
= static_cast<unsigned long>(number
);
283 setProperty(target
, XA_CARDINAL
, net_current_desktop
,
284 reinterpret_cast<const unsigned char *>(&x
), 1);
288 bool bt::EWMH::readCurrentDesktop(Window target
, unsigned int* number
) const {
289 unsigned char* data
= 0;
290 if (getProperty(target
, XA_CARDINAL
, net_current_desktop
, &data
)) {
292 static_cast<unsigned int>(*(reinterpret_cast<unsigned long *>(data
)));
301 void bt::EWMH::setDesktopNames(Window target
,
302 const std::vector
<bt::ustring
> &names
) const {
304 return; // cannot convert UTF-32 to UTF-8
307 std::vector
<bt::ustring
>::const_iterator it
= names
.begin();
308 const std::vector
<bt::ustring
>::const_iterator end
= names
.end();
309 for (; it
!= end
; ++it
)
310 s
+= toUtf8(*it
) + '\0';
312 XChangeProperty(display
.XDisplay(), target
, net_desktop_names
, utf8_string
,
314 reinterpret_cast<const unsigned char *>(s
.c_str()),
319 bool bt::EWMH::readDesktopNames(Window target
,
320 std::vector
<bt::ustring
> &names
) const {
322 return false; // cannot convert UTF-8 to UTF-32
324 unsigned char *data
= 0;
325 unsigned long nitems
;
326 if (getListProperty(target
, utf8_string
, net_desktop_names
,
327 &data
, &nitems
) && nitems
> 0) {
328 char *tmp
= reinterpret_cast<char *>(data
);
329 for (unsigned int i
= 0; i
< nitems
; ++i
) {
330 if (data
[i
] == '\0') {
331 const std::string
str(tmp
, reinterpret_cast<char *>(data
) + i
);
332 names
.push_back(toUtf32(str
));
333 tmp
= reinterpret_cast<char *>(data
) + i
+ 1;
339 return (!names
.empty());
343 void bt::EWMH::setActiveWindow(Window target
, Window data
) const {
344 setProperty(target
, XA_WINDOW
, net_active_window
,
345 reinterpret_cast<unsigned char *>(&data
), 1);
349 void bt::EWMH::setSupportingWMCheck(Window target
, Window data
) const {
350 setProperty(target
, XA_WINDOW
, net_supporting_wm_check
,
351 reinterpret_cast<unsigned char *>(&data
), 1);
355 bool bt::EWMH::readSupportingWMCheck(Window target
, Window
* window
) const {
356 unsigned char* data
= 0;
357 if (getProperty(target
, XA_WINDOW
, net_supporting_wm_check
, &data
)) {
358 *window
= * (reinterpret_cast<Window
*>(data
));
367 void bt::EWMH::setVirtualRoots(Window target
, WindowList
&windows
) const {
368 setProperty(target
, XA_WINDOW
, net_virtual_roots
,
369 reinterpret_cast<unsigned char *>(&windows
[0]), windows
.size());
373 bool bt::EWMH::readVirtualRoots(Window target
, WindowList
&windows
) const {
374 unsigned char* data
= 0;
375 unsigned long nitems
;
376 if (getListProperty(target
, XA_WINDOW
, net_virtual_roots
, &data
, &nitems
)) {
377 Window
* values
= reinterpret_cast<Window
*>(data
);
379 windows
.reserve(nitems
);
380 windows
.assign(values
, values
+ nitems
);
385 return (!windows
.empty());
389 // application properties
391 void bt::EWMH::setWMName(Window target
, const bt::ustring
&name
) const {
393 return; // cannot convert UTF-32 to UTF-8
395 const std::string utf8
= toUtf8(name
);
396 XChangeProperty(display
.XDisplay(), target
, net_wm_name
, utf8_string
,
398 reinterpret_cast<const unsigned char *>(utf8
.c_str()),
403 bool bt::EWMH::readWMName(Window target
, bt::ustring
&name
) const {
405 return false; // cannot convert UTF-8 to UTF-32
407 unsigned char* data
= 0;
408 unsigned long nitems
;
409 if (getListProperty(target
, utf8_string
, net_wm_name
,
410 &data
, &nitems
) && nitems
> 0) {
411 name
= toUtf32(reinterpret_cast<char*>(data
));
415 return (!name
.empty());
419 void bt::EWMH::setWMVisibleName(Window target
,
420 const bt::ustring
&name
) const {
422 return; // cannot convert UTF-32 to UTF-8
424 const std::string utf8
= toUtf8(name
);
425 XChangeProperty(display
.XDisplay(), target
, net_wm_visible_name
, utf8_string
,
427 reinterpret_cast<const unsigned char *>(utf8
.c_str()),
432 bool bt::EWMH::readWMIconName(Window target
, bt::ustring
&name
) const {
434 return false; // cannot convert UTF-8 to UTF-32
436 unsigned char* data
= 0;
437 unsigned long nitems
;
438 if (getListProperty(target
, utf8_string
, net_wm_icon_name
,
439 &data
, &nitems
) && nitems
> 0) {
440 name
= toUtf32(reinterpret_cast<char*>(data
));
444 return (!name
.empty());
448 void bt::EWMH::setWMVisibleIconName(Window target
,
449 const bt::ustring
&name
) const {
451 return; // cannot convert UTF-32 to UTF-8
453 const std::string utf8
= toUtf8(name
);
454 XChangeProperty(display
.XDisplay(), target
, net_wm_visible_icon_name
, utf8_string
,
456 reinterpret_cast<const unsigned char *>(utf8
.c_str()),
461 void bt::EWMH::setWMDesktop(Window target
, unsigned int desktop
) const {
462 const unsigned long x
= desktop
;
463 setProperty(target
, XA_CARDINAL
, net_wm_desktop
,
464 reinterpret_cast<const unsigned char *>(&x
), 1);
468 bool bt::EWMH::readWMDesktop(Window target
, unsigned int& desktop
) const {
469 unsigned char* data
= 0;
470 if (getProperty(target
, XA_CARDINAL
, net_wm_desktop
, &data
)) {
472 static_cast<unsigned int>(*(reinterpret_cast<unsigned long *>(data
)));
481 bool bt::EWMH::readWMWindowType(Window target
, AtomList
& types
) const {
482 unsigned char* data
= 0;
483 unsigned long nitems
;
484 if (getListProperty(target
, XA_ATOM
, net_wm_window_type
, &data
, &nitems
)) {
485 Atom
* values
= reinterpret_cast<Atom
*>(data
);
487 types
.reserve(nitems
);
488 types
.assign(values
, values
+ nitems
);
493 return (!types
.empty());
497 void bt::EWMH::setWMState(Window target
, AtomList
& atoms
) const {
498 setProperty(target
, XA_ATOM
, net_wm_state
,
499 reinterpret_cast<unsigned char *>(&(atoms
[0])), atoms
.size());
503 bool bt::EWMH::readWMState(Window target
, AtomList
& states
) const {
504 unsigned char* data
= 0;
505 unsigned long nitems
;
506 if (getListProperty(target
, XA_ATOM
, net_wm_state
, &data
, &nitems
)) {
507 Atom
* values
= reinterpret_cast<Atom
*>(data
);
509 states
.reserve(nitems
);
510 states
.assign(values
, values
+ nitems
);
515 return (!states
.empty());
519 void bt::EWMH::setWMAllowedActions(Window target
, AtomList
& atoms
) const {
520 setProperty(target
, XA_ATOM
, net_wm_allowed_actions
,
521 reinterpret_cast<unsigned char *>(&(atoms
[0])), atoms
.size());
525 bool bt::EWMH::readWMStrut(Window target
, Strut
* strut
) const {
528 unsigned long nitems
, bytes_left
;
531 int ret
= XGetWindowProperty(display
.XDisplay(), target
, net_wm_strut
,
533 XA_CARDINAL
, &atom_return
, &size
,
534 &nitems
, &bytes_left
, &data
);
535 if (ret
!= Success
|| nitems
< 4)
538 unsigned long* const values
= reinterpret_cast<unsigned long*>(data
);
540 strut
->left
= static_cast<unsigned int>(values
[0]);
541 strut
->right
= static_cast<unsigned int>(values
[1]);
542 strut
->top
= static_cast<unsigned int>(values
[2]);
543 strut
->bottom
= static_cast<unsigned int>(values
[3]);
551 bool bt::EWMH::readWMStrutPartial(Window target
, StrutPartial
* strut
) const {
554 unsigned long nitems
, bytes_left
;
557 int ret
= XGetWindowProperty(display
.XDisplay(), target
, net_wm_strut_partial
,
559 XA_CARDINAL
, &atom_return
, &size
,
560 &nitems
, &bytes_left
, &data
);
561 if (ret
!= Success
|| nitems
< 4)
564 unsigned long * const values
= reinterpret_cast<unsigned long *>(data
);
566 strut
->left
= static_cast<unsigned int>(values
[0]);
567 strut
->right
= static_cast<unsigned int>(values
[1]);
568 strut
->top
= static_cast<unsigned int>(values
[2]);
569 strut
->bottom
= static_cast<unsigned int>(values
[3]);
570 strut
->left_start
= static_cast<unsigned int>(values
[4]);
571 strut
->left_end
= static_cast<unsigned int>(values
[5]);
572 strut
->right_start
= static_cast<unsigned int>(values
[6]);
573 strut
->right_end
= static_cast<unsigned int>(values
[7]);
574 strut
->top_start
= static_cast<unsigned int>(values
[8]);
575 strut
->top_end
= static_cast<unsigned int>(values
[9]);
576 strut
->bottom_start
= static_cast<unsigned int>(values
[10]);
577 strut
->bottom_end
= static_cast<unsigned int>(values
[11]);
585 bool bt::EWMH::readWMIconGeometry(Window target
, int &x
, int &y
,
587 unsigned int &height
) const {
588 unsigned char *data
= 0;
589 unsigned long nitems
;
590 if (getListProperty(target
, XA_CARDINAL
, net_wm_icon_geometry
,
591 &data
, &nitems
) && nitems
== 4) {
592 unsigned long *values
= reinterpret_cast<unsigned long *>(data
);
594 x
= static_cast<int>(values
[0]);
595 y
= static_cast<int>(values
[1]);
596 width
= static_cast<unsigned int>(values
[2]);
597 height
= static_cast<unsigned int>(values
[3]);
607 bool bt::EWMH::readWMPid(Window target
, unsigned int &pid
) const {
608 unsigned char* data
= 0;
609 if (getProperty(target
, XA_CARDINAL
, net_wm_pid
, &data
)) {
611 static_cast<unsigned int>(*(reinterpret_cast<unsigned long *>(data
)));
620 bool bt::EWMH::readWMUserTime(Window target
, Time
&user_time
) const {
621 unsigned char* data
= 0;
622 if (getProperty(target
, XA_CARDINAL
, net_wm_user_time
, &data
)) {
623 user_time
= *(reinterpret_cast<unsigned long *>(data
));
634 void bt::EWMH::removeProperty(Window target
, Atom atom
) const {
635 XDeleteProperty(display
.XDisplay(), target
, atom
);
639 void bt::EWMH::setProperty(Window target
, Atom type
, Atom property
,
640 const unsigned char *data
,
641 unsigned long count
) const {
642 XChangeProperty(display
.XDisplay(), target
, property
, type
,
643 32, PropModeReplace
, data
, count
);
647 bool bt::EWMH::getProperty(Window target
, Atom type
, Atom property
,
648 unsigned char** data
) const {
651 unsigned long nitems
, bytes_left
;
653 int ret
= XGetWindowProperty(display
.XDisplay(), target
, property
,
655 type
, &atom_return
, &size
,
656 &nitems
, &bytes_left
, data
);
657 if (ret
!= Success
|| nitems
!= 1)
664 bool bt::EWMH::getListProperty(Window target
, Atom type
, Atom property
,
665 unsigned char** data
,
666 unsigned long* count
) const {
669 unsigned long nitems
, bytes_left
;
671 int ret
= XGetWindowProperty(display
.XDisplay(), target
, property
,
673 type
, &atom_return
, &size
,
674 &nitems
, &bytes_left
, data
);
675 if (ret
!= Success
|| nitems
< 1)
678 if (bytes_left
!= 0) {
680 unsigned long remain
= ((size
/ 8) * nitems
) + bytes_left
;
681 ret
= XGetWindowProperty(display
.XDisplay(), target
,
682 property
, 0l, remain
, false,
683 type
, &atom_return
, &size
,
684 &nitems
, &bytes_left
, data
);
694 bool bt::EWMH::isSupportedWMWindowType(Atom atom
) const {
696 the implementation looks silly I know. You are probably thinking
698 return (atom > net_wm_window_type && atom <= net_wm_window_type_normal)?".
699 Well the problem is it assumes the atoms were created in a contiguous
700 range. This happens to be true if we created them but could be false if we
701 were started after some EWMH app which allocated the windows in an odd
702 order. So the following is guaranteed to work even if it looks silly and
703 requires more effort to maintain.
705 return (atom
== net_wm_window_type_desktop
||
706 atom
== net_wm_window_type_dock
||
707 atom
== net_wm_window_type_toolbar
||
708 atom
== net_wm_window_type_menu
||
709 atom
== net_wm_window_type_utility
||
710 atom
== net_wm_window_type_splash
||
711 atom
== net_wm_window_type_dialog
||
712 atom
== net_wm_window_type_normal
);