• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdecore
 

tdecore

  • tdecore
netwm.cpp
1/*
2
3 Copyright (c) 2000 Troll Tech AS
4 Copyright (c) 2003 Lubos Lunak <l.lunak@kde.org>
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 and/or sell copies of the Software, and to permit persons to whom the
11 Software is furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
23
24*/
25
26//#define NETWMDEBUG
27
28#include <tqwidget.h>
29#include <tqapplication.h>
30#ifdef TQ_WS_X11 //FIXME
31
32#include "netwm.h"
33
34#include <string.h>
35#include <stdio.h>
36#include <assert.h>
37#include <stdlib.h>
38
39#include <X11/Xmd.h>
40
41#include "netwm_p.h"
42
43// UTF-8 string
44static Atom UTF8_STRING = 0;
45
46// root window properties
47static Atom net_supported = 0;
48static Atom net_client_list = 0;
49static Atom net_client_list_stacking = 0;
50static Atom net_desktop_geometry = 0;
51static Atom net_desktop_viewport = 0;
52static Atom net_current_desktop = 0;
53static Atom net_desktop_names = 0;
54static Atom net_number_of_desktops = 0;
55static Atom net_active_window = 0;
56static Atom net_workarea = 0;
57static Atom net_supporting_wm_check = 0;
58static Atom net_virtual_roots = 0;
59static Atom net_showing_desktop = 0;
60static Atom net_desktop_layout = 0;
61
62// root window messages
63static Atom net_close_window = 0;
64static Atom net_restack_window = 0;
65static Atom net_wm_moveresize = 0;
66static Atom net_moveresize_window = 0;
67
68// application window properties
69static Atom net_wm_name = 0;
70static Atom net_wm_visible_name = 0;
71static Atom net_wm_icon_name = 0;
72static Atom net_wm_visible_icon_name = 0;
73static Atom net_wm_desktop = 0;
74static Atom net_wm_window_type = 0;
75static Atom net_wm_state = 0;
76static Atom net_wm_strut = 0;
77static Atom net_wm_extended_strut = 0; // the atom is called _NET_WM_STRUT_PARTIAL
78static Atom net_wm_icon_geometry = 0;
79static Atom net_wm_icon = 0;
80static Atom net_wm_pid = 0;
81static Atom net_wm_user_time = 0;
82static Atom net_wm_handled_icons = 0;
83static Atom net_startup_id = 0;
84static Atom net_wm_allowed_actions = 0;
85static Atom wm_window_role = 0;
86static Atom net_frame_extents = 0;
87
88// KDE extensions
89static Atom kde_net_system_tray_windows = 0;
90static Atom kde_net_wm_system_tray_window_for = 0;
91static Atom kde_net_wm_frame_strut = 0;
92static Atom kde_net_wm_window_type_override = 0;
93static Atom kde_net_wm_window_type_topmenu = 0;
94static Atom kde_net_wm_temporary_rules = 0;
95
96// application protocols
97static Atom wm_protocols = 0;
98static Atom net_wm_ping = 0;
99static Atom net_wm_take_activity = 0;
100
101// application window types
102static Atom net_wm_window_type_normal = 0;
103static Atom net_wm_window_type_desktop = 0;
104static Atom net_wm_window_type_dock = 0;
105static Atom net_wm_window_type_toolbar = 0;
106static Atom net_wm_window_type_menu = 0;
107static Atom net_wm_window_type_dialog = 0;
108static Atom net_wm_window_type_utility = 0;
109static Atom net_wm_window_type_splash = 0;
110static Atom net_wm_window_type_dropdown_menu = 0;
111static Atom net_wm_window_type_popup_menu = 0;
112static Atom net_wm_window_type_tooltip = 0;
113static Atom net_wm_window_type_notification = 0;
114static Atom net_wm_window_type_combobox = 0;
115static Atom net_wm_window_type_dnd = 0;
116
117// application window state
118static Atom net_wm_state_modal = 0;
119static Atom net_wm_state_sticky = 0;
120static Atom net_wm_state_max_vert = 0;
121static Atom net_wm_state_max_horiz = 0;
122static Atom net_wm_state_shaded = 0;
123static Atom net_wm_state_skip_taskbar = 0;
124static Atom net_wm_state_skip_pager = 0;
125static Atom net_wm_state_hidden = 0;
126static Atom net_wm_state_fullscreen = 0;
127static Atom net_wm_state_above = 0;
128static Atom net_wm_state_below = 0;
129static Atom net_wm_state_demands_attention = 0;
130
131// allowed actions
132static Atom net_wm_action_move = 0;
133static Atom net_wm_action_resize = 0;
134static Atom net_wm_action_minimize = 0;
135static Atom net_wm_action_shade = 0;
136static Atom net_wm_action_stick = 0;
137static Atom net_wm_action_max_vert = 0;
138static Atom net_wm_action_max_horiz = 0;
139static Atom net_wm_action_fullscreen = 0;
140static Atom net_wm_action_change_desk = 0;
141static Atom net_wm_action_close = 0;
142
143// KDE extension that's not in the specs - Replaced by state_above now?
144static Atom net_wm_state_stays_on_top = 0;
145
146// used to determine whether application window is managed or not
147static Atom xa_wm_state = 0;
148
149// ability flags
150static Atom net_wm_full_placement = 0;
151
152static Bool netwm_atoms_created = False;
153const unsigned long netwm_sendevent_mask = (SubstructureRedirectMask|
154 SubstructureNotifyMask);
155
156
157const long MAX_PROP_SIZE = 100000;
158
159static char *nstrdup(const char *s1) {
160 if (! s1) return (char *) 0;
161
162 int l = strlen(s1) + 1;
163 char *s2 = new char[l];
164 strncpy(s2, s1, l);
165 return s2;
166}
167
168
169static char *nstrndup(const char *s1, int l) {
170 if (! s1 || l == 0) return (char *) 0;
171
172 char *s2 = new char[l+1];
173 strncpy(s2, s1, l);
174 s2[l] = '\0';
175 return s2;
176}
177
178
179static Window *nwindup(Window *w1, int n) {
180 if (! w1 || n == 0) return (Window *) 0;
181
182 Window *w2 = new Window[n];
183 while (n--) w2[n] = w1[n];
184 return w2;
185}
186
187
188static void refdec_nri(NETRootInfoPrivate *p) {
189
190#ifdef NETWMDEBUG
191 fprintf(stderr, "NET: decrementing NETRootInfoPrivate::ref (%d)\n", p->ref - 1);
192#endif
193
194 if (! --p->ref) {
195
196#ifdef NETWMDEBUG
197 fprintf(stderr, "NET: \tno more references, deleting\n");
198#endif
199
200 delete [] p->name;
201 delete [] p->stacking;
202 delete [] p->clients;
203 delete [] p->virtual_roots;
204 delete [] p->kde_system_tray_windows;
205
206 int i;
207 for (i = 0; i < p->desktop_names.size(); i++)
208 delete [] p->desktop_names[i];
209 }
210}
211
212
213static void refdec_nwi(NETWinInfoPrivate *p) {
214
215#ifdef NETWMDEBUG
216 fprintf(stderr, "NET: decrementing NETWinInfoPrivate::ref (%d)\n", p->ref - 1);
217#endif
218
219 if (! --p->ref) {
220
221#ifdef NETWMDEBUG
222 fprintf(stderr, "NET: \tno more references, deleting\n");
223#endif
224
225 delete [] p->name;
226 delete [] p->visible_name;
227 delete [] p->icon_name;
228 delete [] p->visible_icon_name;
229 delete [] p->startup_id;
230
231 int i;
232 for (i = 0; i < p->icons.size(); i++)
233 delete [] p->icons[i].data;
234 }
235}
236
237
238static int wcmp(const void *a, const void *b) {
239 return *((Window *) a) - *((Window *) b);
240}
241
242
243static const int netAtomCount = 85;
244static void create_atoms(Display *d) {
245 static const char * const names[netAtomCount] =
246 {
247 "UTF8_STRING",
248 "_NET_SUPPORTED",
249 "_NET_SUPPORTING_WM_CHECK",
250 "_NET_CLIENT_LIST",
251 "_NET_CLIENT_LIST_STACKING",
252 "_NET_NUMBER_OF_DESKTOPS",
253 "_NET_DESKTOP_GEOMETRY",
254 "_NET_DESKTOP_VIEWPORT",
255 "_NET_CURRENT_DESKTOP",
256 "_NET_DESKTOP_NAMES",
257 "_NET_ACTIVE_WINDOW",
258 "_NET_WORKAREA",
259 "_NET_VIRTUAL_ROOTS",
260 "_NET_DESKTOP_LAYOUT",
261 "_NET_SHOWING_DESKTOP",
262 "_NET_CLOSE_WINDOW",
263 "_NET_RESTACK_WINDOW",
264
265 "_NET_WM_MOVERESIZE",
266 "_NET_MOVERESIZE_WINDOW",
267 "_NET_WM_NAME",
268 "_NET_WM_VISIBLE_NAME",
269 "_NET_WM_ICON_NAME",
270 "_NET_WM_VISIBLE_ICON_NAME",
271 "_NET_WM_DESKTOP",
272 "_NET_WM_WINDOW_TYPE",
273 "_NET_WM_STATE",
274 "_NET_WM_STRUT",
275 "_NET_WM_STRUT_PARTIAL",
276 "_NET_WM_ICON_GEOMETRY",
277 "_NET_WM_ICON",
278 "_NET_WM_PID",
279 "_NET_WM_USER_TIME",
280 "_NET_WM_HANDLED_ICONS",
281 "_NET_STARTUP_ID",
282 "_NET_WM_ALLOWED_ACTIONS",
283 "_NET_WM_PING",
284 "_NET_WM_TAKE_ACTIVITY",
285 "WM_WINDOW_ROLE",
286 "_NET_FRAME_EXTENTS",
287
288 "_NET_WM_WINDOW_TYPE_NORMAL",
289 "_NET_WM_WINDOW_TYPE_DESKTOP",
290 "_NET_WM_WINDOW_TYPE_DOCK",
291 "_NET_WM_WINDOW_TYPE_TOOLBAR",
292 "_NET_WM_WINDOW_TYPE_MENU",
293 "_NET_WM_WINDOW_TYPE_DIALOG",
294 "_NET_WM_WINDOW_TYPE_UTILITY",
295 "_NET_WM_WINDOW_TYPE_SPLASH",
296 "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU",
297 "_NET_WM_WINDOW_TYPE_POPUP_MENU",
298 "_NET_WM_WINDOW_TYPE_TOOLTIP",
299 "_NET_WM_WINDOW_TYPE_NOTIFICATION",
300 "_NET_WM_WINDOW_TYPE_COMBOBOX",
301 "_NET_WM_WINDOW_TYPE_DND",
302
303 "_NET_WM_STATE_MODAL",
304 "_NET_WM_STATE_STICKY",
305 "_NET_WM_STATE_MAXIMIZED_VERT",
306 "_NET_WM_STATE_MAXIMIZED_HORZ",
307 "_NET_WM_STATE_SHADED",
308 "_NET_WM_STATE_SKIP_TASKBAR",
309 "_NET_WM_STATE_SKIP_PAGER",
310 "_NET_WM_STATE_HIDDEN",
311 "_NET_WM_STATE_FULLSCREEN",
312 "_NET_WM_STATE_ABOVE",
313 "_NET_WM_STATE_BELOW",
314 "_NET_WM_STATE_DEMANDS_ATTENTION",
315
316 "_NET_WM_ACTION_MOVE",
317 "_NET_WM_ACTION_RESIZE",
318 "_NET_WM_ACTION_MINIMIZE",
319 "_NET_WM_ACTION_SHADE",
320 "_NET_WM_ACTION_STICK",
321 "_NET_WM_ACTION_MAXIMIZE_VERT",
322 "_NET_WM_ACTION_MAXIMIZE_HORZ",
323 "_NET_WM_ACTION_FULLSCREEN",
324 "_NET_WM_ACTION_CHANGE_DESKTOP",
325 "_NET_WM_ACTION_CLOSE",
326
327 "_NET_WM_STATE_STAYS_ON_TOP",
328
329 "_KDE_NET_SYSTEM_TRAY_WINDOWS",
330 "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR",
331 "_KDE_NET_WM_FRAME_STRUT",
332 "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE",
333 "_KDE_NET_WM_WINDOW_TYPE_TOPMENU",
334 "_KDE_NET_WM_TEMPORARY_RULES",
335
336 "WM_STATE",
337 "WM_PROTOCOLS",
338
339 "_NET_WM_FULL_PLACEMENT"
340 };
341
342 Atom atoms[netAtomCount], *atomsp[netAtomCount] =
343 {
344 &UTF8_STRING,
345 &net_supported,
346 &net_supporting_wm_check,
347 &net_client_list,
348 &net_client_list_stacking,
349 &net_number_of_desktops,
350 &net_desktop_geometry,
351 &net_desktop_viewport,
352 &net_current_desktop,
353 &net_desktop_names,
354 &net_active_window,
355 &net_workarea,
356 &net_virtual_roots,
357 &net_desktop_layout,
358 &net_showing_desktop,
359 &net_close_window,
360 &net_restack_window,
361
362 &net_wm_moveresize,
363 &net_moveresize_window,
364 &net_wm_name,
365 &net_wm_visible_name,
366 &net_wm_icon_name,
367 &net_wm_visible_icon_name,
368 &net_wm_desktop,
369 &net_wm_window_type,
370 &net_wm_state,
371 &net_wm_strut,
372 &net_wm_extended_strut,
373 &net_wm_icon_geometry,
374 &net_wm_icon,
375 &net_wm_pid,
376 &net_wm_user_time,
377 &net_wm_handled_icons,
378 &net_startup_id,
379 &net_wm_allowed_actions,
380 &net_wm_ping,
381 &net_wm_take_activity,
382 &wm_window_role,
383 &net_frame_extents,
384
385 &net_wm_window_type_normal,
386 &net_wm_window_type_desktop,
387 &net_wm_window_type_dock,
388 &net_wm_window_type_toolbar,
389 &net_wm_window_type_menu,
390 &net_wm_window_type_dialog,
391 &net_wm_window_type_utility,
392 &net_wm_window_type_splash,
393 &net_wm_window_type_dropdown_menu,
394 &net_wm_window_type_popup_menu,
395 &net_wm_window_type_tooltip,
396 &net_wm_window_type_notification,
397 &net_wm_window_type_combobox,
398 &net_wm_window_type_dnd,
399
400 &net_wm_state_modal,
401 &net_wm_state_sticky,
402 &net_wm_state_max_vert,
403 &net_wm_state_max_horiz,
404 &net_wm_state_shaded,
405 &net_wm_state_skip_taskbar,
406 &net_wm_state_skip_pager,
407 &net_wm_state_hidden,
408 &net_wm_state_fullscreen,
409 &net_wm_state_above,
410 &net_wm_state_below,
411 &net_wm_state_demands_attention,
412
413 &net_wm_action_move,
414 &net_wm_action_resize,
415 &net_wm_action_minimize,
416 &net_wm_action_shade,
417 &net_wm_action_stick,
418 &net_wm_action_max_vert,
419 &net_wm_action_max_horiz,
420 &net_wm_action_fullscreen,
421 &net_wm_action_change_desk,
422 &net_wm_action_close,
423
424 &net_wm_state_stays_on_top,
425
426 &kde_net_system_tray_windows,
427 &kde_net_wm_system_tray_window_for,
428 &kde_net_wm_frame_strut,
429 &kde_net_wm_window_type_override,
430 &kde_net_wm_window_type_topmenu,
431 &kde_net_wm_temporary_rules,
432
433 &xa_wm_state,
434 &wm_protocols,
435
436 &net_wm_full_placement
437 };
438
439 assert( !netwm_atoms_created );
440
441 int i = netAtomCount;
442 while (i--)
443 atoms[i] = 0;
444
445 XInternAtoms(d, (char **) names, netAtomCount, False, atoms);
446
447 i = netAtomCount;
448 while (i--)
449 *atomsp[i] = atoms[i];
450
451 netwm_atoms_created = True;
452}
453
454
455static void readIcon(Display* display, Window window, Atom property, NETRArray<NETIcon>& icons, int& icon_count) {
456
457#ifdef NETWMDEBUG
458 fprintf(stderr, "NET: readIcon\n");
459#endif
460
461 Atom type_ret;
462 int format_ret;
463 unsigned long nitems_ret = 0, after_ret = 0;
464 unsigned char *data_ret = 0;
465
466 // reset
467 for (int i = 0; i < icons.size(); i++)
468 delete [] icons[i].data;
469 icons.reset();
470 icon_count = 0;
471
472 // allocate buffers
473 unsigned char *buffer = 0;
474 unsigned long offset = 0;
475 unsigned long buffer_offset = 0;
476 unsigned long bufsize = 0;
477
478 // read data
479 do {
480 if (XGetWindowProperty(display, window, property, offset,
481 MAX_PROP_SIZE, False, XA_CARDINAL, &type_ret,
482 &format_ret, &nitems_ret, &after_ret, &data_ret)
483 == Success) {
484 if (!bufsize)
485 {
486 if (nitems_ret < 3 || type_ret != XA_CARDINAL ||
487 format_ret != 32) {
488 // either we didn't get the property, or the property has less than
489 // 3 elements in it
490 // NOTE: 3 is the ABSOLUTE minimum:
491 // width = 1, height = 1, length(data) = 1 (width * height)
492 if ( data_ret )
493 XFree(data_ret);
494 return;
495 }
496
497 bufsize = nitems_ret * sizeof(long) + after_ret;
498 buffer = (unsigned char *) malloc(bufsize);
499 }
500 else if (buffer_offset + nitems_ret*sizeof(long) > bufsize)
501 {
502fprintf(stderr, "NETWM: Warning readIcon() needs buffer adjustment!\n");
503 bufsize = buffer_offset + nitems_ret * sizeof(long) + after_ret;
504 buffer = (unsigned char *) realloc(buffer, bufsize);
505 }
506 memcpy((buffer + buffer_offset), data_ret, nitems_ret * sizeof(long));
507 buffer_offset += nitems_ret * sizeof(long);
508 offset += nitems_ret;
509
510 if ( data_ret )
511 XFree(data_ret);
512 } else {
513 if (buffer)
514 free(buffer);
515 return; // Some error occurred cq. property didn't exist.
516 }
517 }
518 while (after_ret > 0);
519
520 CARD32 *data32;
521 unsigned long i, j, k, sz, s;
522 unsigned long *d = (unsigned long *) buffer;
523 for (i = 0, j = 0; i < bufsize;) {
524 icons[j].size.width = *d++;
525 i += sizeof(long);
526 icons[j].size.height = *d++;
527 i += sizeof(long);
528
529 sz = icons[j].size.width * icons[j].size.height;
530 s = sz * sizeof(long);
531
532 if ( i + s - 1 > bufsize || sz == 0 || sz > 1024 * 1024 ) {
533 break;
534 }
535
536 delete [] icons[j].data;
537 data32 = new CARD32[sz];
538 icons[j].data = (unsigned char *) data32;
539 for (k = 0; k < sz; k++, i += sizeof(long)) {
540 *data32++ = (CARD32) *d++;
541 }
542 j++;
543 icon_count++;
544 }
545
546#ifdef NETWMDEBUG
547 fprintf(stderr, "NET: readIcon got %d icons\n", icon_count);
548#endif
549
550 free(buffer);
551}
552
553
554template <class Z>
555NETRArray<Z>::NETRArray()
556 : sz(0), capacity(2)
557{
558 d = (Z*) calloc(capacity, sizeof(Z)); // allocate 2 elts and set to zero
559}
560
561
562template <class Z>
563NETRArray<Z>::~NETRArray() {
564 free(d);
565}
566
567
568template <class Z>
569void NETRArray<Z>::reset() {
570 sz = 0;
571 capacity = 2;
572 d = (Z*) realloc(d, sizeof(Z)*capacity);
573 memset( (void*) d, 0, sizeof(Z)*capacity );
574}
575
576template <class Z>
577Z &NETRArray<Z>::operator[](int index) {
578 if (index >= capacity) {
579 // allocate space for the new data
580 // open table has amortized O(1) access time
581 // when N elements appended consecutively -- exa
582 int newcapacity = 2*capacity > index+1 ? 2*capacity : index+1; // max
583 // copy into new larger memory block using realloc
584 d = (Z*) realloc(d, sizeof(Z)*newcapacity);
585 memset( (void*) &d[capacity], 0, sizeof(Z)*(newcapacity-capacity) );
586 capacity = newcapacity;
587 }
588 if (index >= sz) // at this point capacity>index
589 sz = index + 1;
590
591 return d[index];
592}
593
594
595// Construct a new NETRootInfo object.
596
597NETRootInfo::NETRootInfo(Display *display, Window supportWindow, const char *wmName,
598 const unsigned long properties[], int properties_size,
599 int screen, bool doActivate)
600{
601
602#ifdef NETWMDEBUG
603 fprintf(stderr, "NETRootInfo::NETRootInfo: using window manager constructor\n");
604#endif
605
606 p = new NETRootInfoPrivate;
607 p->ref = 1;
608
609 p->display = display;
610 p->name = nstrdup(wmName);
611
612 if (screen != -1) {
613 p->screen = screen;
614 } else {
615 p->screen = DefaultScreen(p->display);
616 }
617
618 p->root = RootWindow(p->display, p->screen);
619 p->supportwindow = supportWindow;
620 p->number_of_desktops = p->current_desktop = 0;
621 p->active = None;
622 p->clients = p->stacking = p->virtual_roots = (Window *) 0;
623 p->clients_count = p->stacking_count = p->virtual_roots_count = 0;
624 p->kde_system_tray_windows = 0;
625 p->kde_system_tray_windows_count = 0;
626 p->showing_desktop = false;
627 p->desktop_layout_orientation = OrientationHorizontal;
628 p->desktop_layout_corner = DesktopLayoutCornerTopLeft;
629 p->desktop_layout_columns = p->desktop_layout_rows = 0;
630 setDefaultProperties();
631 if( properties_size > PROPERTIES_SIZE ) {
632 fprintf( stderr, "[netwm] NETRootInfo::NETRootInfo(): properties array too large\n");
633 properties_size = PROPERTIES_SIZE;
634 }
635 for( int i = 0; i < properties_size; ++i )
636 p->properties[ i ] = properties[ i ];
637 // force support for Supported and SupportingWMCheck for window managers
638 p->properties[ PROTOCOLS ] |= ( Supported | SupportingWMCheck );
639 p->client_properties[ PROTOCOLS ] = DesktopNames // the only thing that can be changed by clients
640 | WMPing; // or they can reply to this
641 p->client_properties[ PROTOCOLS2 ] = WM2TakeActivity | WM2DesktopLayout;
642
643 role = WindowManager;
644
645 if (! netwm_atoms_created) create_atoms(p->display);
646
647 if (doActivate) activate();
648}
649
650NETRootInfo::NETRootInfo(Display *display, Window supportWindow, const char *wmName,
651 unsigned long properties, int screen, bool doActivate)
652{
653
654#ifdef NETWMDEBUG
655 fprintf(stderr, "NETRootInfo::NETRootInfo: using window manager constructor\n");
656#endif
657
658 p = new NETRootInfoPrivate;
659 p->ref = 1;
660
661 p->display = display;
662 p->name = nstrdup(wmName);
663
664 if (screen != -1) {
665 p->screen = screen;
666 } else {
667 p->screen = DefaultScreen(p->display);
668 }
669
670 p->root = RootWindow(p->display, p->screen);
671 p->supportwindow = supportWindow;
672 p->number_of_desktops = p->current_desktop = 0;
673 p->active = None;
674 p->clients = p->stacking = p->virtual_roots = (Window *) 0;
675 p->clients_count = p->stacking_count = p->virtual_roots_count = 0;
676 p->kde_system_tray_windows = 0;
677 p->kde_system_tray_windows_count = 0;
678 p->showing_desktop = false;
679 setDefaultProperties();
680 p->properties[ PROTOCOLS ] = properties;
681 // force support for Supported and SupportingWMCheck for window managers
682 p->properties[ PROTOCOLS ] |= ( Supported | SupportingWMCheck );
683 p->client_properties[ PROTOCOLS ] = DesktopNames // the only thing that can be changed by clients
684 | WMPing; // or they can reply to this
685 p->client_properties[ PROTOCOLS2 ] = WM2TakeActivity;
686
687 role = WindowManager;
688
689 if (! netwm_atoms_created) create_atoms(p->display);
690
691 if (doActivate) activate();
692}
693
694
695NETRootInfo::NETRootInfo(Display *display, const unsigned long properties[], int properties_size,
696 int screen, bool doActivate)
697{
698
699#ifdef NETWMDEBUG
700 fprintf(stderr, "NETRootInfo::NETRootInfo: using Client constructor\n");
701#endif
702
703 p = new NETRootInfoPrivate;
704 p->ref = 1;
705
706 p->name = 0;
707
708 p->display = display;
709
710 if (screen != -1) {
711 p->screen = screen;
712 } else {
713 p->screen = DefaultScreen(p->display);
714 }
715
716 p->root = RootWindow(p->display, p->screen);
717 p->rootSize.width = WidthOfScreen(ScreenOfDisplay(p->display, p->screen));
718 p->rootSize.height = HeightOfScreen(ScreenOfDisplay(p->display, p->screen));
719
720 p->supportwindow = None;
721 p->number_of_desktops = p->current_desktop = 0;
722 p->active = None;
723 p->clients = p->stacking = p->virtual_roots = (Window *) 0;
724 p->clients_count = p->stacking_count = p->virtual_roots_count = 0;
725 p->kde_system_tray_windows = 0;
726 p->kde_system_tray_windows_count = 0;
727 p->showing_desktop = false;
728 p->desktop_layout_orientation = OrientationHorizontal;
729 p->desktop_layout_corner = DesktopLayoutCornerTopLeft;
730 p->desktop_layout_columns = p->desktop_layout_rows = 0;
731 setDefaultProperties();
732 if( properties_size > 2 ) {
733 fprintf( stderr, "[netwm] NETWinInfo::NETWinInfo(): properties array too large\n");
734 properties_size = 2;
735 }
736 for( int i = 0; i < properties_size; ++i )
737 // remap from [0]=NET::Property,[1]=NET::Property2
738 switch( i ) {
739 case 0:
740 p->client_properties[ PROTOCOLS ] = properties[ i ];
741 break;
742 case 1:
743 p->client_properties[ PROTOCOLS2 ] = properties[ i ];
744 break;
745 }
746 for( int i = 0; i < PROPERTIES_SIZE; ++i )
747 p->properties[ i ] = 0;
748
749 role = Client;
750
751 if (! netwm_atoms_created) create_atoms(p->display);
752
753 if (doActivate) activate();
754}
755
756NETRootInfo::NETRootInfo(Display *display, unsigned long properties, int screen,
757 bool doActivate)
758{
759
760#ifdef NETWMDEBUG
761 fprintf(stderr, "NETRootInfo::NETRootInfo: using Client constructor\n");
762#endif
763
764 p = new NETRootInfoPrivate;
765 p->ref = 1;
766
767 p->name = 0;
768
769 p->display = display;
770
771 if (screen != -1) {
772 p->screen = screen;
773 } else {
774 p->screen = DefaultScreen(p->display);
775 }
776
777 p->root = RootWindow(p->display, p->screen);
778 p->rootSize.width = WidthOfScreen(ScreenOfDisplay(p->display, p->screen));
779 p->rootSize.height = HeightOfScreen(ScreenOfDisplay(p->display, p->screen));
780
781 p->supportwindow = None;
782 p->number_of_desktops = p->current_desktop = 0;
783 p->active = None;
784 p->clients = p->stacking = p->virtual_roots = (Window *) 0;
785 p->clients_count = p->stacking_count = p->virtual_roots_count = 0;
786 p->kde_system_tray_windows = 0;
787 p->kde_system_tray_windows_count = 0;
788 p->showing_desktop = false;
789 p->desktop_layout_orientation = OrientationHorizontal;
790 p->desktop_layout_corner = DesktopLayoutCornerTopLeft;
791 p->desktop_layout_columns = p->desktop_layout_rows = 0;
792 setDefaultProperties();
793 p->client_properties[ PROTOCOLS ] = properties;
794 for( int i = 0; i < PROPERTIES_SIZE; ++i )
795 p->properties[ i ] = 0;
796
797 role = Client;
798
799 if (! netwm_atoms_created) create_atoms(p->display);
800
801 if (doActivate) activate();
802}
803
804
805NETRootInfo2::NETRootInfo2(Display *display, Window supportWindow, const char *wmName,
806 unsigned long properties[], int properties_size,
807 int screen, bool doActivate)
808 : NETRootInfo( display, supportWindow, wmName, properties, properties_size,
809 screen, doActivate )
810{
811}
812
813NETRootInfo2::NETRootInfo2(Display *display, const unsigned long properties[], int properties_size,
814 int screen, bool doActivate)
815 : NETRootInfo( display, properties, properties_size, screen, doActivate )
816{
817}
818
819NETRootInfo3::NETRootInfo3(Display *display, Window supportWindow, const char *wmName,
820 unsigned long properties[], int properties_size,
821 int screen, bool doActivate)
822 : NETRootInfo2( display, supportWindow, wmName, properties, properties_size,
823 screen, doActivate )
824{
825}
826
827NETRootInfo3::NETRootInfo3(Display *display, const unsigned long properties[], int properties_size,
828 int screen, bool doActivate)
829 : NETRootInfo2( display, properties, properties_size, screen, doActivate )
830{
831}
832
833NETRootInfo4::NETRootInfo4(Display *display, Window supportWindow, const char *wmName,
834 unsigned long properties[], int properties_size,
835 int screen, bool doActivate)
836 : NETRootInfo3( display, supportWindow, wmName, properties, properties_size,
837 screen, doActivate )
838{
839}
840
841NETRootInfo4::NETRootInfo4(Display *display, const unsigned long properties[], int properties_size,
842 int screen, bool doActivate)
843 : NETRootInfo3( display, properties, properties_size, screen, doActivate )
844{
845}
846
847// Copy an existing NETRootInfo object.
848
849NETRootInfo::NETRootInfo(const NETRootInfo &rootinfo) {
850
851#ifdef NETWMDEBUG
852 fprintf(stderr, "NETRootInfo::NETRootInfo: using copy constructor\n");
853#endif
854
855 p = rootinfo.p;
856 role = rootinfo.role;
857
858 p->ref++;
859}
860
861
862// Be gone with our NETRootInfo.
863
864NETRootInfo::~NETRootInfo() {
865 refdec_nri(p);
866
867 if (! p->ref) delete p;
868}
869
870
871void NETRootInfo::setDefaultProperties()
872{
873 p->properties[ PROTOCOLS ] = Supported | SupportingWMCheck;
874 p->properties[ WINDOW_TYPES ] = NormalMask | DesktopMask | DockMask
875 | ToolbarMask | MenuMask | DialogMask;
876 p->properties[ STATES ] = Modal | Sticky | MaxVert | MaxHoriz | Shaded
877 | SkipTaskbar | StaysOnTop;
878 p->properties[ PROTOCOLS2 ] = 0;
879 p->properties[ ACTIONS ] = 0;
880 p->client_properties[ PROTOCOLS ] = 0;
881 p->client_properties[ WINDOW_TYPES ] = 0; // these two actually don't
882 p->client_properties[ STATES ] = 0; // make sense in client_properties
883 p->client_properties[ PROTOCOLS2 ] = 0;
884 p->client_properties[ ACTIONS ] = 0;
885}
886
887void NETRootInfo::activate() {
888 if (role == WindowManager) {
889
890#ifdef NETWMDEBUG
891 fprintf(stderr,
892 "NETRootInfo::activate: setting supported properties on root\n");
893#endif
894
895 setSupported();
896 update(p->client_properties);
897 } else {
898
899#ifdef NETWMDEBUG
900 fprintf(stderr, "NETRootInfo::activate: updating client information\n");
901#endif
902
903 update(p->client_properties);
904 }
905}
906
907
908void NETRootInfo::setClientList(Window *windows, unsigned int count) {
909 if (role != WindowManager) return;
910
911 p->clients_count = count;
912
913 delete [] p->clients;
914 p->clients = nwindup(windows, count);
915
916#ifdef NETWMDEBUG
917 fprintf(stderr, "NETRootInfo::setClientList: setting list with %ld windows\n",
918 p->clients_count);
919#endif
920
921 XChangeProperty(p->display, p->root, net_client_list, XA_WINDOW, 32,
922 PropModeReplace, (unsigned char *)p->clients,
923 p->clients_count);
924}
925
926
927void NETRootInfo::setClientListStacking(Window *windows, unsigned int count) {
928 if (role != WindowManager) return;
929
930 p->stacking_count = count;
931 delete [] p->stacking;
932 p->stacking = nwindup(windows, count);
933
934#ifdef NETWMDEBUG
935 fprintf(stderr,
936 "NETRootInfo::setClientListStacking: setting list with %ld windows\n",
937 p->clients_count);
938#endif
939
940 XChangeProperty(p->display, p->root, net_client_list_stacking, XA_WINDOW, 32,
941 PropModeReplace, (unsigned char *) p->stacking,
942 p->stacking_count);
943}
944
945
946void NETRootInfo::setKDESystemTrayWindows(Window *windows, unsigned int count) {
947 if (role != WindowManager) return;
948
949 p->kde_system_tray_windows_count = count;
950 delete [] p->kde_system_tray_windows;
951 p->kde_system_tray_windows = nwindup(windows, count);
952
953#ifdef NETWMDEBUG
954 fprintf(stderr,
955 "NETRootInfo::setKDESystemTrayWindows: setting list with %ld windows\n",
956 p->kde_system_tray_windows_count);
957#endif
958
959 XChangeProperty(p->display, p->root, kde_net_system_tray_windows, XA_WINDOW, 32,
960 PropModeReplace,
961 (unsigned char *) p->kde_system_tray_windows,
962 p->kde_system_tray_windows_count);
963}
964
965
966void NETRootInfo::setNumberOfDesktops(int numberOfDesktops) {
967
968#ifdef NETWMDEBUG
969 fprintf(stderr,
970 "NETRootInfo::setNumberOfDesktops: setting desktop count to %d (%s)\n",
971 numberOfDesktops, (role == WindowManager) ? "WM" : "Client");
972#endif
973
974 if (role == WindowManager) {
975 p->number_of_desktops = numberOfDesktops;
976 long d = numberOfDesktops;
977 XChangeProperty(p->display, p->root, net_number_of_desktops, XA_CARDINAL, 32,
978 PropModeReplace, (unsigned char *) &d, 1);
979 } else {
980 XEvent e;
981
982 e.xclient.type = ClientMessage;
983 e.xclient.message_type = net_number_of_desktops;
984 e.xclient.display = p->display;
985 e.xclient.window = p->root;
986 e.xclient.format = 32;
987 e.xclient.data.l[0] = numberOfDesktops;
988 e.xclient.data.l[1] = 0l;
989 e.xclient.data.l[2] = 0l;
990 e.xclient.data.l[3] = 0l;
991 e.xclient.data.l[4] = 0l;
992
993 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
994 }
995}
996
997
998void NETRootInfo::setCurrentDesktop(int desktop) {
999
1000#ifdef NETWMDEBUG
1001 fprintf(stderr,
1002 "NETRootInfo::setCurrentDesktop: setting current desktop = %d (%s)\n",
1003 desktop, (role == WindowManager) ? "WM" : "Client");
1004#endif
1005
1006 if (role == WindowManager) {
1007 p->current_desktop = desktop;
1008 long d = p->current_desktop - 1;
1009 XChangeProperty(p->display, p->root, net_current_desktop, XA_CARDINAL, 32,
1010 PropModeReplace, (unsigned char *) &d, 1);
1011 } else {
1012 XEvent e;
1013
1014 e.xclient.type = ClientMessage;
1015 e.xclient.message_type = net_current_desktop;
1016 e.xclient.display = p->display;
1017 e.xclient.window = p->root;
1018 e.xclient.format = 32;
1019 e.xclient.data.l[0] = desktop - 1;
1020 e.xclient.data.l[1] = 0l;
1021 e.xclient.data.l[2] = 0l;
1022 e.xclient.data.l[3] = 0l;
1023 e.xclient.data.l[4] = 0l;
1024
1025 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
1026 }
1027}
1028
1029
1030void NETRootInfo::setDesktopName(int desktop, const char *desktopName) {
1031 // allow setting desktop names even for non-existant desktops, see the spec, sect.3.7.
1032 if (desktop < 1) return;
1033
1034 delete [] p->desktop_names[desktop - 1];
1035 p->desktop_names[desktop - 1] = nstrdup(desktopName);
1036
1037 unsigned int i, proplen,
1038 num = ((p->number_of_desktops > p->desktop_names.size()) ?
1039 p->number_of_desktops : p->desktop_names.size());
1040 for (i = 0, proplen = 0; i < num; i++)
1041 proplen += (p->desktop_names[i] != 0 ? strlen(p->desktop_names[i])+1 : 1 );
1042
1043 char *prop = new char[proplen], *propp = prop;
1044
1045 for (i = 0; i < num; i++)
1046 if (p->desktop_names[i]) {
1047 strcpy(propp, p->desktop_names[i]);
1048 propp += strlen(p->desktop_names[i]) + 1;
1049 } else
1050 *propp++ = '\0';
1051
1052#ifdef NETWMDEBUG
1053 fprintf(stderr,
1054 "NETRootInfo::setDesktopName(%d, '%s')\n"
1055 "NETRootInfo::setDesktopName: total property length = %d",
1056 desktop, desktopName, proplen);
1057#endif
1058
1059 XChangeProperty(p->display, p->root, net_desktop_names, UTF8_STRING, 8,
1060 PropModeReplace, (unsigned char *) prop, proplen);
1061
1062 delete [] prop;
1063}
1064
1065
1066void NETRootInfo::setDesktopGeometry(int , const NETSize &geometry) {
1067
1068#ifdef NETWMDEBUG
1069 fprintf(stderr, "NETRootInfo::setDesktopGeometry( -- , { %d, %d }) (%s)\n",
1070 geometry.width, geometry.height, (role == WindowManager) ? "WM" : "Client");
1071#endif
1072
1073 if (role == WindowManager) {
1074 p->geometry = geometry;
1075
1076 long data[2];
1077 data[0] = p->geometry.width;
1078 data[1] = p->geometry.height;
1079
1080 XChangeProperty(p->display, p->root, net_desktop_geometry, XA_CARDINAL, 32,
1081 PropModeReplace, (unsigned char *) data, 2);
1082 } else {
1083 XEvent e;
1084
1085 e.xclient.type = ClientMessage;
1086 e.xclient.message_type = net_desktop_geometry;
1087 e.xclient.display = p->display;
1088 e.xclient.window = p->root;
1089 e.xclient.format = 32;
1090 e.xclient.data.l[0] = geometry.width;
1091 e.xclient.data.l[1] = geometry.height;
1092 e.xclient.data.l[2] = 0l;
1093 e.xclient.data.l[3] = 0l;
1094 e.xclient.data.l[4] = 0l;
1095
1096 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
1097 }
1098}
1099
1100
1101void NETRootInfo::setDesktopViewport(int desktop, const NETPoint &viewport) {
1102
1103#ifdef NETWMDEBUG
1104 fprintf(stderr, "NETRootInfo::setDesktopViewport(%d, { %d, %d }) (%s)\n",
1105 desktop, viewport.x, viewport.y, (role == WindowManager) ? "WM" : "Client");
1106#endif
1107
1108 if (desktop < 1) return;
1109
1110 if (role == WindowManager) {
1111 p->viewport[desktop - 1] = viewport;
1112
1113 int d, i, l;
1114 l = p->number_of_desktops * 2;
1115 long *data = new long[l];
1116 for (d = 0, i = 0; d < p->number_of_desktops; d++) {
1117 data[i++] = p->viewport[d].x;
1118 data[i++] = p->viewport[d].y;
1119 }
1120
1121 XChangeProperty(p->display, p->root, net_desktop_viewport, XA_CARDINAL, 32,
1122 PropModeReplace, (unsigned char *) data, l);
1123
1124 delete [] data;
1125 } else {
1126 XEvent e;
1127
1128 e.xclient.type = ClientMessage;
1129 e.xclient.message_type = net_desktop_viewport;
1130 e.xclient.display = p->display;
1131 e.xclient.window = p->root;
1132 e.xclient.format = 32;
1133 e.xclient.data.l[0] = viewport.x;
1134 e.xclient.data.l[1] = viewport.y;
1135 e.xclient.data.l[2] = 0l;
1136 e.xclient.data.l[3] = 0l;
1137 e.xclient.data.l[4] = 0l;
1138
1139 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
1140 }
1141}
1142
1143
1144void NETRootInfo::setSupported() {
1145 if (role != WindowManager) {
1146#ifdef NETWMDEBUG
1147 fprintf(stderr, "NETRootInfo::setSupported - role != WindowManager\n");
1148#endif
1149
1150 return;
1151 }
1152
1153 Atom atoms[netAtomCount];
1154 int pnum = 2;
1155
1156 // Root window properties/messages
1157 atoms[0] = net_supported;
1158 atoms[1] = net_supporting_wm_check;
1159
1160 if (p->properties[ PROTOCOLS ] & ClientList)
1161 atoms[pnum++] = net_client_list;
1162
1163 if (p->properties[ PROTOCOLS ] & ClientListStacking)
1164 atoms[pnum++] = net_client_list_stacking;
1165
1166 if (p->properties[ PROTOCOLS ] & NumberOfDesktops)
1167 atoms[pnum++] = net_number_of_desktops;
1168
1169 if (p->properties[ PROTOCOLS ] & DesktopGeometry)
1170 atoms[pnum++] = net_desktop_geometry;
1171
1172 if (p->properties[ PROTOCOLS ] & DesktopViewport)
1173 atoms[pnum++] = net_desktop_viewport;
1174
1175 if (p->properties[ PROTOCOLS ] & CurrentDesktop)
1176 atoms[pnum++] = net_current_desktop;
1177
1178 if (p->properties[ PROTOCOLS ] & DesktopNames)
1179 atoms[pnum++] = net_desktop_names;
1180
1181 if (p->properties[ PROTOCOLS ] & ActiveWindow)
1182 atoms[pnum++] = net_active_window;
1183
1184 if (p->properties[ PROTOCOLS ] & WorkArea)
1185 atoms[pnum++] = net_workarea;
1186
1187 if (p->properties[ PROTOCOLS ] & VirtualRoots)
1188 atoms[pnum++] = net_virtual_roots;
1189
1190 if (p->properties[ PROTOCOLS2 ] & WM2DesktopLayout)
1191 atoms[pnum++] = net_desktop_layout;
1192
1193 if (p->properties[ PROTOCOLS ] & CloseWindow)
1194 atoms[pnum++] = net_close_window;
1195
1196 if (p->properties[ PROTOCOLS2 ] & WM2RestackWindow)
1197 atoms[pnum++] = net_restack_window;
1198
1199 if (p->properties[ PROTOCOLS2 ] & WM2ShowingDesktop)
1200 atoms[pnum++] = net_showing_desktop;
1201
1202 // Application window properties/messages
1203 if (p->properties[ PROTOCOLS ] & WMMoveResize)
1204 atoms[pnum++] = net_wm_moveresize;
1205
1206 if (p->properties[ PROTOCOLS2 ] & WM2MoveResizeWindow)
1207 atoms[pnum++] = net_moveresize_window;
1208
1209 if (p->properties[ PROTOCOLS ] & WMName)
1210 atoms[pnum++] = net_wm_name;
1211
1212 if (p->properties[ PROTOCOLS ] & WMVisibleName)
1213 atoms[pnum++] = net_wm_visible_name;
1214
1215 if (p->properties[ PROTOCOLS ] & WMIconName)
1216 atoms[pnum++] = net_wm_icon_name;
1217
1218 if (p->properties[ PROTOCOLS ] & WMVisibleIconName)
1219 atoms[pnum++] = net_wm_visible_icon_name;
1220
1221 if (p->properties[ PROTOCOLS ] & WMDesktop)
1222 atoms[pnum++] = net_wm_desktop;
1223
1224 if (p->properties[ PROTOCOLS ] & WMWindowType) {
1225 atoms[pnum++] = net_wm_window_type;
1226
1227 // Application window types
1228 if (p->properties[ WINDOW_TYPES ] & NormalMask)
1229 atoms[pnum++] = net_wm_window_type_normal;
1230 if (p->properties[ WINDOW_TYPES ] & DesktopMask)
1231 atoms[pnum++] = net_wm_window_type_desktop;
1232 if (p->properties[ WINDOW_TYPES ] & DockMask)
1233 atoms[pnum++] = net_wm_window_type_dock;
1234 if (p->properties[ WINDOW_TYPES ] & ToolbarMask)
1235 atoms[pnum++] = net_wm_window_type_toolbar;
1236 if (p->properties[ WINDOW_TYPES ] & MenuMask)
1237 atoms[pnum++] = net_wm_window_type_menu;
1238 if (p->properties[ WINDOW_TYPES ] & DialogMask)
1239 atoms[pnum++] = net_wm_window_type_dialog;
1240 if (p->properties[ WINDOW_TYPES ] & UtilityMask)
1241 atoms[pnum++] = net_wm_window_type_utility;
1242 if (p->properties[ WINDOW_TYPES ] & SplashMask)
1243 atoms[pnum++] = net_wm_window_type_splash;
1244 if (p->properties[ WINDOW_TYPES ] & DropdownMenuMask)
1245 atoms[pnum++] = net_wm_window_type_dropdown_menu;
1246 if (p->properties[ WINDOW_TYPES ] & PopupMenuMask)
1247 atoms[pnum++] = net_wm_window_type_popup_menu;
1248 if (p->properties[ WINDOW_TYPES ] & TooltipMask)
1249 atoms[pnum++] = net_wm_window_type_tooltip;
1250 if (p->properties[ WINDOW_TYPES ] & NotificationMask)
1251 atoms[pnum++] = net_wm_window_type_notification;
1252 if (p->properties[ WINDOW_TYPES ] & ComboBoxMask)
1253 atoms[pnum++] = net_wm_window_type_combobox;
1254 if (p->properties[ WINDOW_TYPES ] & DNDIconMask)
1255 atoms[pnum++] = net_wm_window_type_dnd;
1256 // KDE extensions
1257 if (p->properties[ WINDOW_TYPES ] & OverrideMask)
1258 atoms[pnum++] = kde_net_wm_window_type_override;
1259 if (p->properties[ WINDOW_TYPES ] & TopMenuMask)
1260 atoms[pnum++] = kde_net_wm_window_type_topmenu;
1261 }
1262
1263 if (p->properties[ PROTOCOLS ] & WMState) {
1264 atoms[pnum++] = net_wm_state;
1265
1266 // Application window states
1267 if (p->properties[ STATES ] & Modal)
1268 atoms[pnum++] = net_wm_state_modal;
1269 if (p->properties[ STATES ] & Sticky)
1270 atoms[pnum++] = net_wm_state_sticky;
1271 if (p->properties[ STATES ] & MaxVert)
1272 atoms[pnum++] = net_wm_state_max_vert;
1273 if (p->properties[ STATES ] & MaxHoriz)
1274 atoms[pnum++] = net_wm_state_max_horiz;
1275 if (p->properties[ STATES ] & Shaded)
1276 atoms[pnum++] = net_wm_state_shaded;
1277 if (p->properties[ STATES ] & SkipTaskbar)
1278 atoms[pnum++] = net_wm_state_skip_taskbar;
1279 if (p->properties[ STATES ] & SkipPager)
1280 atoms[pnum++] = net_wm_state_skip_pager;
1281 if (p->properties[ STATES ] & Hidden)
1282 atoms[pnum++] = net_wm_state_hidden;
1283 if (p->properties[ STATES ] & FullScreen)
1284 atoms[pnum++] = net_wm_state_fullscreen;
1285 if (p->properties[ STATES ] & KeepAbove)
1286 atoms[pnum++] = net_wm_state_above;
1287 if (p->properties[ STATES ] & KeepBelow)
1288 atoms[pnum++] = net_wm_state_below;
1289 if (p->properties[ STATES ] & DemandsAttention)
1290 atoms[pnum++] = net_wm_state_demands_attention;
1291
1292 if (p->properties[ STATES ] & StaysOnTop)
1293 atoms[pnum++] = net_wm_state_stays_on_top;
1294 }
1295
1296 if (p->properties[ PROTOCOLS ] & WMStrut)
1297 atoms[pnum++] = net_wm_strut;
1298
1299 if (p->properties[ PROTOCOLS2 ] & WM2ExtendedStrut)
1300 atoms[pnum++] = net_wm_extended_strut;
1301
1302 if (p->properties[ PROTOCOLS ] & WMIconGeometry)
1303 atoms[pnum++] = net_wm_icon_geometry;
1304
1305 if (p->properties[ PROTOCOLS ] & WMIcon)
1306 atoms[pnum++] = net_wm_icon;
1307
1308 if (p->properties[ PROTOCOLS ] & WMPid)
1309 atoms[pnum++] = net_wm_pid;
1310
1311 if (p->properties[ PROTOCOLS ] & WMHandledIcons)
1312 atoms[pnum++] = net_wm_handled_icons;
1313
1314 if (p->properties[ PROTOCOLS ] & WMPing)
1315 atoms[pnum++] = net_wm_ping;
1316
1317 if (p->properties[ PROTOCOLS2 ] & WM2TakeActivity)
1318 atoms[pnum++] = net_wm_take_activity;
1319
1320 if (p->properties[ PROTOCOLS2 ] & WM2UserTime)
1321 atoms[pnum++] = net_wm_user_time;
1322
1323 if (p->properties[ PROTOCOLS2 ] & WM2StartupId)
1324 atoms[pnum++] = net_startup_id;
1325
1326 if (p->properties[ PROTOCOLS2 ] & WM2AllowedActions) {
1327 atoms[pnum++] = net_wm_allowed_actions;
1328
1329 // Actions
1330 if (p->properties[ ACTIONS ] & ActionMove)
1331 atoms[pnum++] = net_wm_action_move;
1332 if (p->properties[ ACTIONS ] & ActionResize)
1333 atoms[pnum++] = net_wm_action_resize;
1334 if (p->properties[ ACTIONS ] & ActionMinimize)
1335 atoms[pnum++] = net_wm_action_minimize;
1336 if (p->properties[ ACTIONS ] & ActionShade)
1337 atoms[pnum++] = net_wm_action_shade;
1338 if (p->properties[ ACTIONS ] & ActionStick)
1339 atoms[pnum++] = net_wm_action_stick;
1340 if (p->properties[ ACTIONS ] & ActionMaxVert)
1341 atoms[pnum++] = net_wm_action_max_vert;
1342 if (p->properties[ ACTIONS ] & ActionMaxHoriz)
1343 atoms[pnum++] = net_wm_action_max_horiz;
1344 if (p->properties[ ACTIONS ] & ActionFullScreen)
1345 atoms[pnum++] = net_wm_action_fullscreen;
1346 if (p->properties[ ACTIONS ] & ActionChangeDesktop)
1347 atoms[pnum++] = net_wm_action_change_desk;
1348 if (p->properties[ ACTIONS ] & ActionClose)
1349 atoms[pnum++] = net_wm_action_close;
1350 }
1351
1352 // KDE specific extensions
1353 if (p->properties[ PROTOCOLS ] & KDESystemTrayWindows)
1354 atoms[pnum++] = kde_net_system_tray_windows;
1355
1356 if (p->properties[ PROTOCOLS ] & WMKDESystemTrayWinFor)
1357 atoms[pnum++] = kde_net_wm_system_tray_window_for;
1358
1359 if (p->properties[ PROTOCOLS ] & WMFrameExtents) {
1360 atoms[pnum++] = net_frame_extents;
1361 atoms[pnum++] = kde_net_wm_frame_strut;
1362 }
1363
1364 if (p->properties[ PROTOCOLS2 ] & WM2KDETemporaryRules)
1365 atoms[pnum++] = kde_net_wm_temporary_rules;
1366 if (p->properties[ PROTOCOLS2 ] & WM2FullPlacement)
1367 atoms[pnum++] = net_wm_full_placement;
1368
1369 XChangeProperty(p->display, p->root, net_supported, XA_ATOM, 32,
1370 PropModeReplace, (unsigned char *) atoms, pnum);
1371 XChangeProperty(p->display, p->root, net_supporting_wm_check, XA_WINDOW, 32,
1372 PropModeReplace, (unsigned char *) &(p->supportwindow), 1);
1373
1374#ifdef NETWMDEBUG
1375 fprintf(stderr,
1376 "NETRootInfo::setSupported: _NET_SUPPORTING_WM_CHECK = 0x%lx on 0x%lx\n"
1377 " : _NET_WM_NAME = '%s' on 0x%lx\n",
1378 p->supportwindow, p->supportwindow, p->name, p->supportwindow);
1379#endif
1380
1381 XChangeProperty(p->display, p->supportwindow, net_supporting_wm_check,
1382 XA_WINDOW, 32, PropModeReplace,
1383 (unsigned char *) &(p->supportwindow), 1);
1384 XChangeProperty(p->display, p->supportwindow, net_wm_name, UTF8_STRING, 8,
1385 PropModeReplace, (unsigned char *) p->name,
1386 strlen(p->name));
1387}
1388
1389void NETRootInfo::updateSupportedProperties( Atom atom )
1390{
1391 if( atom == net_supported )
1392 p->properties[ PROTOCOLS ] |= Supported;
1393
1394 else if( atom == net_supporting_wm_check )
1395 p->properties[ PROTOCOLS ] |= SupportingWMCheck;
1396
1397 else if( atom == net_client_list )
1398 p->properties[ PROTOCOLS ] |= ClientList;
1399
1400 else if( atom == net_client_list_stacking )
1401 p->properties[ PROTOCOLS ] |= ClientListStacking;
1402
1403 else if( atom == net_number_of_desktops )
1404 p->properties[ PROTOCOLS ] |= NumberOfDesktops;
1405
1406 else if( atom == net_desktop_geometry )
1407 p->properties[ PROTOCOLS ] |= DesktopGeometry;
1408
1409 else if( atom == net_desktop_viewport )
1410 p->properties[ PROTOCOLS ] |= DesktopViewport;
1411
1412 else if( atom == net_current_desktop )
1413 p->properties[ PROTOCOLS ] |= CurrentDesktop;
1414
1415 else if( atom == net_desktop_names )
1416 p->properties[ PROTOCOLS ] |= DesktopNames;
1417
1418 else if( atom == net_active_window )
1419 p->properties[ PROTOCOLS ] |= ActiveWindow;
1420
1421 else if( atom == net_workarea )
1422 p->properties[ PROTOCOLS ] |= WorkArea;
1423
1424 else if( atom == net_virtual_roots )
1425 p->properties[ PROTOCOLS ] |= VirtualRoots;
1426
1427 else if( atom == net_desktop_layout )
1428 p->properties[ PROTOCOLS2 ] |= WM2DesktopLayout;
1429
1430 else if( atom == net_close_window )
1431 p->properties[ PROTOCOLS ] |= CloseWindow;
1432
1433 else if( atom == net_restack_window )
1434 p->properties[ PROTOCOLS2 ] |= WM2RestackWindow;
1435
1436 else if( atom == net_showing_desktop )
1437 p->properties[ PROTOCOLS2 ] |= WM2ShowingDesktop;
1438
1439 // Application window properties/messages
1440 else if( atom == net_wm_moveresize )
1441 p->properties[ PROTOCOLS ] |= WMMoveResize;
1442
1443 else if( atom == net_moveresize_window )
1444 p->properties[ PROTOCOLS2 ] |= WM2MoveResizeWindow;
1445
1446 else if( atom == net_wm_name )
1447 p->properties[ PROTOCOLS ] |= WMName;
1448
1449 else if( atom == net_wm_visible_name )
1450 p->properties[ PROTOCOLS ] |= WMVisibleName;
1451
1452 else if( atom == net_wm_icon_name )
1453 p->properties[ PROTOCOLS ] |= WMIconName;
1454
1455 else if( atom == net_wm_visible_icon_name )
1456 p->properties[ PROTOCOLS ] |= WMVisibleIconName;
1457
1458 else if( atom == net_wm_desktop )
1459 p->properties[ PROTOCOLS ] |= WMDesktop;
1460
1461 else if( atom == net_wm_window_type )
1462 p->properties[ PROTOCOLS ] |= WMWindowType;
1463
1464 // Application window types
1465 else if( atom == net_wm_window_type_normal )
1466 p->properties[ WINDOW_TYPES ] |= NormalMask;
1467 else if( atom == net_wm_window_type_desktop )
1468 p->properties[ WINDOW_TYPES ] |= DesktopMask;
1469 else if( atom == net_wm_window_type_dock )
1470 p->properties[ WINDOW_TYPES ] |= DockMask;
1471 else if( atom == net_wm_window_type_toolbar )
1472 p->properties[ WINDOW_TYPES ] |= ToolbarMask;
1473 else if( atom == net_wm_window_type_menu )
1474 p->properties[ WINDOW_TYPES ] |= MenuMask;
1475 else if( atom == net_wm_window_type_dialog )
1476 p->properties[ WINDOW_TYPES ] |= DialogMask;
1477 else if( atom == net_wm_window_type_utility )
1478 p->properties[ WINDOW_TYPES ] |= UtilityMask;
1479 else if( atom == net_wm_window_type_splash )
1480 p->properties[ WINDOW_TYPES ] |= SplashMask;
1481 else if( atom == net_wm_window_type_dropdown_menu )
1482 p->properties[ WINDOW_TYPES ] |= DropdownMenuMask;
1483 else if( atom == net_wm_window_type_popup_menu )
1484 p->properties[ WINDOW_TYPES ] |= PopupMenuMask;
1485 else if( atom == net_wm_window_type_tooltip )
1486 p->properties[ WINDOW_TYPES ] |= TooltipMask;
1487 else if( atom == net_wm_window_type_notification )
1488 p->properties[ WINDOW_TYPES ] |= NotificationMask;
1489 else if( atom == net_wm_window_type_combobox )
1490 p->properties[ WINDOW_TYPES ] |= ComboBoxMask;
1491 else if( atom == net_wm_window_type_dnd )
1492 p->properties[ WINDOW_TYPES ] |= DNDIconMask;
1493 // KDE extensions
1494 else if( atom == kde_net_wm_window_type_override )
1495 p->properties[ WINDOW_TYPES ] |= OverrideMask;
1496 else if( atom == kde_net_wm_window_type_topmenu )
1497 p->properties[ WINDOW_TYPES ] |= TopMenuMask;
1498
1499 else if( atom == net_wm_state )
1500 p->properties[ PROTOCOLS ] |= WMState;
1501
1502 // Application window states
1503 else if( atom == net_wm_state_modal )
1504 p->properties[ STATES ] |= Modal;
1505 else if( atom == net_wm_state_sticky )
1506 p->properties[ STATES ] |= Sticky;
1507 else if( atom == net_wm_state_max_vert )
1508 p->properties[ STATES ] |= MaxVert;
1509 else if( atom == net_wm_state_max_horiz )
1510 p->properties[ STATES ] |= MaxHoriz;
1511 else if( atom == net_wm_state_shaded )
1512 p->properties[ STATES ] |= Shaded;
1513 else if( atom == net_wm_state_skip_taskbar )
1514 p->properties[ STATES ] |= SkipTaskbar;
1515 else if( atom == net_wm_state_skip_pager )
1516 p->properties[ STATES ] |= SkipPager;
1517 else if( atom == net_wm_state_hidden )
1518 p->properties[ STATES ] |= Hidden;
1519 else if( atom == net_wm_state_fullscreen )
1520 p->properties[ STATES ] |= FullScreen;
1521 else if( atom == net_wm_state_above )
1522 p->properties[ STATES ] |= KeepAbove;
1523 else if( atom == net_wm_state_below )
1524 p->properties[ STATES ] |= KeepBelow;
1525 else if( atom == net_wm_state_demands_attention )
1526 p->properties[ STATES ] |= DemandsAttention;
1527
1528 else if( atom == net_wm_state_stays_on_top )
1529 p->properties[ STATES ] |= StaysOnTop;
1530
1531 else if( atom == net_wm_strut )
1532 p->properties[ PROTOCOLS ] |= WMStrut;
1533
1534 else if( atom == net_wm_extended_strut )
1535 p->properties[ PROTOCOLS2 ] |= WM2ExtendedStrut;
1536
1537 else if( atom == net_wm_icon_geometry )
1538 p->properties[ PROTOCOLS ] |= WMIconGeometry;
1539
1540 else if( atom == net_wm_icon )
1541 p->properties[ PROTOCOLS ] |= WMIcon;
1542
1543 else if( atom == net_wm_pid )
1544 p->properties[ PROTOCOLS ] |= WMPid;
1545
1546 else if( atom == net_wm_handled_icons )
1547 p->properties[ PROTOCOLS ] |= WMHandledIcons;
1548
1549 else if( atom == net_wm_ping )
1550 p->properties[ PROTOCOLS ] |= WMPing;
1551
1552 else if( atom == net_wm_take_activity )
1553 p->properties[ PROTOCOLS2 ] |= WM2TakeActivity;
1554
1555 else if( atom == net_wm_user_time )
1556 p->properties[ PROTOCOLS2 ] |= WM2UserTime;
1557
1558 else if( atom == net_startup_id )
1559 p->properties[ PROTOCOLS2 ] |= WM2StartupId;
1560
1561 else if( atom == net_wm_allowed_actions )
1562 p->properties[ PROTOCOLS2 ] |= WM2AllowedActions;
1563
1564 // Actions
1565 else if( atom == net_wm_action_move )
1566 p->properties[ ACTIONS ] |= ActionMove;
1567 else if( atom == net_wm_action_resize )
1568 p->properties[ ACTIONS ] |= ActionResize;
1569 else if( atom == net_wm_action_minimize )
1570 p->properties[ ACTIONS ] |= ActionMinimize;
1571 else if( atom == net_wm_action_shade )
1572 p->properties[ ACTIONS ] |= ActionShade;
1573 else if( atom == net_wm_action_stick )
1574 p->properties[ ACTIONS ] |= ActionStick;
1575 else if( atom == net_wm_action_max_vert )
1576 p->properties[ ACTIONS ] |= ActionMaxVert;
1577 else if( atom == net_wm_action_max_horiz )
1578 p->properties[ ACTIONS ] |= ActionMaxHoriz;
1579 else if( atom == net_wm_action_fullscreen )
1580 p->properties[ ACTIONS ] |= ActionFullScreen;
1581 else if( atom == net_wm_action_change_desk )
1582 p->properties[ ACTIONS ] |= ActionChangeDesktop;
1583 else if( atom == net_wm_action_close )
1584 p->properties[ ACTIONS ] |= ActionClose;
1585
1586 // KDE specific extensions
1587 else if( atom == kde_net_system_tray_windows )
1588 p->properties[ PROTOCOLS ] |= KDESystemTrayWindows;
1589
1590 else if( atom == kde_net_wm_system_tray_window_for )
1591 p->properties[ PROTOCOLS ] |= WMKDESystemTrayWinFor;
1592
1593 else if( atom == net_frame_extents )
1594 p->properties[ PROTOCOLS ] |= WMFrameExtents;
1595 else if( atom == kde_net_wm_frame_strut )
1596 p->properties[ PROTOCOLS ] |= WMKDEFrameStrut;
1597
1598 else if( atom == kde_net_wm_temporary_rules )
1599 p->properties[ PROTOCOLS2 ] |= WM2KDETemporaryRules;
1600 else if( atom == net_wm_full_placement )
1601 p->properties[ PROTOCOLS2 ] |= WM2FullPlacement;
1602}
1603
1604void NETRootInfo::setActiveWindow(Window window) {
1605 setActiveWindow( window, FromUnknown, get_tqt_x_user_time(), None );
1606}
1607
1608void NETRootInfo::setActiveWindow(Window window, NET::RequestSource src,
1609 Time timestamp, Window active_window ) {
1610
1611#ifdef NETWMDEBUG
1612 fprintf(stderr, "NETRootInfo::setActiveWindow(0x%lx) (%s)\n",
1613 window, (role == WindowManager) ? "WM" : "Client");
1614#endif
1615
1616 if (role == WindowManager) {
1617 p->active = window;
1618 XChangeProperty(p->display, p->root, net_active_window, XA_WINDOW, 32,
1619 PropModeReplace, (unsigned char *) &(p->active), 1);
1620 } else {
1621 XEvent e;
1622
1623 e.xclient.type = ClientMessage;
1624 e.xclient.message_type = net_active_window;
1625 e.xclient.display = p->display;
1626 e.xclient.window = window;
1627 e.xclient.format = 32;
1628 e.xclient.data.l[0] = src;
1629 e.xclient.data.l[1] = timestamp;
1630 e.xclient.data.l[2] = active_window;
1631 e.xclient.data.l[3] = 0l;
1632 e.xclient.data.l[4] = 0l;
1633
1634 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
1635 }
1636}
1637
1638
1639void NETRootInfo::setWorkArea(int desktop, const NETRect &workarea) {
1640
1641#ifdef NETWMDEBUG
1642 fprintf(stderr, "NETRootInfo::setWorkArea(%d, { %d, %d, %d, %d }) (%s)\n",
1643 desktop, workarea.pos.x, workarea.pos.y, workarea.size.width, workarea.size.height,
1644 (role == WindowManager) ? "WM" : "Client");
1645#endif
1646
1647 if (role != WindowManager || desktop < 1) return;
1648
1649 p->workarea[desktop - 1] = workarea;
1650
1651 long *wa = new long[p->number_of_desktops * 4];
1652 int i, o;
1653 for (i = 0, o = 0; i < p->number_of_desktops; i++) {
1654 wa[o++] = p->workarea[i].pos.x;
1655 wa[o++] = p->workarea[i].pos.y;
1656 wa[o++] = p->workarea[i].size.width;
1657 wa[o++] = p->workarea[i].size.height;
1658 }
1659
1660 XChangeProperty(p->display, p->root, net_workarea, XA_CARDINAL, 32,
1661 PropModeReplace, (unsigned char *) wa,
1662 p->number_of_desktops * 4);
1663
1664 delete [] wa;
1665}
1666
1667
1668void NETRootInfo::setVirtualRoots(Window *windows, unsigned int count) {
1669 if (role != WindowManager) return;
1670
1671 p->virtual_roots_count = count;
1672 p->virtual_roots = windows;
1673
1674#ifdef NETWMDEBUG
1675 fprintf(stderr, "NETRootInfo::setVirtualRoots: setting list with %ld windows\n",
1676 p->virtual_roots_count);
1677#endif
1678
1679 XChangeProperty(p->display, p->root, net_virtual_roots, XA_WINDOW, 32,
1680 PropModeReplace, (unsigned char *) p->virtual_roots,
1681 p->virtual_roots_count);
1682}
1683
1684
1685void NETRootInfo::setDesktopLayout(NET::Orientation orientation, int columns, int rows,
1686 NET::DesktopLayoutCorner corner)
1687{
1688 p->desktop_layout_orientation = orientation;
1689 p->desktop_layout_columns = columns;
1690 p->desktop_layout_rows = rows;
1691 p->desktop_layout_corner = corner;
1692
1693#ifdef NETWMDEBUG
1694 fprintf(stderr, "NETRootInfo::setDesktopLayout: %d %d %d %d\n",
1695 orientation, columns, rows, corner);
1696#endif
1697
1698 long data[ 4 ];
1699 data[ 0 ] = orientation;
1700 data[ 1 ] = columns;
1701 data[ 2 ] = rows;
1702 data[ 3 ] = corner;
1703 XChangeProperty(p->display, p->root, net_desktop_layout, XA_CARDINAL, 32,
1704 PropModeReplace, (unsigned char *) &data, 4);
1705}
1706
1707
1708void NETRootInfo::setShowingDesktop( bool showing ) {
1709 if (role == WindowManager) {
1710 long d = p->showing_desktop = showing;
1711 XChangeProperty(p->display, p->root, net_showing_desktop, XA_CARDINAL, 32,
1712 PropModeReplace, (unsigned char *) &d, 1);
1713 } else {
1714 XEvent e;
1715
1716 e.xclient.type = ClientMessage;
1717 e.xclient.message_type = net_showing_desktop;
1718 e.xclient.display = p->display;
1719 e.xclient.window = 0;
1720 e.xclient.format = 32;
1721 e.xclient.data.l[0] = showing ? 1 : 0;
1722 e.xclient.data.l[1] = 0;
1723 e.xclient.data.l[2] = 0;
1724 e.xclient.data.l[3] = 0;
1725 e.xclient.data.l[4] = 0;
1726
1727 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
1728 }
1729}
1730
1731
1732bool NETRootInfo::showingDesktop() const {
1733 return p->showing_desktop;
1734}
1735
1736
1737void NETRootInfo::closeWindowRequest(Window window) {
1738
1739#ifdef NETWMDEBUG
1740 fprintf(stderr, "NETRootInfo::closeWindowRequest: requesting close for 0x%lx\n",
1741 window);
1742#endif
1743
1744 XEvent e;
1745
1746 e.xclient.type = ClientMessage;
1747 e.xclient.message_type = net_close_window;
1748 e.xclient.display = p->display;
1749 e.xclient.window = window;
1750 e.xclient.format = 32;
1751 e.xclient.data.l[0] = 0l;
1752 e.xclient.data.l[1] = 0l;
1753 e.xclient.data.l[2] = 0l;
1754 e.xclient.data.l[3] = 0l;
1755 e.xclient.data.l[4] = 0l;
1756
1757 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
1758}
1759
1760
1761void NETRootInfo::moveResizeRequest(Window window, int x_root, int y_root,
1762 Direction direction)
1763{
1764
1765#ifdef NETWMDEBUG
1766 fprintf(stderr,
1767 "NETRootInfo::moveResizeRequest: requesting resize/move for 0x%lx (%d, %d, %d)\n",
1768 window, x_root, y_root, direction);
1769#endif
1770
1771 XEvent e;
1772
1773 e.xclient.type = ClientMessage;
1774 e.xclient.message_type = net_wm_moveresize;
1775 e.xclient.display = p->display;
1776 e.xclient.window = window,
1777 e.xclient.format = 32;
1778 e.xclient.data.l[0] = x_root;
1779 e.xclient.data.l[1] = y_root;
1780 e.xclient.data.l[2] = direction;
1781 e.xclient.data.l[3] = 0l;
1782 e.xclient.data.l[4] = 0l;
1783
1784 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
1785}
1786
1787void NETRootInfo::moveResizeWindowRequest(Window window, int flags, int x, int y, int width, int height )
1788{
1789
1790#ifdef NETWMDEBUG
1791 fprintf(stderr,
1792 "NETRootInfo::moveResizeWindowRequest: resizing/moving 0x%lx (%d, %d, %d, %d, %d)\n",
1793 window, flags, x, y, width, height);
1794#endif
1795
1796 XEvent e;
1797
1798 e.xclient.type = ClientMessage;
1799 e.xclient.message_type = net_moveresize_window;
1800 e.xclient.display = p->display;
1801 e.xclient.window = window,
1802 e.xclient.format = 32;
1803 e.xclient.data.l[0] = flags;
1804 e.xclient.data.l[1] = x;
1805 e.xclient.data.l[2] = y;
1806 e.xclient.data.l[3] = width;
1807 e.xclient.data.l[4] = height;
1808
1809 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
1810}
1811
1812void NETRootInfo::restackRequest(Window window, Window above, int detail)
1813{
1814 restackRequest( window, FromTool, above, detail, get_tqt_x_user_time() );
1815}
1816
1817void NETRootInfo::restackRequest(Window window, RequestSource src, Window above, int detail, Time timestamp )
1818{
1819#ifdef NETWMDEBUG
1820 fprintf(stderr,
1821 "NETRootInfo::restackRequest: requesting restack for 0x%lx (%lx, %d)\n",
1822 window, above, detail);
1823#endif
1824
1825 XEvent e;
1826
1827 e.xclient.type = ClientMessage;
1828 e.xclient.message_type = net_restack_window;
1829 e.xclient.display = p->display;
1830 e.xclient.window = window,
1831 e.xclient.format = 32;
1832 e.xclient.data.l[0] = src;
1833 e.xclient.data.l[1] = above;
1834 e.xclient.data.l[2] = detail;
1835 e.xclient.data.l[3] = timestamp;
1836 e.xclient.data.l[4] = 0l;
1837
1838 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
1839}
1840
1841void NETRootInfo2::sendPing( Window window, Time timestamp )
1842{
1843 if (role != WindowManager) return;
1844#ifdef NETWMDEBUG
1845 fprintf(stderr, "NETRootInfo2::setPing: window 0x%lx, timestamp %lu\n",
1846 window, timestamp );
1847#endif
1848 XEvent e;
1849 e.xclient.type = ClientMessage;
1850 e.xclient.message_type = wm_protocols;
1851 e.xclient.display = p->display;
1852 e.xclient.window = window,
1853 e.xclient.format = 32;
1854 e.xclient.data.l[0] = net_wm_ping;
1855 e.xclient.data.l[1] = timestamp;
1856 e.xclient.data.l[2] = window;
1857 e.xclient.data.l[3] = 0;
1858 e.xclient.data.l[4] = 0;
1859
1860 XSendEvent(p->display, window, False, 0, &e);
1861}
1862
1863void NETRootInfo3::takeActivity( Window window, Time timestamp, long flags )
1864{
1865 if (role != WindowManager) return;
1866#ifdef NETWMDEBUG
1867 fprintf(stderr, "NETRootInfo2::takeActivity: window 0x%lx, timestamp %lu, flags 0x%lx\n",
1868 window, timestamp, flags );
1869#endif
1870 XEvent e;
1871 e.xclient.type = ClientMessage;
1872 e.xclient.message_type = wm_protocols;
1873 e.xclient.display = p->display;
1874 e.xclient.window = window,
1875 e.xclient.format = 32;
1876 e.xclient.data.l[0] = net_wm_take_activity;
1877 e.xclient.data.l[1] = timestamp;
1878 e.xclient.data.l[2] = window;
1879 e.xclient.data.l[3] = flags;
1880 e.xclient.data.l[4] = 0;
1881
1882 XSendEvent(p->display, window, False, 0, &e);
1883}
1884
1885
1886
1887// assignment operator
1888
1889const NETRootInfo &NETRootInfo::operator=(const NETRootInfo &rootinfo) {
1890
1891#ifdef NETWMDEBUG
1892 fprintf(stderr, "NETRootInfo::operator=()\n");
1893#endif
1894
1895 if (p != rootinfo.p) {
1896 refdec_nri(p);
1897
1898 if (! p->ref) delete p;
1899 }
1900
1901 p = rootinfo.p;
1902 role = rootinfo.role;
1903 p->ref++;
1904
1905 return *this;
1906}
1907
1908unsigned long NETRootInfo::event(XEvent *ev )
1909{
1910 unsigned long props[ 1 ];
1911 event( ev, props, 1 );
1912 return props[ 0 ];
1913}
1914
1915void NETRootInfo::event(XEvent *event, unsigned long* properties, int properties_size )
1916{
1917 unsigned long props[ PROPERTIES_SIZE ] = { 0, 0, 0, 0, 0 };
1918 assert( PROPERTIES_SIZE == 5 ); // add elements above
1919 unsigned long& dirty = props[ PROTOCOLS ];
1920 unsigned long& dirty2 = props[ PROTOCOLS2 ];
1921 bool do_update = false;
1922
1923 // the window manager will be interested in client messages... no other
1924 // client should get these messages
1925 if (role == WindowManager && event->type == ClientMessage &&
1926 event->xclient.format == 32) {
1927#ifdef NETWMDEBUG
1928 fprintf(stderr, "NETRootInfo::event: handling ClientMessage event\n");
1929#endif
1930
1931 if (event->xclient.message_type == net_number_of_desktops) {
1932 dirty = NumberOfDesktops;
1933
1934#ifdef NETWMDEBUG
1935 fprintf(stderr, "NETRootInfo::event: changeNumberOfDesktops(%ld)\n",
1936 event->xclient.data.l[0]);
1937#endif
1938
1939 changeNumberOfDesktops(event->xclient.data.l[0]);
1940 } else if (event->xclient.message_type == net_desktop_geometry) {
1941 dirty = DesktopGeometry;
1942
1943 NETSize sz;
1944 sz.width = event->xclient.data.l[0];
1945 sz.height = event->xclient.data.l[1];
1946
1947#ifdef NETWMDEBUG
1948 fprintf(stderr, "NETRootInfo::event: changeDesktopGeometry( -- , { %d, %d })\n",
1949 sz.width, sz.height);
1950#endif
1951
1952 changeDesktopGeometry(~0, sz);
1953 } else if (event->xclient.message_type == net_desktop_viewport) {
1954 dirty = DesktopViewport;
1955
1956 NETPoint pt;
1957 pt.x = event->xclient.data.l[0];
1958 pt.y = event->xclient.data.l[1];
1959
1960#ifdef NETWMDEBUG
1961 fprintf(stderr, "NETRootInfo::event: changeDesktopViewport(%d, { %d, %d })\n",
1962 p->current_desktop, pt.x, pt.y);
1963#endif
1964
1965 changeDesktopViewport(p->current_desktop, pt);
1966 } else if (event->xclient.message_type == net_current_desktop) {
1967 dirty = CurrentDesktop;
1968
1969#ifdef NETWMDEBUG
1970 fprintf(stderr, "NETRootInfo::event: changeCurrentDesktop(%ld)\n",
1971 event->xclient.data.l[0] + 1);
1972#endif
1973
1974 changeCurrentDesktop(event->xclient.data.l[0] + 1);
1975 } else if (event->xclient.message_type == net_active_window) {
1976 dirty = ActiveWindow;
1977
1978#ifdef NETWMDEBUG
1979 fprintf(stderr, "NETRootInfo::event: changeActiveWindow(0x%lx)\n",
1980 event->xclient.window);
1981#endif
1982
1983 changeActiveWindow(event->xclient.window);
1984 if( NETRootInfo2* this2 = dynamic_cast< NETRootInfo2* >( this ))
1985 {
1986 RequestSource src = FromUnknown;
1987 Time timestamp = CurrentTime;
1988 Window active_window = None;
1989 // make sure there aren't unknown values
1990 if( event->xclient.data.l[0] >= FromUnknown
1991 && event->xclient.data.l[0] <= FromTool )
1992 {
1993 src = static_cast< RequestSource >( event->xclient.data.l[0] );
1994 timestamp = event->xclient.data.l[1];
1995 active_window = event->xclient.data.l[2];
1996 }
1997 this2->changeActiveWindow( event->xclient.window, src, timestamp, active_window );
1998 }
1999 } else if (event->xclient.message_type == net_wm_moveresize) {
2000
2001#ifdef NETWMDEBUG
2002 fprintf(stderr, "NETRootInfo::event: moveResize(%ld, %ld, %ld, %ld)\n",
2003 event->xclient.window,
2004 event->xclient.data.l[0],
2005 event->xclient.data.l[1],
2006 event->xclient.data.l[2]
2007 );
2008#endif
2009
2010 moveResize(event->xclient.window,
2011 event->xclient.data.l[0],
2012 event->xclient.data.l[1],
2013 event->xclient.data.l[2]);
2014 } else if (event->xclient.message_type == net_moveresize_window) {
2015
2016#ifdef NETWMDEBUG
2017 fprintf(stderr, "NETRootInfo::event: moveResizeWindow(%ld, %ld, %ld, %ld, %ld, %ld)\n",
2018 event->xclient.window,
2019 event->xclient.data.l[0],
2020 event->xclient.data.l[1],
2021 event->xclient.data.l[2],
2022 event->xclient.data.l[3],
2023 event->xclient.data.l[4]
2024 );
2025#endif
2026
2027 if( NETRootInfo2* this2 = dynamic_cast< NETRootInfo2* >( this ))
2028 this2->moveResizeWindow(event->xclient.window,
2029 event->xclient.data.l[0],
2030 event->xclient.data.l[1],
2031 event->xclient.data.l[2],
2032 event->xclient.data.l[3],
2033 event->xclient.data.l[4]);
2034 } else if (event->xclient.message_type == net_close_window) {
2035
2036#ifdef NETWMDEBUG
2037 fprintf(stderr, "NETRootInfo::event: closeWindow(0x%lx)\n",
2038 event->xclient.window);
2039#endif
2040
2041 closeWindow(event->xclient.window);
2042 } else if (event->xclient.message_type == net_restack_window) {
2043
2044#ifdef NETWMDEBUG
2045 fprintf(stderr, "NETRootInfo::event: restackWindow(0x%lx)\n",
2046 event->xclient.window);
2047#endif
2048
2049 if( NETRootInfo3* this3 = dynamic_cast< NETRootInfo3* >( this ))
2050 {
2051 RequestSource src = FromUnknown;
2052 Time timestamp = CurrentTime;
2053 // make sure there aren't unknown values
2054 if( event->xclient.data.l[0] >= FromUnknown
2055 && event->xclient.data.l[0] <= FromTool )
2056 {
2057 src = static_cast< RequestSource >( event->xclient.data.l[0] );
2058 timestamp = event->xclient.data.l[3];
2059 }
2060 this3->restackWindow(event->xclient.window, src,
2061 event->xclient.data.l[1], event->xclient.data.l[2], timestamp);
2062 }
2063 else if( NETRootInfo2* this2 = dynamic_cast< NETRootInfo2* >( this ))
2064 this2->restackWindow(event->xclient.window,
2065 event->xclient.data.l[1], event->xclient.data.l[2]);
2066 } else if (event->xclient.message_type == wm_protocols
2067 && (Atom)event->xclient.data.l[ 0 ] == net_wm_ping) {
2068 dirty = WMPing;
2069
2070#ifdef NETWMDEBUG
2071 fprintf(stderr, "NETRootInfo2::event: gotPing(0x%lx,%lu)\n",
2072 event->xclient.window, event->xclient.data.l[1]);
2073#endif
2074 if( NETRootInfo2* this2 = dynamic_cast< NETRootInfo2* >( this ))
2075 this2->gotPing( event->xclient.data.l[2], event->xclient.data.l[1]);
2076 } else if (event->xclient.message_type == wm_protocols
2077 && (Atom)event->xclient.data.l[ 0 ] == net_wm_take_activity) {
2078 dirty2 = WM2TakeActivity;
2079
2080#ifdef NETWMDEBUG
2081 fprintf(stderr, "NETRootInfo2::event: gotTakeActivity(0x%lx,%lu,0x%lx)\n",
2082 event->xclient.window, event->xclient.data.l[1], event->xclient.data.l[3]);
2083#endif
2084 if( NETRootInfo3* this3 = dynamic_cast< NETRootInfo3* >( this ))
2085 this3->gotTakeActivity( event->xclient.data.l[2], event->xclient.data.l[1],
2086 event->xclient.data.l[3]);
2087 } else if (event->xclient.message_type == net_showing_desktop) {
2088 dirty2 = WM2ShowingDesktop;
2089
2090#ifdef NETWMDEBUG
2091 fprintf(stderr, "NETRootInfo::event: changeShowingDesktop(%ld)\n",
2092 event->xclient.data.l[0]);
2093#endif
2094
2095 if( NETRootInfo4* this4 = dynamic_cast< NETRootInfo4* >( this ))
2096 this4->changeShowingDesktop(event->xclient.data.l[0]);
2097 }
2098 }
2099
2100 if (event->type == PropertyNotify) {
2101
2102#ifdef NETWMDEBUG
2103 fprintf(stderr, "NETRootInfo::event: handling PropertyNotify event\n");
2104#endif
2105
2106 XEvent pe = *event;
2107
2108 Bool done = False;
2109 Bool compaction = False;
2110 while (! done) {
2111
2112#ifdef NETWMDEBUG
2113 fprintf(stderr, "NETRootInfo::event: loop fire\n");
2114#endif
2115
2116 if (pe.xproperty.atom == net_client_list)
2117 dirty |= ClientList;
2118 else if (pe.xproperty.atom == net_client_list_stacking)
2119 dirty |= ClientListStacking;
2120 else if (pe.xproperty.atom == kde_net_system_tray_windows)
2121 dirty |= KDESystemTrayWindows;
2122 else if (pe.xproperty.atom == net_desktop_names)
2123 dirty |= DesktopNames;
2124 else if (pe.xproperty.atom == net_workarea)
2125 dirty |= WorkArea;
2126 else if (pe.xproperty.atom == net_number_of_desktops)
2127 dirty |= NumberOfDesktops;
2128 else if (pe.xproperty.atom == net_desktop_geometry)
2129 dirty |= DesktopGeometry;
2130 else if (pe.xproperty.atom == net_desktop_viewport)
2131 dirty |= DesktopViewport;
2132 else if (pe.xproperty.atom == net_current_desktop)
2133 dirty |= CurrentDesktop;
2134 else if (pe.xproperty.atom == net_active_window)
2135 dirty |= ActiveWindow;
2136 else if (pe.xproperty.atom == net_showing_desktop)
2137 dirty2 |= WM2ShowingDesktop;
2138// else if (pe.xproperty.atom == net_supported )
2139// dirty |= Supported; // update here?
2140 else if (pe.xproperty.atom == net_supporting_wm_check )
2141 dirty |= SupportingWMCheck;
2142 else if (pe.xproperty.atom == net_virtual_roots )
2143 dirty |= VirtualRoots;
2144 else if (pe.xproperty.atom == net_desktop_layout )
2145 dirty2 |= WM2DesktopLayout;
2146 else {
2147
2148#ifdef NETWMDEBUG
2149 fprintf(stderr, "NETRootInfo::event: putting back event and breaking\n");
2150#endif
2151
2152 if ( compaction )
2153 XPutBackEvent(p->display, &pe);
2154 break;
2155 }
2156
2157 if (XCheckTypedWindowEvent(p->display, p->root, PropertyNotify, &pe) )
2158 compaction = True;
2159 else
2160 break;
2161 }
2162
2163 do_update = true;
2164 }
2165
2166 if( do_update )
2167 update( props );
2168
2169#ifdef NETWMDEBUG
2170 fprintf(stderr, "NETRootInfo::event: handled events, returning dirty = 0x%lx, 0x%lx\n",
2171 dirty, dirty2);
2172#endif
2173
2174 if( properties_size > PROPERTIES_SIZE )
2175 properties_size = PROPERTIES_SIZE;
2176 for( int i = 0;
2177 i < properties_size;
2178 ++i )
2179 properties[ i ] = props[ i ];
2180}
2181
2182
2183// private functions to update the data we keep
2184
2185void NETRootInfo::update( const unsigned long dirty_props[] )
2186{
2187 Atom type_ret;
2188 int format_ret;
2189 unsigned char *data_ret;
2190 unsigned long nitems_ret, unused;
2191 unsigned long props[ PROPERTIES_SIZE ];
2192 for( int i = 0;
2193 i < PROPERTIES_SIZE;
2194 ++i )
2195 props[ i ] = dirty_props[ i ] & p->client_properties[ i ];
2196 const unsigned long& dirty = props[ PROTOCOLS ];
2197 const unsigned long& dirty2 = props[ PROTOCOLS2 ];
2198
2199 if (dirty & Supported ) {
2200 // only in Client mode
2201 for( int i = 0; i < PROPERTIES_SIZE; ++i )
2202 p->properties[ i ] = 0;
2203 if( XGetWindowProperty(p->display, p->root, net_supported,
2204 0l, MAX_PROP_SIZE, False, XA_ATOM, &type_ret,
2205 &format_ret, &nitems_ret, &unused, &data_ret)
2206 == Success ) {
2207 if( type_ret == XA_ATOM && format_ret == 32 ) {
2208 Atom* atoms = (Atom*) data_ret;
2209 for( unsigned int i = 0;
2210 i < nitems_ret;
2211 ++i )
2212 updateSupportedProperties( atoms[ i ] );
2213 }
2214 if ( data_ret )
2215 XFree(data_ret);
2216 }
2217 }
2218
2219 if (dirty & ClientList) {
2220 bool read_ok = false;
2221 if (XGetWindowProperty(p->display, p->root, net_client_list,
2222 0l, MAX_PROP_SIZE, False, XA_WINDOW, &type_ret,
2223 &format_ret, &nitems_ret, &unused, &data_ret)
2224 == Success) {
2225 if (type_ret == XA_WINDOW && format_ret == 32) {
2226 Window *wins = (Window *) data_ret;
2227
2228 qsort(wins, nitems_ret, sizeof(Window), wcmp);
2229
2230 if (p->clients) {
2231 if (role == Client) {
2232 unsigned long new_index = 0, old_index = 0;
2233 unsigned long new_count = nitems_ret,
2234 old_count = p->clients_count;
2235
2236 while (old_index < old_count || new_index < new_count) {
2237 if (old_index == old_count) {
2238 addClient(wins[new_index++]);
2239 } else if (new_index == new_count) {
2240 removeClient(p->clients[old_index++]);
2241 } else {
2242 if (p->clients[old_index] <
2243 wins[new_index]) {
2244 removeClient(p->clients[old_index++]);
2245 } else if (wins[new_index] <
2246 p->clients[old_index]) {
2247 addClient(wins[new_index++]);
2248 } else {
2249 new_index++;
2250 old_index++;
2251 }
2252 }
2253 }
2254 }
2255
2256 delete [] p->clients;
2257 } else {
2258#ifdef NETWMDEBUG
2259 fprintf(stderr, "NETRootInfo::update: client list null, creating\n");
2260#endif
2261
2262 unsigned long n;
2263 for (n = 0; n < nitems_ret; n++) {
2264 addClient(wins[n]);
2265 }
2266 }
2267
2268 p->clients_count = nitems_ret;
2269 p->clients = nwindup(wins, p->clients_count);
2270 read_ok = true;
2271 }
2272
2273 if ( data_ret )
2274 XFree(data_ret);
2275 }
2276 if( !read_ok ) {
2277 for( unsigned int i = 0; i < p->clients_count; ++ i )
2278 removeClient(p->clients[i]);
2279 p->clients_count = 0;
2280 delete[] p->clients;
2281 p->clients = NULL;
2282 }
2283
2284#ifdef NETWMDEBUG
2285 fprintf(stderr, "NETRootInfo::update: client list updated (%ld clients)\n",
2286 p->clients_count);
2287#endif
2288 }
2289
2290 if (dirty & KDESystemTrayWindows) {
2291 bool read_ok = false;
2292 if (XGetWindowProperty(p->display, p->root, kde_net_system_tray_windows,
2293 0l, MAX_PROP_SIZE, False, XA_WINDOW, &type_ret,
2294 &format_ret, &nitems_ret, &unused, &data_ret)
2295 == Success) {
2296 if (type_ret == XA_WINDOW && format_ret == 32) {
2297 Window *wins = (Window *) data_ret;
2298
2299 qsort(wins, nitems_ret, sizeof(Window), wcmp);
2300
2301 if (p->kde_system_tray_windows) {
2302 if (role == Client) {
2303 unsigned long new_index = 0, new_count = nitems_ret;
2304 unsigned long old_index = 0,
2305 old_count = p->kde_system_tray_windows_count;
2306
2307 while(old_index < old_count || new_index < new_count) {
2308 if (old_index == old_count) {
2309 addSystemTrayWin(wins[new_index++]);
2310 } else if (new_index == new_count) {
2311 removeSystemTrayWin(p->kde_system_tray_windows[old_index++]);
2312 } else {
2313 if (p->kde_system_tray_windows[old_index] <
2314 wins[new_index]) {
2315 removeSystemTrayWin(p->kde_system_tray_windows[old_index++]);
2316 } else if (wins[new_index] <
2317 p->kde_system_tray_windows[old_index]) {
2318 addSystemTrayWin(wins[new_index++]);
2319 } else {
2320 new_index++;
2321 old_index++;
2322 }
2323 }
2324 }
2325 }
2326
2327 } else {
2328 unsigned long n;
2329 for (n = 0; n < nitems_ret; n++) {
2330 addSystemTrayWin(wins[n]);
2331 }
2332 }
2333
2334 p->kde_system_tray_windows_count = nitems_ret;
2335 delete [] p->kde_system_tray_windows;
2336 p->kde_system_tray_windows =
2337 nwindup(wins, p->kde_system_tray_windows_count);
2338 read_ok = true;
2339 }
2340
2341 if ( data_ret )
2342 XFree(data_ret);
2343 }
2344 if( !read_ok ) {
2345 for( unsigned int i = 0; i < p->kde_system_tray_windows_count; ++i )
2346 removeSystemTrayWin(p->kde_system_tray_windows[i]);
2347 p->kde_system_tray_windows_count = 0;
2348 delete [] p->kde_system_tray_windows;
2349 p->kde_system_tray_windows = NULL;
2350 }
2351 }
2352
2353 if (dirty & ClientListStacking) {
2354 p->stacking_count = 0;
2355 delete[] p->stacking;
2356 p->stacking = NULL;
2357 if (XGetWindowProperty(p->display, p->root, net_client_list_stacking,
2358 0, MAX_PROP_SIZE, False, XA_WINDOW, &type_ret,
2359 &format_ret, &nitems_ret, &unused, &data_ret)
2360 == Success) {
2361 if (type_ret == XA_WINDOW && format_ret == 32) {
2362 Window *wins = (Window *) data_ret;
2363
2364 p->stacking_count = nitems_ret;
2365 p->stacking = nwindup(wins, p->stacking_count);
2366 }
2367
2368#ifdef NETWMDEBUG
2369 fprintf(stderr,"NETRootInfo::update: client stacking updated (%ld clients)\n",
2370 p->stacking_count);
2371#endif
2372
2373 if ( data_ret )
2374 XFree(data_ret);
2375 }
2376 }
2377
2378 if (dirty & NumberOfDesktops) {
2379 p->number_of_desktops = 0;
2380
2381 if (XGetWindowProperty(p->display, p->root, net_number_of_desktops,
2382 0l, 1l, False, XA_CARDINAL, &type_ret, &format_ret,
2383 &nitems_ret, &unused, &data_ret)
2384 == Success) {
2385 if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 1) {
2386 p->number_of_desktops = *((long *) data_ret);
2387 }
2388
2389#ifdef NETWMDEBUG
2390 fprintf(stderr, "NETRootInfo::update: number of desktops = %d\n",
2391 p->number_of_desktops);
2392#endif
2393 if ( data_ret )
2394 XFree(data_ret);
2395 }
2396 }
2397
2398 if (dirty & DesktopGeometry) {
2399 p->geometry = p->rootSize;
2400 if (XGetWindowProperty(p->display, p->root, net_desktop_geometry,
2401 0l, 2l, False, XA_CARDINAL, &type_ret, &format_ret,
2402 &nitems_ret, &unused, &data_ret)
2403 == Success) {
2404 if (type_ret == XA_CARDINAL && format_ret == 32 &&
2405 nitems_ret == 2) {
2406 long *data = (long *) data_ret;
2407
2408 p->geometry.width = data[0];
2409 p->geometry.height = data[1];
2410
2411#ifdef NETWMDEBUG
2412 fprintf(stderr, "NETRootInfo::update: desktop geometry updated\n");
2413#endif
2414 }
2415 if ( data_ret )
2416 XFree(data_ret);
2417 }
2418 }
2419
2420 if (dirty & DesktopViewport) {
2421 for (int i = 0; i < p->viewport.size(); i++)
2422 p->viewport[i].x = p->viewport[i].y = 0;
2423 if (XGetWindowProperty(p->display, p->root, net_desktop_viewport,
2424 0l, 2l, False, XA_CARDINAL, &type_ret, &format_ret,
2425 &nitems_ret, &unused, &data_ret)
2426 == Success) {
2427 if (type_ret == XA_CARDINAL && format_ret == 32 &&
2428 nitems_ret == 2) {
2429 long *data = (long *) data_ret;
2430
2431 int d, i, n;
2432 n = nitems_ret / 2;
2433 for (d = 0, i = 0; d < n; d++) {
2434 p->viewport[d].x = data[i++];
2435 p->viewport[d].y = data[i++];
2436 }
2437
2438#ifdef NETWMDEBUG
2439 fprintf(stderr,
2440 "NETRootInfo::update: desktop viewport array updated (%d entries)\n",
2441 p->viewport.size());
2442
2443 if (nitems_ret % 2 != 0) {
2444 fprintf(stderr,
2445 "NETRootInfo::update(): desktop viewport array "
2446 "size not a multiple of 2\n");
2447 }
2448#endif
2449 }
2450 if ( data_ret )
2451 XFree(data_ret);
2452 }
2453 }
2454
2455 if (dirty & CurrentDesktop) {
2456 p->current_desktop = 0;
2457 if (XGetWindowProperty(p->display, p->root, net_current_desktop,
2458 0l, 1l, False, XA_CARDINAL, &type_ret, &format_ret,
2459 &nitems_ret, &unused, &data_ret)
2460 == Success) {
2461 if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 1) {
2462 p->current_desktop = *((long *) data_ret) + 1;
2463 }
2464
2465#ifdef NETWMDEBUG
2466 fprintf(stderr, "NETRootInfo::update: current desktop = %d\n",
2467 p->current_desktop);
2468#endif
2469 if ( data_ret )
2470 XFree(data_ret);
2471 }
2472 }
2473
2474 if (dirty & DesktopNames) {
2475 for( int i = 0; i < p->desktop_names.size(); ++i )
2476 delete[] p->desktop_names[ i ];
2477 p->desktop_names.reset();
2478 if (XGetWindowProperty(p->display, p->root, net_desktop_names,
2479 0l, MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
2480 &format_ret, &nitems_ret, &unused, &data_ret)
2481 == Success) {
2482 if (type_ret == UTF8_STRING && format_ret == 8) {
2483 const char *d = (const char *) data_ret;
2484 unsigned int s, n, index;
2485
2486 for (s = 0, n = 0, index = 0; n < nitems_ret; n++) {
2487 if (d[n] == '\0') {
2488 delete [] p->desktop_names[index];
2489 p->desktop_names[index++] = nstrndup((d + s), n - s + 1);
2490 s = n + 1;
2491 }
2492 }
2493 }
2494
2495#ifdef NETWMDEBUG
2496 fprintf(stderr, "NETRootInfo::update: desktop names array updated (%d entries)\n",
2497 p->desktop_names.size());
2498#endif
2499 if ( data_ret )
2500 XFree(data_ret);
2501 }
2502 }
2503
2504 if (dirty & ActiveWindow) {
2505 p->active = None;
2506 if (XGetWindowProperty(p->display, p->root, net_active_window, 0l, 1l,
2507 False, XA_WINDOW, &type_ret, &format_ret,
2508 &nitems_ret, &unused, &data_ret)
2509 == Success) {
2510 if (type_ret == XA_WINDOW && format_ret == 32 && nitems_ret == 1) {
2511 p->active = *((Window *) data_ret);
2512 }
2513
2514#ifdef NETWMDEBUG
2515 fprintf(stderr, "NETRootInfo::update: active window = 0x%lx\n",
2516 p->active);
2517#endif
2518 if ( data_ret )
2519 XFree(data_ret);
2520 }
2521 }
2522
2523 if (dirty & WorkArea) {
2524 p->workarea.reset();
2525 if (XGetWindowProperty(p->display, p->root, net_workarea, 0l,
2526 (p->number_of_desktops * 4), False, XA_CARDINAL,
2527 &type_ret, &format_ret, &nitems_ret, &unused,
2528 &data_ret)
2529 == Success) {
2530 if (type_ret == XA_CARDINAL && format_ret == 32 &&
2531 nitems_ret == (unsigned) (p->number_of_desktops * 4)) {
2532 long *d = (long *) data_ret;
2533 int i, j;
2534 for (i = 0, j = 0; i < p->number_of_desktops; i++) {
2535 p->workarea[i].pos.x = d[j++];
2536 p->workarea[i].pos.y = d[j++];
2537 p->workarea[i].size.width = d[j++];
2538 p->workarea[i].size.height = d[j++];
2539 }
2540 }
2541
2542#ifdef NETWMDEBUG
2543 fprintf(stderr, "NETRootInfo::update: work area array updated (%d entries)\n",
2544 p->workarea.size());
2545#endif
2546 if ( data_ret )
2547 XFree(data_ret);
2548 }
2549 }
2550
2551
2552 if (dirty & SupportingWMCheck) {
2553 p->supportwindow = None;
2554 delete[] p->name;
2555 p->name = NULL;
2556 if (XGetWindowProperty(p->display, p->root, net_supporting_wm_check,
2557 0l, 1l, False, XA_WINDOW, &type_ret, &format_ret,
2558 &nitems_ret, &unused, &data_ret)
2559 == Success) {
2560 if (type_ret == XA_WINDOW && format_ret == 32 && nitems_ret == 1) {
2561 p->supportwindow = *((Window *) data_ret);
2562
2563 unsigned char *name_ret;
2564 if (XGetWindowProperty(p->display, p->supportwindow,
2565 net_wm_name, 0l, MAX_PROP_SIZE, False,
2566 UTF8_STRING, &type_ret, &format_ret,
2567 &nitems_ret, &unused, &name_ret)
2568 == Success) {
2569 if (type_ret == UTF8_STRING && format_ret == 8)
2570 p->name = nstrndup((const char *) name_ret, nitems_ret);
2571
2572 if ( name_ret )
2573 XFree(name_ret);
2574 }
2575 }
2576
2577#ifdef NETWMDEBUG
2578 fprintf(stderr,
2579 "NETRootInfo::update: supporting window manager = '%s'\n",
2580 p->name);
2581#endif
2582 if ( data_ret )
2583 XFree(data_ret);
2584 }
2585 }
2586
2587 if (dirty & VirtualRoots) {
2588 p->virtual_roots_count = 0;
2589 delete[] p->virtual_roots;
2590 p->virtual_roots = NULL;
2591 if (XGetWindowProperty(p->display, p->root, net_virtual_roots,
2592 0, MAX_PROP_SIZE, False, XA_WINDOW, &type_ret,
2593 &format_ret, &nitems_ret, &unused, &data_ret)
2594 == Success) {
2595 if (type_ret == XA_WINDOW && format_ret == 32) {
2596 Window *wins = (Window *) data_ret;
2597
2598 p->virtual_roots_count = nitems_ret;
2599 p->virtual_roots = nwindup(wins, p->virtual_roots_count);
2600 }
2601
2602#ifdef NETWMDEBUG
2603 fprintf(stderr, "NETRootInfo::updated: virtual roots updated (%ld windows)\n",
2604 p->virtual_roots_count);
2605#endif
2606 if ( data_ret )
2607 XFree(data_ret);
2608 }
2609 }
2610
2611 if (dirty2 & WM2DesktopLayout) {
2612 p->desktop_layout_orientation = OrientationHorizontal;
2613 p->desktop_layout_corner = DesktopLayoutCornerTopLeft;
2614 p->desktop_layout_columns = p->desktop_layout_rows = 0;
2615 if (XGetWindowProperty(p->display, p->root, net_desktop_layout,
2616 0, MAX_PROP_SIZE, False, XA_CARDINAL, &type_ret,
2617 &format_ret, &nitems_ret, &unused, &data_ret)
2618 == Success) {
2619 if (type_ret == XA_CARDINAL && format_ret == 32) {
2620 long* data = (long*) data_ret;
2621 if( nitems_ret >= 4 && data[ 3 ] >= 0 && data[ 3 ] <= 3 )
2622 p->desktop_layout_corner = (NET::DesktopLayoutCorner)data[ 3 ];
2623 if( nitems_ret >= 3 ) {
2624 if( data[ 0 ] >= 0 && data[ 0 ] <= 1 )
2625 p->desktop_layout_orientation = (NET::Orientation)data[ 0 ];
2626 p->desktop_layout_columns = data[ 1 ];
2627 p->desktop_layout_rows = data[ 2 ];
2628 }
2629 }
2630
2631#ifdef NETWMDEBUG
2632 fprintf(stderr, "NETRootInfo::updated: desktop layout updated (%d %d %d %d)\n",
2633 p->desktop_layout_orientation, p->desktop_layout_columns,
2634 p->desktop_layout_rows, p->desktop_layout_corner );
2635#endif
2636 if ( data_ret )
2637 XFree(data_ret);
2638 }
2639 }
2640
2641 if (dirty2 & WM2ShowingDesktop) {
2642 p->showing_desktop = false;
2643 if (XGetWindowProperty(p->display, p->root, net_showing_desktop,
2644 0, MAX_PROP_SIZE, False, XA_CARDINAL, &type_ret,
2645 &format_ret, &nitems_ret, &unused, &data_ret)
2646 == Success) {
2647 if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 1) {
2648 p->showing_desktop = *((long *) data_ret);
2649 }
2650
2651#ifdef NETWMDEBUG
2652 fprintf(stderr, "NETRootInfo::update: showing desktop = %d\n",
2653 p->showing_desktop);
2654#endif
2655 if ( data_ret )
2656 XFree(data_ret);
2657 }
2658 }
2659}
2660
2661
2662Display *NETRootInfo::x11Display() const {
2663 return p->display;
2664}
2665
2666
2667Window NETRootInfo::rootWindow() const {
2668 return p->root;
2669}
2670
2671
2672Window NETRootInfo::supportWindow() const {
2673 return p->supportwindow;
2674}
2675
2676
2677const char *NETRootInfo::wmName() const {
2678 return p->name; }
2679
2680
2681int NETRootInfo::screenNumber() const {
2682 return p->screen;
2683}
2684
2685
2686unsigned long NETRootInfo::supported() const {
2687 return role == WindowManager
2688 ? p->properties[ PROTOCOLS ]
2689 : p->client_properties[ PROTOCOLS ];
2690}
2691
2692const unsigned long* NETRootInfo::supportedProperties() const {
2693 return p->properties;
2694}
2695
2696const unsigned long* NETRootInfo::passedProperties() const {
2697 return role == WindowManager
2698 ? p->properties
2699 : p->client_properties;
2700}
2701
2702bool NETRootInfo::isSupported( NET::Property property ) const {
2703 return p->properties[ PROTOCOLS ] & property;
2704}
2705
2706bool NETRootInfo::isSupported( NET::Property2 property ) const {
2707 return p->properties[ PROTOCOLS2 ] & property;
2708}
2709
2710bool NETRootInfo::isSupported( NET::WindowType type ) const {
2711 return p->properties[ WINDOW_TYPES ] & type;
2712}
2713
2714bool NETRootInfo::isSupported( NET::State state ) const {
2715 return p->properties[ STATES ] & state;
2716}
2717
2718bool NETRootInfo::isSupported( NET::Action action ) const {
2719 return p->properties[ ACTIONS ] & action;
2720}
2721
2722const Window *NETRootInfo::clientList() const {
2723 return p->clients;
2724}
2725
2726
2727int NETRootInfo::clientListCount() const {
2728 return p->clients_count;
2729}
2730
2731
2732const Window *NETRootInfo::clientListStacking() const {
2733 return p->stacking;
2734}
2735
2736
2737int NETRootInfo::clientListStackingCount() const {
2738 return p->stacking_count;
2739}
2740
2741
2742const Window *NETRootInfo::kdeSystemTrayWindows() const {
2743 return p->kde_system_tray_windows;
2744}
2745
2746
2747int NETRootInfo::kdeSystemTrayWindowsCount() const {
2748 return p->kde_system_tray_windows_count;
2749}
2750
2751
2752NETSize NETRootInfo::desktopGeometry(int) const {
2753 return p->geometry.width != 0 ? p->geometry : p->rootSize;
2754}
2755
2756
2757NETPoint NETRootInfo::desktopViewport(int desktop) const {
2758 if (desktop < 1) {
2759 NETPoint pt; // set to (0,0)
2760 return pt;
2761 }
2762
2763 return p->viewport[desktop - 1];
2764}
2765
2766
2767NETRect NETRootInfo::workArea(int desktop) const {
2768 if (desktop < 1) {
2769 NETRect rt;
2770 return rt;
2771 }
2772
2773 return p->workarea[desktop - 1];
2774}
2775
2776
2777const char *NETRootInfo::desktopName(int desktop) const {
2778 if (desktop < 1) {
2779 return 0;
2780 }
2781
2782 return p->desktop_names[desktop - 1];
2783}
2784
2785
2786const Window *NETRootInfo::virtualRoots( ) const {
2787 return p->virtual_roots;
2788}
2789
2790
2791int NETRootInfo::virtualRootsCount() const {
2792 return p->virtual_roots_count;
2793}
2794
2795
2796NET::Orientation NETRootInfo::desktopLayoutOrientation() const {
2797 return p->desktop_layout_orientation;
2798}
2799
2800
2801TQSize NETRootInfo::desktopLayoutColumnsRows() const {
2802 return TQSize( p->desktop_layout_columns, p->desktop_layout_rows );
2803}
2804
2805
2806NET::DesktopLayoutCorner NETRootInfo::desktopLayoutCorner() const {
2807 return p->desktop_layout_corner;
2808}
2809
2810
2811int NETRootInfo::numberOfDesktops() const {
2812 return p->number_of_desktops == 0 ? 1 : p->number_of_desktops;
2813}
2814
2815
2816int NETRootInfo::currentDesktop() const {
2817 return p->current_desktop == 0 ? 1 : p->current_desktop;
2818}
2819
2820
2821Window NETRootInfo::activeWindow() const {
2822 return p->active;
2823}
2824
2825
2826// NETWinInfo stuffs
2827
2828const int NETWinInfo::OnAllDesktops = NET::OnAllDesktops;
2829
2830NETWinInfo::NETWinInfo(Display *display, Window window, Window rootWindow,
2831 const unsigned long properties[], int properties_size,
2832 Role role)
2833{
2834
2835#ifdef NETWMDEBUG
2836 fprintf(stderr, "NETWinInfo::NETWinInfo: constructing object with role '%s'\n",
2837 (role == WindowManager) ? "WindowManager" : "Client");
2838#endif
2839
2840 p = new NETWinInfoPrivate;
2841 p->ref = 1;
2842
2843 p->display = display;
2844 p->window = window;
2845 p->root = rootWindow;
2846 p->mapping_state = Withdrawn;
2847 p->mapping_state_dirty = True;
2848 p->state = 0;
2849 p->types[ 0 ] = Unknown;
2850 p->name = (char *) 0;
2851 p->visible_name = (char *) 0;
2852 p->icon_name = (char *) 0;
2853 p->visible_icon_name = (char *) 0;
2854 p->desktop = p->pid = p->handled_icons = 0;
2855 p->user_time = -1U;
2856 p->startup_id = NULL;
2857 p->transient_for = None;
2858 p->window_group = None;
2859 p->allowed_actions = 0;
2860 p->has_net_support = false;
2861 p->class_class = (char*) 0;
2862 p->class_name = (char*) 0;
2863 p->role = (char*) 0;
2864 p->client_machine = (char*) 0;
2865
2866 // p->strut.left = p->strut.right = p->strut.top = p->strut.bottom = 0;
2867 // p->frame_strut.left = p->frame_strut.right = p->frame_strut.top =
2868 // p->frame_strut.bottom = 0;
2869
2870 p->kde_system_tray_win_for = 0;
2871
2872 for( int i = 0;
2873 i < PROPERTIES_SIZE;
2874 ++i )
2875 p->properties[ i ] = 0;
2876 if( properties_size > PROPERTIES_SIZE )
2877 properties_size = PROPERTIES_SIZE;
2878 for( int i = 0;
2879 i < properties_size;
2880 ++i )
2881 p->properties[ i ] = properties[ i ];
2882
2883 p->icon_count = 0;
2884
2885 this->role = role;
2886
2887 if (! netwm_atoms_created) create_atoms(p->display);
2888
2889 update(p->properties);
2890}
2891
2892
2893NETWinInfo::NETWinInfo(Display *display, Window window, Window rootWindow,
2894 unsigned long properties, Role role)
2895{
2896
2897#ifdef NETWMDEBUG
2898 fprintf(stderr, "NETWinInfo::NETWinInfo: constructing object with role '%s'\n",
2899 (role == WindowManager) ? "WindowManager" : "Client");
2900#endif
2901
2902 p = new NETWinInfoPrivate;
2903 p->ref = 1;
2904
2905 p->display = display;
2906 p->window = window;
2907 p->root = rootWindow;
2908 p->mapping_state = Withdrawn;
2909 p->mapping_state_dirty = True;
2910 p->state = 0;
2911 p->types[ 0 ] = Unknown;
2912 p->name = (char *) 0;
2913 p->visible_name = (char *) 0;
2914 p->icon_name = (char *) 0;
2915 p->visible_icon_name = (char *) 0;
2916 p->desktop = p->pid = p->handled_icons = 0;
2917 p->user_time = -1U;
2918 p->startup_id = NULL;
2919 p->transient_for = None;
2920 p->window_group = None;
2921 p->allowed_actions = 0;
2922 p->has_net_support = false;
2923 p->class_class = (char*) 0;
2924 p->class_name = (char*) 0;
2925 p->role = (char*) 0;
2926 p->client_machine = (char*) 0;
2927
2928 // p->strut.left = p->strut.right = p->strut.top = p->strut.bottom = 0;
2929 // p->frame_strut.left = p->frame_strut.right = p->frame_strut.top =
2930 // p->frame_strut.bottom = 0;
2931
2932 p->kde_system_tray_win_for = 0;
2933
2934 for( int i = 0;
2935 i < PROPERTIES_SIZE;
2936 ++i )
2937 p->properties[ i ] = 0;
2938 p->properties[ PROTOCOLS ] = properties;
2939
2940 p->icon_count = 0;
2941
2942 this->role = role;
2943
2944 if (! netwm_atoms_created) create_atoms(p->display);
2945
2946 update(p->properties);
2947}
2948
2949
2950NETWinInfo::NETWinInfo(const NETWinInfo &wininfo) {
2951 p = wininfo.p;
2952 p->ref++;
2953}
2954
2955
2956NETWinInfo::~NETWinInfo() {
2957 refdec_nwi(p);
2958
2959 if (! p->ref) delete p;
2960}
2961
2962
2963// assignment operator
2964
2965const NETWinInfo &NETWinInfo::operator=(const NETWinInfo &wininfo) {
2966
2967#ifdef NETWMDEBUG
2968 fprintf(stderr, "NETWinInfo::operator=()\n");
2969#endif
2970
2971 if (p != wininfo.p) {
2972 refdec_nwi(p);
2973
2974 if (! p->ref) delete p;
2975 }
2976
2977 p = wininfo.p;
2978 role = wininfo.role;
2979 p->ref++;
2980
2981 return *this;
2982}
2983
2984
2985void NETWinInfo::setIcon(NETIcon icon, Bool replace) {
2986 setIconInternal( p->icons, p->icon_count, net_wm_icon, icon, replace );
2987}
2988
2989void NETWinInfo::setIconInternal(NETRArray<NETIcon>& icons, int& icon_count, Atom property, NETIcon icon, Bool replace) {
2990 if (role != Client) return;
2991
2992 int proplen, i, sz, j;
2993
2994 if (replace) {
2995
2996 for (i = 0; i < icons.size(); i++) {
2997 delete [] icons[i].data;
2998 icons[i].data = 0;
2999 icons[i].size.width = 0;
3000 icons[i].size.height = 0;
3001 }
3002
3003 icon_count = 0;
3004 }
3005
3006 // assign icon
3007 icons[icon_count] = icon;
3008 icon_count++;
3009
3010 // do a deep copy, we want to own the data
3011 NETIcon &ni = icons[icon_count - 1];
3012 sz = ni.size.width * ni.size.height;
3013 CARD32 *d = new CARD32[sz];
3014 ni.data = (unsigned char *) d;
3015 memcpy(d, icon.data, sz * sizeof(CARD32));
3016
3017 // compute property length
3018 for (i = 0, proplen = 0; i < icon_count; i++) {
3019 proplen += 2 + (icons[i].size.width *
3020 icons[i].size.height);
3021 }
3022
3023 CARD32 *d32;
3024 long *prop = new long[proplen], *pprop = prop;
3025 for (i = 0; i < icon_count; i++) {
3026 // copy size into property
3027 *pprop++ = icons[i].size.width;
3028 *pprop++ = icons[i].size.height;
3029
3030 // copy data into property
3031 sz = (icons[i].size.width * icons[i].size.height);
3032 d32 = (CARD32 *) icons[i].data;
3033 for (j = 0; j < sz; j++) *pprop++ = *d32++;
3034 }
3035
3036 XChangeProperty(p->display, p->window, property, XA_CARDINAL, 32,
3037 PropModeReplace, (unsigned char *) prop, proplen);
3038
3039 delete [] prop;
3040}
3041
3042
3043void NETWinInfo::setIconGeometry(NETRect geometry) {
3044 if (role != Client) return;
3045
3046 p->icon_geom = geometry;
3047
3048 if( geometry.size.width == 0 ) // empty
3049 XDeleteProperty(p->display, p->window, net_wm_icon_geometry);
3050 else {
3051 long data[4];
3052 data[0] = geometry.pos.x;
3053 data[1] = geometry.pos.y;
3054 data[2] = geometry.size.width;
3055 data[3] = geometry.size.height;
3056
3057 XChangeProperty(p->display, p->window, net_wm_icon_geometry, XA_CARDINAL,
3058 32, PropModeReplace, (unsigned char *) data, 4);
3059 }
3060}
3061
3062
3063void NETWinInfo::setExtendedStrut(const NETExtendedStrut& extended_strut ) {
3064 if (role != Client) return;
3065
3066 p->extended_strut = extended_strut;
3067
3068 long data[12];
3069 data[0] = extended_strut.left_width;
3070 data[1] = extended_strut.right_width;
3071 data[2] = extended_strut.top_width;
3072 data[3] = extended_strut.bottom_width;
3073 data[4] = extended_strut.left_start;
3074 data[5] = extended_strut.left_end;
3075 data[6] = extended_strut.right_start;
3076 data[7] = extended_strut.right_end;
3077 data[8] = extended_strut.top_start;
3078 data[9] = extended_strut.top_end;
3079 data[10] = extended_strut.bottom_start;
3080 data[11] = extended_strut.bottom_end;
3081
3082 XChangeProperty(p->display, p->window, net_wm_extended_strut, XA_CARDINAL, 32,
3083 PropModeReplace, (unsigned char *) data, 12);
3084}
3085
3086
3087void NETWinInfo::setStrut(NETStrut strut) {
3088 if (role != Client) return;
3089
3090 p->strut = strut;
3091
3092 long data[4];
3093 data[0] = strut.left;
3094 data[1] = strut.right;
3095 data[2] = strut.top;
3096 data[3] = strut.bottom;
3097
3098 XChangeProperty(p->display, p->window, net_wm_strut, XA_CARDINAL, 32,
3099 PropModeReplace, (unsigned char *) data, 4);
3100}
3101
3102
3103void NETWinInfo::setState(unsigned long state, unsigned long mask) {
3104 if (p->mapping_state_dirty)
3105 updateWMState();
3106
3107 // setState() needs to know the current state, so read it even if not requested
3108 if( ( p->properties[ PROTOCOLS ] & WMState ) == 0 ) {
3109 p->properties[ PROTOCOLS ] |= WMState;
3110 unsigned long props[ PROPERTIES_SIZE ] = { WMState, 0 };
3111 assert( PROPERTIES_SIZE == 2 ); // add elements above
3112 update( props );
3113 p->properties[ PROTOCOLS ] &= ~WMState;
3114 }
3115
3116 if (role == Client && p->mapping_state != Withdrawn) {
3117
3118#ifdef NETWMDEBUG
3119 fprintf(stderr, "NETWinInfo::setState (0x%lx, 0x%lx) (Client)\n",
3120 state, mask);
3121#endif // NETWMDEBUG
3122
3123 XEvent e;
3124 e.xclient.type = ClientMessage;
3125 e.xclient.message_type = net_wm_state;
3126 e.xclient.display = p->display;
3127 e.xclient.window = p->window;
3128 e.xclient.format = 32;
3129 e.xclient.data.l[3] = 0l;
3130 e.xclient.data.l[4] = 0l;
3131
3132 if ((mask & Modal) && ((p->state & Modal) != (state & Modal))) {
3133 e.xclient.data.l[0] = (state & Modal) ? 1 : 0;
3134 e.xclient.data.l[1] = net_wm_state_modal;
3135 e.xclient.data.l[2] = 0l;
3136
3137 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3138 }
3139
3140 if ((mask & Sticky) && ((p->state & Sticky) != (state & Sticky))) {
3141 e.xclient.data.l[0] = (state & Sticky) ? 1 : 0;
3142 e.xclient.data.l[1] = net_wm_state_sticky;
3143 e.xclient.data.l[2] = 0l;
3144
3145 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3146 }
3147
3148 if ((mask & Max) && (( (p->state&mask) & Max) != (state & Max))) {
3149
3150 unsigned long wishstate = (p->state & ~mask) | (state & mask);
3151 if ( ( (wishstate & MaxHoriz) != (p->state & MaxHoriz) )
3152 && ( (wishstate & MaxVert) != (p->state & MaxVert) ) ) {
3153 if ( (wishstate & Max) == Max ) {
3154 e.xclient.data.l[0] = 1;
3155 e.xclient.data.l[1] = net_wm_state_max_horiz;
3156 e.xclient.data.l[2] = net_wm_state_max_vert;
3157 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3158 } else if ( (wishstate & Max) == 0 ) {
3159 e.xclient.data.l[0] = 0;
3160 e.xclient.data.l[1] = net_wm_state_max_horiz;
3161 e.xclient.data.l[2] = net_wm_state_max_vert;
3162 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3163 } else {
3164 e.xclient.data.l[0] = ( wishstate & MaxHoriz ) ? 1 : 0;
3165 e.xclient.data.l[1] = net_wm_state_max_horiz;
3166 e.xclient.data.l[2] = 0;
3167 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3168 e.xclient.data.l[0] = ( wishstate & MaxVert ) ? 1 : 0;
3169 e.xclient.data.l[1] = net_wm_state_max_vert;
3170 e.xclient.data.l[2] = 0;
3171 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3172 }
3173 } else if ( (wishstate & MaxVert) != (p->state & MaxVert) ) {
3174 e.xclient.data.l[0] = ( wishstate & MaxVert ) ? 1 : 0;
3175 e.xclient.data.l[1] = net_wm_state_max_vert;
3176 e.xclient.data.l[2] = 0;
3177 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3178 } else if ( (wishstate & MaxHoriz) != (p->state & MaxHoriz) ) {
3179 e.xclient.data.l[0] = ( wishstate & MaxHoriz ) ? 1 : 0;
3180 e.xclient.data.l[1] = net_wm_state_max_horiz;
3181 e.xclient.data.l[2] = 0;
3182 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3183 }
3184 }
3185
3186 if ((mask & Shaded) && ((p->state & Shaded) != (state & Shaded))) {
3187 e.xclient.data.l[0] = (state & Shaded) ? 1 : 0;
3188 e.xclient.data.l[1] = net_wm_state_shaded;
3189 e.xclient.data.l[2] = 0l;
3190
3191 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3192 }
3193
3194 if ((mask & SkipTaskbar) &&
3195 ((p->state & SkipTaskbar) != (state & SkipTaskbar))) {
3196 e.xclient.data.l[0] = (state & SkipTaskbar) ? 1 : 0;
3197 e.xclient.data.l[1] = net_wm_state_skip_taskbar;
3198 e.xclient.data.l[2] = 0l;
3199
3200 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3201 }
3202
3203 if ((mask & SkipPager) &&
3204 ((p->state & SkipPager) != (state & SkipPager))) {
3205 e.xclient.data.l[0] = (state & SkipPager) ? 1 : 0;
3206 e.xclient.data.l[1] = net_wm_state_skip_pager;
3207 e.xclient.data.l[2] = 0l;
3208
3209 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3210 }
3211
3212 if ((mask & Hidden) &&
3213 ((p->state & Hidden) != (state & Hidden))) {
3214 e.xclient.data.l[0] = (state & Hidden) ? 1 : 0;
3215 e.xclient.data.l[1] = net_wm_state_hidden;
3216 e.xclient.data.l[2] = 0l;
3217
3218 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3219 }
3220
3221 if ((mask & FullScreen) &&
3222 ((p->state & FullScreen) != (state & FullScreen))) {
3223 e.xclient.data.l[0] = (state & FullScreen) ? 1 : 0;
3224 e.xclient.data.l[1] = net_wm_state_fullscreen;
3225 e.xclient.data.l[2] = 0l;
3226
3227 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3228 }
3229
3230 if ((mask & KeepAbove) &&
3231 ((p->state & KeepAbove) != (state & KeepAbove))) {
3232 e.xclient.data.l[0] = (state & KeepAbove) ? 1 : 0;
3233 e.xclient.data.l[1] = net_wm_state_above;
3234 e.xclient.data.l[2] = 0l;
3235
3236 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3237 }
3238
3239 if ((mask & KeepBelow) &&
3240 ((p->state & KeepBelow) != (state & KeepBelow))) {
3241 e.xclient.data.l[0] = (state & KeepBelow) ? 1 : 0;
3242 e.xclient.data.l[1] = net_wm_state_below;
3243 e.xclient.data.l[2] = 0l;
3244
3245 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3246 }
3247
3248 if ((mask & StaysOnTop) && ((p->state & StaysOnTop) != (state & StaysOnTop))) {
3249 e.xclient.data.l[0] = (state & StaysOnTop) ? 1 : 0;
3250 e.xclient.data.l[1] = net_wm_state_stays_on_top;
3251 e.xclient.data.l[2] = 0l;
3252
3253 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3254 }
3255
3256 if ((mask & DemandsAttention) &&
3257 ((p->state & DemandsAttention) != (state & DemandsAttention))) {
3258 e.xclient.data.l[0] = (state & DemandsAttention) ? 1 : 0;
3259 e.xclient.data.l[1] = net_wm_state_demands_attention;
3260 e.xclient.data.l[2] = 0l;
3261
3262 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3263 }
3264
3265 } else {
3266 p->state &= ~mask;
3267 p->state |= state;
3268
3269 long data[50];
3270 int count = 0;
3271
3272 // hints
3273 if (p->state & Modal) data[count++] = net_wm_state_modal;
3274 if (p->state & MaxVert) data[count++] = net_wm_state_max_vert;
3275 if (p->state & MaxHoriz) data[count++] = net_wm_state_max_horiz;
3276 if (p->state & Shaded) data[count++] = net_wm_state_shaded;
3277 if (p->state & Hidden) data[count++] = net_wm_state_hidden;
3278 if (p->state & FullScreen) data[count++] = net_wm_state_fullscreen;
3279 if (p->state & DemandsAttention) data[count++] = net_wm_state_demands_attention;
3280
3281 // policy
3282 if (p->state & KeepAbove) data[count++] = net_wm_state_above;
3283 if (p->state & KeepBelow) data[count++] = net_wm_state_below;
3284 if (p->state & StaysOnTop) data[count++] = net_wm_state_stays_on_top;
3285 if (p->state & Sticky) data[count++] = net_wm_state_sticky;
3286 if (p->state & SkipTaskbar) data[count++] = net_wm_state_skip_taskbar;
3287 if (p->state & SkipPager) data[count++] = net_wm_state_skip_pager;
3288
3289#ifdef NETWMDEBUG
3290 fprintf(stderr, "NETWinInfo::setState: setting state property (%d)\n", count);
3291 for (int i = 0; i < count; i++) {
3292 char* data_ret = XGetAtomName(p->display, (Atom) data[i]);
3293 fprintf(stderr, "NETWinInfo::setState: state %ld '%s'\n",
3294 data[i], data_ret);
3295 if ( data_ret )
3296 XFree( data_ret );
3297 }
3298
3299#endif
3300
3301 XChangeProperty(p->display, p->window, net_wm_state, XA_ATOM, 32,
3302 PropModeReplace, (unsigned char *) data, count);
3303 }
3304}
3305
3306
3307void NETWinInfo::setWindowType(WindowType type) {
3308 if (role != Client) return;
3309
3310 int len;
3311 long data[2];
3312
3313 switch (type) {
3314 case Override:
3315 // spec extension: override window type. we must comply with the spec
3316 // and provide a fall back (normal seems best)
3317 data[0] = kde_net_wm_window_type_override;
3318 data[1] = net_wm_window_type_normal;
3319 len = 2;
3320 break;
3321
3322 case Dialog:
3323 data[0] = net_wm_window_type_dialog;
3324 data[1] = None;
3325 len = 1;
3326 break;
3327
3328 case Menu:
3329 data[0] = net_wm_window_type_menu;
3330 data[1] = None;
3331 len = 1;
3332 break;
3333
3334 case TopMenu:
3335 // spec extension: override window type. we must comply with the spec
3336 // and provide a fall back (dock seems best)
3337 data[0] = kde_net_wm_window_type_topmenu;
3338 data[1] = net_wm_window_type_dock;
3339 len = 2;
3340 break;
3341
3342 case Tool:
3343 data[0] = net_wm_window_type_toolbar;
3344 data[1] = None;
3345 len = 1;
3346 break;
3347
3348 case Dock:
3349 data[0] = net_wm_window_type_dock;
3350 data[1] = None;
3351 len = 1;
3352 break;
3353
3354 case Desktop:
3355 data[0] = net_wm_window_type_desktop;
3356 data[1] = None;
3357 len = 1;
3358 break;
3359
3360 case Utility:
3361 data[0] = net_wm_window_type_utility;
3362 data[1] = net_wm_window_type_dialog; // fallback for old netwm version
3363 len = 2;
3364 break;
3365
3366 case Splash:
3367 data[0] = net_wm_window_type_splash;
3368 data[1] = net_wm_window_type_dock; // fallback (dock seems best)
3369 len = 2;
3370 break;
3371
3372 case DropdownMenu:
3373 data[0] = net_wm_window_type_dropdown_menu;
3374 data[1] = None;
3375 len = 1;
3376 break;
3377
3378 case PopupMenu:
3379 data[0] = net_wm_window_type_popup_menu;
3380 data[1] = None;
3381 len = 1;
3382 break;
3383
3384 case Tooltip:
3385 data[0] = net_wm_window_type_tooltip;
3386 data[1] = None;
3387 len = 1;
3388 break;
3389
3390 case Notification:
3391 data[0] = net_wm_window_type_notification;
3392 data[1] = None;
3393 len = 1;
3394 break;
3395
3396 case ComboBox:
3397 data[0] = net_wm_window_type_combobox;
3398 data[1] = None;
3399 len = 1;
3400 break;
3401
3402 case DNDIcon:
3403 data[0] = net_wm_window_type_dnd;
3404 data[1] = None;
3405 len = 1;
3406 break;
3407
3408 default:
3409 case Normal:
3410 data[0] = net_wm_window_type_normal;
3411 data[1] = None;
3412 len = 1;
3413 break;
3414 }
3415
3416 XChangeProperty(p->display, p->window, net_wm_window_type, XA_ATOM, 32,
3417 PropModeReplace, (unsigned char *) &data, len);
3418}
3419
3420
3421void NETWinInfo::setName(const char *name) {
3422 if (role != Client) return;
3423
3424 delete [] p->name;
3425 p->name = nstrdup(name);
3426 if( p->name[ 0 ] != '\0' )
3427 XChangeProperty(p->display, p->window, net_wm_name, UTF8_STRING, 8,
3428 PropModeReplace, (unsigned char *) p->name,
3429 strlen(p->name));
3430 else
3431 XDeleteProperty(p->display, p->window, net_wm_name);
3432}
3433
3434
3435void NETWinInfo::setVisibleName(const char *visibleName) {
3436 if (role != WindowManager) return;
3437
3438 delete [] p->visible_name;
3439 p->visible_name = nstrdup(visibleName);
3440 if( p->visible_name[ 0 ] != '\0' )
3441 XChangeProperty(p->display, p->window, net_wm_visible_name, UTF8_STRING, 8,
3442 PropModeReplace, (unsigned char *) p->visible_name,
3443 strlen(p->visible_name));
3444 else
3445 XDeleteProperty(p->display, p->window, net_wm_visible_name);
3446}
3447
3448
3449void NETWinInfo::setIconName(const char *iconName) {
3450 if (role != Client) return;
3451
3452 delete [] p->icon_name;
3453 p->icon_name = nstrdup(iconName);
3454 if( p->icon_name[ 0 ] != '\0' )
3455 XChangeProperty(p->display, p->window, net_wm_icon_name, UTF8_STRING, 8,
3456 PropModeReplace, (unsigned char *) p->icon_name,
3457 strlen(p->icon_name));
3458 else
3459 XDeleteProperty(p->display, p->window, net_wm_icon_name);
3460}
3461
3462
3463void NETWinInfo::setVisibleIconName(const char *visibleIconName) {
3464 if (role != WindowManager) return;
3465
3466 delete [] p->visible_icon_name;
3467 p->visible_icon_name = nstrdup(visibleIconName);
3468 if( p->visible_icon_name[ 0 ] != '\0' )
3469 XChangeProperty(p->display, p->window, net_wm_visible_icon_name, UTF8_STRING, 8,
3470 PropModeReplace, (unsigned char *) p->visible_icon_name,
3471 strlen(p->visible_icon_name));
3472 else
3473 XDeleteProperty(p->display, p->window, net_wm_visible_icon_name);
3474}
3475
3476
3477void NETWinInfo::setDesktop(int desktop) {
3478 if (p->mapping_state_dirty)
3479 updateWMState();
3480
3481 if (role == Client && p->mapping_state != Withdrawn) {
3482 // we only send a ClientMessage if we are 1) a client and 2) managed
3483
3484 if ( desktop == 0 )
3485 return; // we can't do that while being managed
3486
3487 XEvent e;
3488
3489 e.xclient.type = ClientMessage;
3490 e.xclient.message_type = net_wm_desktop;
3491 e.xclient.display = p->display;
3492 e.xclient.window = p->window;
3493 e.xclient.format = 32;
3494 e.xclient.data.l[0] = desktop == OnAllDesktops ? OnAllDesktops : desktop - 1;
3495 e.xclient.data.l[1] = 0l;
3496 e.xclient.data.l[2] = 0l;
3497 e.xclient.data.l[3] = 0l;
3498 e.xclient.data.l[4] = 0l;
3499
3500 XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3501 } else {
3502 // otherwise we just set or remove the property directly
3503 p->desktop = desktop;
3504 long d = desktop;
3505
3506 if ( d != OnAllDesktops ) {
3507 if ( d == 0 ) {
3508 XDeleteProperty( p->display, p->window, net_wm_desktop );
3509 return;
3510 }
3511
3512 d -= 1;
3513 }
3514
3515 XChangeProperty(p->display, p->window, net_wm_desktop, XA_CARDINAL, 32,
3516 PropModeReplace, (unsigned char *) &d, 1);
3517 }
3518}
3519
3520
3521void NETWinInfo::setPid(int pid) {
3522 if (role != Client) return;
3523
3524 p->pid = pid;
3525 long d = pid;
3526 XChangeProperty(p->display, p->window, net_wm_pid, XA_CARDINAL, 32,
3527 PropModeReplace, (unsigned char *) &d, 1);
3528}
3529
3530
3531void NETWinInfo::setHandledIcons(Bool handled) {
3532 if (role != Client) return;
3533
3534 p->handled_icons = handled;
3535 long d = handled;
3536 XChangeProperty(p->display, p->window, net_wm_handled_icons, XA_CARDINAL, 32,
3537 PropModeReplace, (unsigned char *) &d, 1);
3538}
3539
3540void NETWinInfo::setStartupId(const char* id) {
3541 if (role != Client) return;
3542
3543 delete[] p->startup_id;
3544 p->startup_id = nstrdup(id);
3545 XChangeProperty(p->display, p->window, net_startup_id, UTF8_STRING, 8,
3546 PropModeReplace, reinterpret_cast< unsigned char* >( p->startup_id ),
3547 strlen( p->startup_id ));
3548}
3549
3550void NETWinInfo::setAllowedActions( unsigned long actions ) {
3551 if( role != WindowManager )
3552 return;
3553 long data[50];
3554 int count = 0;
3555
3556 p->allowed_actions = actions;
3557 if (p->allowed_actions & ActionMove) data[count++] = net_wm_action_move;
3558 if (p->allowed_actions & ActionResize) data[count++] = net_wm_action_resize;
3559 if (p->allowed_actions & ActionMinimize) data[count++] = net_wm_action_minimize;
3560 if (p->allowed_actions & ActionShade) data[count++] = net_wm_action_shade;
3561 if (p->allowed_actions & ActionStick) data[count++] = net_wm_action_stick;
3562 if (p->allowed_actions & ActionMaxVert) data[count++] = net_wm_action_max_vert;
3563 if (p->allowed_actions & ActionMaxHoriz) data[count++] = net_wm_action_max_horiz;
3564 if (p->allowed_actions & ActionFullScreen) data[count++] = net_wm_action_fullscreen;
3565 if (p->allowed_actions & ActionChangeDesktop) data[count++] = net_wm_action_change_desk;
3566 if (p->allowed_actions & ActionClose) data[count++] = net_wm_action_close;
3567
3568#ifdef NETWMDEBUG
3569 fprintf(stderr, "NETWinInfo::setAllowedActions: setting property (%d)\n", count);
3570 for (int i = 0; i < count; i++) {
3571 char* data_ret = XGetAtomName(p->display, (Atom) data[i]);
3572 fprintf(stderr, "NETWinInfo::setAllowedActions: action %ld '%s'\n",
3573 data[i], data_ret);
3574 if ( data_ret )
3575 XFree(data_ret);
3576 }
3577#endif
3578
3579 XChangeProperty(p->display, p->window, net_wm_allowed_actions, XA_ATOM, 32,
3580 PropModeReplace, (unsigned char *) data, count);
3581}
3582
3583void NETWinInfo::setKDESystemTrayWinFor(Window window) {
3584 if (role != Client) return;
3585
3586 p->kde_system_tray_win_for = window;
3587 XChangeProperty(p->display, p->window, kde_net_wm_system_tray_window_for,
3588 XA_WINDOW, 32, PropModeReplace,
3589 (unsigned char *) &(p->kde_system_tray_win_for), 1);
3590}
3591
3592
3593void NETWinInfo::setKDEFrameStrut(NETStrut strut) {
3594 setFrameExtents( strut );
3595}
3596
3597void NETWinInfo::setFrameExtents(NETStrut strut) {
3598 if (role != WindowManager) return;
3599
3600 p->frame_strut = strut;
3601
3602 long d[4];
3603 d[0] = strut.left;
3604 d[1] = strut.right;
3605 d[2] = strut.top;
3606 d[3] = strut.bottom;
3607
3608 XChangeProperty(p->display, p->window, net_frame_extents, XA_CARDINAL, 32,
3609 PropModeReplace, (unsigned char *) d, 4);
3610 XChangeProperty(p->display, p->window, kde_net_wm_frame_strut, XA_CARDINAL, 32,
3611 PropModeReplace, (unsigned char *) d, 4);
3612}
3613
3614
3615void NETWinInfo::kdeGeometry(NETRect& frame, NETRect& window) {
3616 if (p->win_geom.size.width == 0 || p->win_geom.size.height == 0) {
3617 Window unused;
3618 int x, y;
3619 unsigned int w, h, junk;
3620 XGetGeometry(p->display, p->window, &unused, &x, &y, &w, &h, &junk, &junk);
3621 XTranslateCoordinates(p->display, p->window, p->root, 0, 0, &x, &y, &unused
3622 );
3623
3624 p->win_geom.pos.x = x;
3625 p->win_geom.pos.y = y;
3626
3627 p->win_geom.size.width = w;
3628 p->win_geom.size.height = h;
3629 }
3630// TODO try to work also without _KDE_NET_WM_FRAME_STRUT
3631 window = p->win_geom;
3632
3633 frame.pos.x = window.pos.x - p->frame_strut.left;
3634 frame.pos.y = window.pos.y - p->frame_strut.top;
3635 frame.size.width = window.size.width + p->frame_strut.left + p->frame_strut.right;
3636 frame.size.height = window.size.height + p->frame_strut.top + p->frame_strut.bottom;
3637}
3638
3639
3640NETIcon NETWinInfo::icon(int width, int height) const {
3641 return iconInternal( p->icons, p->icon_count, width, height );
3642}
3643
3644NETIcon NETWinInfo::iconInternal(NETRArray<NETIcon>& icons, int icon_count, int width, int height) const {
3645 NETIcon result;
3646
3647 if ( !icon_count ) {
3648 result.size.width = 0;
3649 result.size.height = 0;
3650 result.data = 0;
3651 return result;
3652 }
3653
3654 // find the largest icon
3655 result = icons[0];
3656 for (int i = 1; i < icons.size(); i++) {
3657 if( icons[i].size.width >= result.size.width &&
3658 icons[i].size.height >= result.size.height )
3659 result = icons[i];
3660 }
3661
3662 // return the largest icon if w and h are -1
3663 if (width == -1 && height == -1) return result;
3664
3665 // find the icon that's closest in size to w x h...
3666 for (int i = 0; i < icons.size(); i++) {
3667 if ((icons[i].size.width >= width &&
3668 icons[i].size.width < result.size.width) &&
3669 (icons[i].size.height >= height &&
3670 icons[i].size.height < result.size.height))
3671 result = icons[i];
3672 }
3673
3674 return result;
3675}
3676
3677void NETWinInfo::setUserTime( Time time ) {
3678 if (role != Client) return;
3679
3680 p->user_time = time;
3681 long d = time;
3682 XChangeProperty(p->display, p->window, net_wm_user_time, XA_CARDINAL, 32,
3683 PropModeReplace, (unsigned char *) &d, 1);
3684}
3685
3686
3687unsigned long NETWinInfo::event(XEvent *ev )
3688{
3689 unsigned long props[ 1 ];
3690 event( ev, props, 1 );
3691 return props[ 0 ];
3692}
3693
3694void NETWinInfo::event(XEvent *event, unsigned long* properties, int properties_size ) {
3695 unsigned long props[ PROPERTIES_SIZE ] = { 0, 0 };
3696 assert( PROPERTIES_SIZE == 2 ); // add elements above
3697 unsigned long& dirty = props[ PROTOCOLS ];
3698 unsigned long& dirty2 = props[ PROTOCOLS2 ];
3699 bool do_update = false;
3700
3701 if (role == WindowManager && event->type == ClientMessage &&
3702 event->xclient.format == 32) {
3703
3704#ifdef NETWMDEBUG
3705 fprintf(stderr, "NETWinInfo::event: handling ClientMessage event\n");
3706#endif // NETWMDEBUG
3707
3708 if (event->xclient.message_type == net_wm_state) {
3709 dirty = WMState;
3710
3711 // we need to generate a change mask
3712
3713#ifdef NETWMDEBUG
3714 fprintf(stderr,
3715 "NETWinInfo::event: state client message, getting new state/mask\n");
3716#endif
3717
3718 int i;
3719 long state = 0, mask = 0;
3720
3721 for (i = 1; i < 3; i++) {
3722#ifdef NETWMDEBUG
3723 char* debug_txt = XGetAtomName(p->display, (Atom) event->xclient.data.l[i]);
3724 fprintf(stderr, "NETWinInfo::event: message %ld '%s'\n",
3725 event->xclient.data.l[i], debug_txt );
3726 if ( debug_txt )
3727 XFree( debug_txt );
3728#endif
3729
3730 if ((Atom) event->xclient.data.l[i] == net_wm_state_modal)
3731 mask |= Modal;
3732 else if ((Atom) event->xclient.data.l[i] == net_wm_state_sticky)
3733 mask |= Sticky;
3734 else if ((Atom) event->xclient.data.l[i] == net_wm_state_max_vert)
3735 mask |= MaxVert;
3736 else if ((Atom) event->xclient.data.l[i] == net_wm_state_max_horiz)
3737 mask |= MaxHoriz;
3738 else if ((Atom) event->xclient.data.l[i] == net_wm_state_shaded)
3739 mask |= Shaded;
3740 else if ((Atom) event->xclient.data.l[i] == net_wm_state_skip_taskbar)
3741 mask |= SkipTaskbar;
3742 else if ((Atom) event->xclient.data.l[i] == net_wm_state_skip_pager)
3743 mask |= SkipPager;
3744 else if ((Atom) event->xclient.data.l[i] == net_wm_state_hidden)
3745 mask |= Hidden;
3746 else if ((Atom) event->xclient.data.l[i] == net_wm_state_fullscreen)
3747 mask |= FullScreen;
3748 else if ((Atom) event->xclient.data.l[i] == net_wm_state_above)
3749 mask |= KeepAbove;
3750 else if ((Atom) event->xclient.data.l[i] == net_wm_state_below)
3751 mask |= KeepBelow;
3752 else if ((Atom) event->xclient.data.l[i] == net_wm_state_demands_attention)
3753 mask |= DemandsAttention;
3754 else if ((Atom) event->xclient.data.l[i] == net_wm_state_stays_on_top)
3755 mask |= StaysOnTop;
3756 }
3757
3758 // when removing, we just leave newstate == 0
3759 switch (event->xclient.data.l[0]) {
3760 case 1: // set
3761 // to set... the change state should be the same as the mask
3762 state = mask;
3763 break;
3764
3765 case 2: // toggle
3766 // to toggle, we need to xor the current state with the new state
3767 state = (p->state & mask) ^ mask;
3768 break;
3769
3770 default:
3771 // to clear state, the new state should stay zero
3772 ;
3773 }
3774
3775#ifdef NETWMDEBUG
3776 fprintf(stderr, "NETWinInfo::event: calling changeState(%lx, %lx)\n",
3777 state, mask);
3778#endif
3779
3780 changeState(state, mask);
3781 } else if (event->xclient.message_type == net_wm_desktop) {
3782 dirty = WMDesktop;
3783
3784 if( event->xclient.data.l[0] == OnAllDesktops )
3785 changeDesktop( OnAllDesktops );
3786 else
3787 changeDesktop(event->xclient.data.l[0] + 1);
3788 }
3789 }
3790
3791 if (event->type == PropertyNotify) {
3792
3793#ifdef NETWMDEBUG
3794 fprintf(stderr, "NETWinInfo::event: handling PropertyNotify event\n");
3795#endif
3796
3797 XEvent pe = *event;
3798
3799 Bool done = False;
3800 Bool compaction = False;
3801 while (! done) {
3802
3803#ifdef NETWMDEBUG
3804 fprintf(stderr, "NETWinInfo::event: loop fire\n");
3805#endif
3806
3807 if (pe.xproperty.atom == net_wm_name)
3808 dirty |= WMName;
3809 else if (pe.xproperty.atom == net_wm_visible_name)
3810 dirty |= WMVisibleName;
3811 else if (pe.xproperty.atom == net_wm_desktop)
3812 dirty |= WMDesktop;
3813 else if (pe.xproperty.atom == net_wm_window_type)
3814 dirty |=WMWindowType;
3815 else if (pe.xproperty.atom == net_wm_state)
3816 dirty |= WMState;
3817 else if (pe.xproperty.atom == net_wm_strut)
3818 dirty |= WMStrut;
3819 else if (pe.xproperty.atom == net_wm_extended_strut)
3820 dirty2 |= WM2ExtendedStrut;
3821 else if (pe.xproperty.atom == net_wm_icon_geometry)
3822 dirty |= WMIconGeometry;
3823 else if (pe.xproperty.atom == net_wm_icon)
3824 dirty |= WMIcon;
3825 else if (pe.xproperty.atom == net_wm_pid)
3826 dirty |= WMPid;
3827 else if (pe.xproperty.atom == net_wm_handled_icons)
3828 dirty |= WMHandledIcons;
3829 else if (pe.xproperty.atom == net_startup_id)
3830 dirty2 |= WM2StartupId;
3831 else if (pe.xproperty.atom == net_wm_allowed_actions)
3832 dirty2 |= WM2AllowedActions;
3833 else if (pe.xproperty.atom == kde_net_wm_system_tray_window_for)
3834 dirty |= WMKDESystemTrayWinFor;
3835 else if (pe.xproperty.atom == xa_wm_state)
3836 dirty |= XAWMState;
3837 else if (pe.xproperty.atom == net_frame_extents)
3838 dirty |= WMFrameExtents;
3839 else if (pe.xproperty.atom == kde_net_wm_frame_strut)
3840 dirty |= WMKDEFrameStrut;
3841 else if (pe.xproperty.atom == net_wm_icon_name)
3842 dirty |= WMIconName;
3843 else if (pe.xproperty.atom == net_wm_visible_icon_name)
3844 dirty |= WMVisibleIconName;
3845 else if (pe.xproperty.atom == net_wm_user_time)
3846 dirty2 |= WM2UserTime;
3847 else if (pe.xproperty.atom == XA_WM_HINTS)
3848 dirty2 |= WM2GroupLeader;
3849 else if (pe.xproperty.atom == XA_WM_TRANSIENT_FOR)
3850 dirty2 |= WM2TransientFor;
3851 else if (pe.xproperty.atom == XA_WM_CLASS)
3852 dirty2 |= WM2WindowClass;
3853 else if (pe.xproperty.atom == wm_window_role)
3854 dirty2 |= WM2WindowRole;
3855 else if (pe.xproperty.atom == XA_WM_CLIENT_MACHINE)
3856 dirty2 |= WM2ClientMachine;
3857 else {
3858
3859#ifdef NETWMDEBUG
3860 fprintf(stderr, "NETWinInfo::event: putting back event and breaking\n");
3861#endif
3862
3863 if ( compaction )
3864 XPutBackEvent(p->display, &pe);
3865 break;
3866 }
3867
3868 if (XCheckTypedWindowEvent(p->display, p->window, PropertyNotify, &pe) )
3869 compaction = True;
3870 else
3871 break;
3872 }
3873
3874 do_update = true;
3875 } else if (event->type == ConfigureNotify) {
3876
3877#ifdef NETWMDEBUG
3878 fprintf(stderr, "NETWinInfo::event: handling ConfigureNotify event\n");
3879#endif
3880
3881 dirty |= WMGeometry;
3882
3883 // update window geometry
3884 p->win_geom.pos.x = event->xconfigure.x;
3885 p->win_geom.pos.y = event->xconfigure.y;
3886 p->win_geom.size.width = event->xconfigure.width;
3887 p->win_geom.size.height = event->xconfigure.height;
3888 }
3889
3890 if( do_update )
3891 update( props );
3892
3893 if( properties_size > PROPERTIES_SIZE )
3894 properties_size = PROPERTIES_SIZE;
3895 for( int i = 0;
3896 i < properties_size;
3897 ++i )
3898 properties[ i ] = props[ i ];
3899}
3900
3901void NETWinInfo::updateWMState() {
3902 unsigned long props[ PROPERTIES_SIZE ] = { XAWMState, 0 };
3903 assert( PROPERTIES_SIZE == 2 ); // add elements above
3904 update( props );
3905}
3906
3907void NETWinInfo::update(const unsigned long dirty_props[]) {
3908 Atom type_ret;
3909 int format_ret;
3910 unsigned long nitems_ret, unused;
3911 unsigned char *data_ret;
3912 unsigned long props[ PROPERTIES_SIZE ];
3913 for( int i = 0;
3914 i < PROPERTIES_SIZE;
3915 ++i )
3916 props[ i ] = dirty_props[ i ] & p->properties[ i ];
3917 const unsigned long& dirty = props[ PROTOCOLS ];
3918 const unsigned long& dirty2 = props[ PROTOCOLS2 ];
3919
3920 // we *always* want to update WM_STATE if set in dirty_props
3921 if( dirty_props[ PROTOCOLS ] & XAWMState )
3922 props[ PROTOCOLS ] |= XAWMState;
3923
3924 if (dirty & XAWMState) {
3925 p->mapping_state = Withdrawn;
3926 if (XGetWindowProperty(p->display, p->window, xa_wm_state, 0l, 1l,
3927 False, xa_wm_state, &type_ret, &format_ret,
3928 &nitems_ret, &unused, &data_ret)
3929 == Success) {
3930 if (type_ret == xa_wm_state && format_ret == 32 &&
3931 nitems_ret == 1) {
3932 long *state = (long *) data_ret;
3933
3934 switch(*state) {
3935 case IconicState:
3936 p->mapping_state = Iconic;
3937 break;
3938 case NormalState:
3939 p->mapping_state = Visible;
3940 break;
3941 case WithdrawnState:
3942 default:
3943 p->mapping_state = Withdrawn;
3944 break;
3945 }
3946
3947 p->mapping_state_dirty = False;
3948 }
3949 if ( data_ret )
3950 XFree(data_ret);
3951 }
3952 }
3953
3954 if (dirty & WMState) {
3955 p->state = 0;
3956 if (XGetWindowProperty(p->display, p->window, net_wm_state, 0l, 2048l,
3957 False, XA_ATOM, &type_ret, &format_ret,
3958 &nitems_ret, &unused, &data_ret)
3959 == Success) {
3960 if (type_ret == XA_ATOM && format_ret == 32 && nitems_ret > 0) {
3961 // determine window state
3962#ifdef NETWMDEBUG
3963 fprintf(stderr, "NETWinInfo::update: updating window state (%ld)\n",
3964 nitems_ret);
3965#endif
3966
3967 long *states = (long *) data_ret;
3968 unsigned long count;
3969
3970 for (count = 0; count < nitems_ret; count++) {
3971#ifdef NETWMDEBUG
3972 char* data_ret = XGetAtomName(p->display, (Atom) states[count]);
3973 fprintf(stderr,
3974 "NETWinInfo::update: adding window state %ld '%s'\n",
3975 states[count], data_ret );
3976 if ( data_ret )
3977 XFree( data_ret );
3978#endif
3979
3980 if ((Atom) states[count] == net_wm_state_modal)
3981 p->state |= Modal;
3982 else if ((Atom) states[count] == net_wm_state_sticky)
3983 p->state |= Sticky;
3984 else if ((Atom) states[count] == net_wm_state_max_vert)
3985 p->state |= MaxVert;
3986 else if ((Atom) states[count] == net_wm_state_max_horiz)
3987 p->state |= MaxHoriz;
3988 else if ((Atom) states[count] == net_wm_state_shaded)
3989 p->state |= Shaded;
3990 else if ((Atom) states[count] == net_wm_state_skip_taskbar)
3991 p->state |= SkipTaskbar;
3992 else if ((Atom) states[count] == net_wm_state_skip_pager)
3993 p->state |= SkipPager;
3994 else if ((Atom) states[count] == net_wm_state_hidden)
3995 p->state |= Hidden;
3996 else if ((Atom) states[count] == net_wm_state_fullscreen)
3997 p->state |= FullScreen;
3998 else if ((Atom) states[count] == net_wm_state_above)
3999 p->state |= KeepAbove;
4000 else if ((Atom) states[count] == net_wm_state_below)
4001 p->state |= KeepBelow;
4002 else if ((Atom) states[count] == net_wm_state_demands_attention)
4003 p->state |= DemandsAttention;
4004 else if ((Atom) states[count] == net_wm_state_stays_on_top)
4005 p->state |= StaysOnTop;
4006 }
4007 }
4008 if ( data_ret )
4009 XFree(data_ret);
4010 }
4011 }
4012
4013 if (dirty & WMDesktop) {
4014 p->desktop = 0;
4015 if (XGetWindowProperty(p->display, p->window, net_wm_desktop, 0l, 1l,
4016 False, XA_CARDINAL, &type_ret,
4017 &format_ret, &nitems_ret,
4018 &unused, &data_ret)
4019 == Success) {
4020 if (type_ret == XA_CARDINAL && format_ret == 32 &&
4021 nitems_ret == 1) {
4022 p->desktop = *((long *) data_ret);
4023 if ((signed) p->desktop != OnAllDesktops)
4024 p->desktop++;
4025
4026 if ( p->desktop == 0 )
4027 p->desktop = OnAllDesktops;
4028 }
4029 if ( data_ret )
4030 XFree(data_ret);
4031 }
4032 }
4033
4034 if (dirty & WMName) {
4035 delete[] p->name;
4036 p->name = NULL;
4037 if (XGetWindowProperty(p->display, p->window, net_wm_name, 0l,
4038 MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
4039 &format_ret, &nitems_ret, &unused, &data_ret)
4040 == Success) {
4041 if (type_ret == UTF8_STRING && format_ret == 8 && nitems_ret > 0) {
4042 p->name = nstrndup((const char *) data_ret, nitems_ret);
4043 }
4044
4045 if( data_ret )
4046 XFree(data_ret);
4047 }
4048 }
4049
4050 if (dirty & WMVisibleName) {
4051 delete[] p->visible_name;
4052 p->visible_name = NULL;
4053 if (XGetWindowProperty(p->display, p->window, net_wm_visible_name, 0l,
4054 MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
4055 &format_ret, &nitems_ret, &unused, &data_ret)
4056 == Success) {
4057 if (type_ret == UTF8_STRING && format_ret == 8 && nitems_ret > 0) {
4058 p->visible_name = nstrndup((const char *) data_ret, nitems_ret);
4059 }
4060
4061 if( data_ret )
4062 XFree(data_ret);
4063 }
4064 }
4065
4066 if (dirty & WMIconName) {
4067 delete[] p->icon_name;
4068 p->icon_name = NULL;
4069 if (XGetWindowProperty(p->display, p->window, net_wm_icon_name, 0l,
4070 MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
4071 &format_ret, &nitems_ret, &unused, &data_ret)
4072 == Success) {
4073 if (type_ret == UTF8_STRING && format_ret == 8 && nitems_ret > 0) {
4074 p->icon_name = nstrndup((const char *) data_ret, nitems_ret);
4075 }
4076
4077 if( data_ret )
4078 XFree(data_ret);
4079 }
4080 }
4081
4082 if (dirty & WMVisibleIconName)
4083 {
4084 delete[] p->visible_icon_name;
4085 p->visible_icon_name = NULL;
4086 if (XGetWindowProperty(p->display, p->window, net_wm_visible_icon_name, 0l,
4087 MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
4088 &format_ret, &nitems_ret, &unused, &data_ret)
4089 == Success) {
4090 if (type_ret == UTF8_STRING && format_ret == 8 && nitems_ret > 0) {
4091 p->visible_icon_name = nstrndup((const char *) data_ret, nitems_ret);
4092 }
4093
4094 if( data_ret )
4095 XFree(data_ret);
4096 }
4097 }
4098
4099 if (dirty & WMWindowType) {
4100 p->types.reset();
4101 p->types[ 0 ] = Unknown;
4102 p->has_net_support = false;
4103 if (XGetWindowProperty(p->display, p->window, net_wm_window_type, 0l, 2048l,
4104 False, XA_ATOM, &type_ret, &format_ret,
4105 &nitems_ret, &unused, &data_ret)
4106 == Success) {
4107 if (type_ret == XA_ATOM && format_ret == 32 && nitems_ret > 0) {
4108 // determine the window type
4109#ifdef NETWMDEBUG
4110 fprintf(stderr, "NETWinInfo::update: getting window type (%ld)\n",
4111 nitems_ret);
4112#endif
4113
4114 p->has_net_support = true;
4115
4116 unsigned long count = 0;
4117 long *types = (long *) data_ret;
4118 int pos = 0;
4119
4120 while (count < nitems_ret) {
4121 // remember all window types we know
4122#ifdef NETWMDEBUG
4123 char* debug_type = XGetAtomName(p->display, (Atom) types[count]);
4124 fprintf(stderr,
4125 "NETWinInfo::update: examining window type %ld %s\n",
4126 types[count], debug_type );
4127 if ( debug_type )
4128 XFree( debug_type );
4129#endif
4130
4131 if ((Atom) types[count] == net_wm_window_type_normal)
4132 p->types[ pos++ ] = Normal;
4133 else if ((Atom) types[count] == net_wm_window_type_desktop)
4134 p->types[ pos++ ] = Desktop;
4135 else if ((Atom) types[count] == net_wm_window_type_dock)
4136 p->types[ pos++ ] = Dock;
4137 else if ((Atom) types[count] == net_wm_window_type_toolbar)
4138 p->types[ pos++ ] = Tool;
4139 else if ((Atom) types[count] == net_wm_window_type_menu)
4140 p->types[ pos++ ] = Menu;
4141 else if ((Atom) types[count] == net_wm_window_type_dialog)
4142 p->types[ pos++ ] = Dialog;
4143 else if ((Atom) types[count] == net_wm_window_type_utility)
4144 p->types[ pos++ ] = Utility;
4145 else if ((Atom) types[count] == net_wm_window_type_splash)
4146 p->types[ pos++ ] = Splash;
4147 else if ((Atom) types[count] == net_wm_window_type_dropdown_menu)
4148 p->types[ pos++ ] = DropdownMenu;
4149 else if ((Atom) types[count] == net_wm_window_type_popup_menu)
4150 p->types[ pos++ ] = PopupMenu;
4151 else if ((Atom) types[count] == net_wm_window_type_tooltip)
4152 p->types[ pos++ ] = Tooltip;
4153 else if ((Atom) types[count] == net_wm_window_type_notification)
4154 p->types[ pos++ ] = Notification;
4155 else if ((Atom) types[count] == net_wm_window_type_combobox)
4156 p->types[ pos++ ] = ComboBox;
4157 else if ((Atom) types[count] == net_wm_window_type_dnd)
4158 p->types[ pos++ ] = DNDIcon;
4159 else if ((Atom) types[count] == kde_net_wm_window_type_override)
4160 p->types[ pos++ ] = Override;
4161 else if ((Atom) types[count] == kde_net_wm_window_type_topmenu)
4162 p->types[ pos++ ] = TopMenu;
4163
4164 count++;
4165 }
4166 }
4167
4168 if ( data_ret )
4169 XFree(data_ret);
4170 }
4171 }
4172
4173 if (dirty & WMStrut) {
4174 p->strut = NETStrut();
4175 if (XGetWindowProperty(p->display, p->window, net_wm_strut, 0l, 4l,
4176 False, XA_CARDINAL, &type_ret, &format_ret,
4177 &nitems_ret, &unused, &data_ret)
4178 == Success) {
4179 if (type_ret == XA_CARDINAL && format_ret == 32 &&
4180 nitems_ret == 4) {
4181 long *d = (long *) data_ret;
4182 p->strut.left = d[0];
4183 p->strut.right = d[1];
4184 p->strut.top = d[2];
4185 p->strut.bottom = d[3];
4186 }
4187 if ( data_ret )
4188 XFree(data_ret);
4189 }
4190 }
4191
4192 if (dirty2 & WM2ExtendedStrut) {
4193 p->extended_strut = NETExtendedStrut();
4194 if (XGetWindowProperty(p->display, p->window, net_wm_extended_strut, 0l, 12l,
4195 False, XA_CARDINAL, &type_ret, &format_ret,
4196 &nitems_ret, &unused, &data_ret)
4197 == Success) {
4198 if (type_ret == XA_CARDINAL && format_ret == 32 &&
4199 nitems_ret == 12) {
4200 long *d = (long *) data_ret;
4201 p->extended_strut.left_width = d[0];
4202 p->extended_strut.right_width = d[1];
4203 p->extended_strut.top_width = d[2];
4204 p->extended_strut.bottom_width = d[3];
4205 p->extended_strut.left_start = d[4];
4206 p->extended_strut.left_end = d[5];
4207 p->extended_strut.right_start = d[6];
4208 p->extended_strut.right_end = d[7];
4209 p->extended_strut.top_start = d[8];
4210 p->extended_strut.top_end = d[9];
4211 p->extended_strut.bottom_start = d[10];
4212 p->extended_strut.bottom_end = d[11];
4213 }
4214 if ( data_ret )
4215 XFree(data_ret);
4216 }
4217 }
4218
4219 if (dirty & WMIconGeometry) {
4220 p->icon_geom = NETRect();
4221 if (XGetWindowProperty(p->display, p->window, net_wm_icon_geometry, 0l, 4l,
4222 False, XA_CARDINAL, &type_ret, &format_ret,
4223 &nitems_ret, &unused, &data_ret)
4224 == Success) {
4225 if (type_ret == XA_CARDINAL && format_ret == 32 &&
4226 nitems_ret == 4) {
4227 long *d = (long *) data_ret;
4228 p->icon_geom.pos.x = d[0];
4229 p->icon_geom.pos.y = d[1];
4230 p->icon_geom.size.width = d[2];
4231 p->icon_geom.size.height = d[3];
4232 }
4233 if ( data_ret )
4234 XFree(data_ret);
4235 }
4236 }
4237
4238 if (dirty & WMIcon) {
4239 readIcon(p->display,p->window,net_wm_icon,p->icons,p->icon_count);
4240 }
4241
4242 if (dirty & WMKDESystemTrayWinFor) {
4243 p->kde_system_tray_win_for = 0;
4244 if (XGetWindowProperty(p->display, p->window, kde_net_wm_system_tray_window_for,
4245 0l, 1l, False, XA_WINDOW, &type_ret, &format_ret,
4246 &nitems_ret, &unused, &data_ret)
4247 == Success) {
4248 if (type_ret == XA_WINDOW && format_ret == 32 &&
4249 nitems_ret == 1) {
4250 p->kde_system_tray_win_for = *((Window *) data_ret);
4251 if ( p->kde_system_tray_win_for == 0 )
4252 p->kde_system_tray_win_for = p->root;
4253 }
4254 if ( data_ret )
4255 XFree(data_ret);
4256 }
4257 }
4258
4259 if (dirty & WMFrameExtents) {
4260 p->frame_strut = NETStrut();
4261 bool ok = false;
4262 if (XGetWindowProperty(p->display, p->window, net_frame_extents,
4263 0l, 4l, False, XA_CARDINAL, &type_ret, &format_ret,
4264 &nitems_ret, &unused, &data_ret) == Success) {
4265 if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 4) {
4266 ok = true;
4267 long *d = (long *) data_ret;
4268
4269 p->frame_strut.left = d[0];
4270 p->frame_strut.right = d[1];
4271 p->frame_strut.top = d[2];
4272 p->frame_strut.bottom = d[3];
4273 }
4274 if ( data_ret )
4275 XFree(data_ret);
4276 }
4277 if (!ok && XGetWindowProperty(p->display, p->window, kde_net_wm_frame_strut,
4278 0l, 4l, False, XA_CARDINAL, &type_ret, &format_ret,
4279 &nitems_ret, &unused, &data_ret) == Success) {
4280 if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 4) {
4281 ok = true;
4282 long *d = (long *) data_ret;
4283
4284 p->frame_strut.left = d[0];
4285 p->frame_strut.right = d[1];
4286 p->frame_strut.top = d[2];
4287 p->frame_strut.bottom = d[3];
4288 }
4289 if ( data_ret )
4290 XFree(data_ret);
4291 }
4292 }
4293
4294 if (dirty & WMPid) {
4295 p->pid = 0;
4296 if (XGetWindowProperty(p->display, p->window, net_wm_pid, 0l, 1l,
4297 False, XA_CARDINAL, &type_ret, &format_ret,
4298 &nitems_ret, &unused, &data_ret) == Success) {
4299 if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 1) {
4300 p->pid = *((long *) data_ret);
4301 }
4302 if ( data_ret )
4303 XFree(data_ret);
4304 }
4305 }
4306
4307 if (dirty2 & WM2StartupId)
4308 {
4309 delete[] p->startup_id;
4310 p->startup_id = NULL;
4311 if (XGetWindowProperty(p->display, p->window, net_startup_id, 0l,
4312 MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
4313 &format_ret, &nitems_ret, &unused, &data_ret)
4314 == Success) {
4315 if (type_ret == UTF8_STRING && format_ret == 8 && nitems_ret > 0) {
4316 p->startup_id = nstrndup((const char *) data_ret, nitems_ret);
4317 }
4318
4319 if( data_ret )
4320 XFree(data_ret);
4321 }
4322 }
4323
4324 if( dirty2 & WM2AllowedActions ) {
4325 p->allowed_actions = 0;
4326 if (XGetWindowProperty(p->display, p->window, net_wm_allowed_actions, 0l, 2048l,
4327 False, XA_ATOM, &type_ret, &format_ret,
4328 &nitems_ret, &unused, &data_ret)
4329 == Success) {
4330 if (type_ret == XA_ATOM && format_ret == 32 && nitems_ret > 0) {
4331 // determine actions
4332#ifdef NETWMDEBUG
4333 fprintf(stderr, "NETWinInfo::update: updating allowed actions (%ld)\n",
4334 nitems_ret);
4335#endif
4336
4337 long *actions = (long *) data_ret;
4338 unsigned long count;
4339
4340 for (count = 0; count < nitems_ret; count++) {
4341#ifdef NETWMDEBUG
4342 char* debug_action = XGetAtomName(p->display, (Atom) actions[count]);
4343 fprintf(stderr,
4344 "NETWinInfo::update: adding allowed action %ld '%s'\n",
4345 actions[count], debug_action);
4346 if( debug_action ) {
4347 XFree( debug_action );
4348 }
4349#endif
4350
4351 if ((Atom) actions[count] == net_wm_action_move)
4352 p->allowed_actions |= ActionMove;
4353 if ((Atom) actions[count] == net_wm_action_resize)
4354 p->allowed_actions |= ActionResize;
4355 if ((Atom) actions[count] == net_wm_action_minimize)
4356 p->allowed_actions |= ActionMinimize;
4357 if ((Atom) actions[count] == net_wm_action_shade)
4358 p->allowed_actions |= ActionShade;
4359 if ((Atom) actions[count] == net_wm_action_stick)
4360 p->allowed_actions |= ActionStick;
4361 if ((Atom) actions[count] == net_wm_action_max_vert)
4362 p->allowed_actions |= ActionMaxVert;
4363 if ((Atom) actions[count] == net_wm_action_max_horiz)
4364 p->allowed_actions |= ActionMaxHoriz;
4365 if ((Atom) actions[count] == net_wm_action_fullscreen)
4366 p->allowed_actions |= ActionFullScreen;
4367 if ((Atom) actions[count] == net_wm_action_change_desk)
4368 p->allowed_actions |= ActionChangeDesktop;
4369 if ((Atom) actions[count] == net_wm_action_close)
4370 p->allowed_actions |= ActionClose;
4371 }
4372 }
4373 if ( data_ret )
4374 XFree(data_ret);
4375 }
4376 }
4377
4378 if (dirty2 & WM2UserTime) {
4379 p->user_time = -1U;
4380 if (XGetWindowProperty(p->display, p->window, net_wm_user_time, 0l, 1l,
4381 False, XA_CARDINAL, &type_ret, &format_ret,
4382 &nitems_ret, &unused, &data_ret) == Success) {
4383 // don't do nitems_ret check - Qt does PropModeAppend to avoid API call for it
4384 if (type_ret == XA_CARDINAL && format_ret == 32 /*&& nitems_ret == 1*/) {
4385 p->user_time = *((long *) data_ret);
4386 }
4387 if ( data_ret )
4388 XFree(data_ret);
4389 }
4390 }
4391
4392 if (dirty2 & WM2TransientFor) {
4393 p->transient_for = None;
4394 XGetTransientForHint(p->display, p->window, &p->transient_for);
4395 }
4396
4397 if (dirty2 & WM2GroupLeader) {
4398 XWMHints *hints = XGetWMHints(p->display, p->window);
4399 p->window_group = None;
4400 if ( hints )
4401 {
4402 if( hints->flags & WindowGroupHint )
4403 p->window_group = hints->window_group;
4404 XFree( reinterpret_cast< char* >( hints ));
4405 }
4406 }
4407
4408 if( dirty2 & WM2WindowClass ) {
4409 delete[] p->class_class;
4410 delete[] p->class_name;
4411 p->class_class = NULL;
4412 p->class_name = NULL;
4413 XClassHint hint;
4414 if( XGetClassHint( p->display, p->window, &hint )) {
4415 p->class_class = strdup( hint.res_class );
4416 p->class_name = strdup( hint.res_name );
4417 XFree( hint.res_class );
4418 XFree( hint.res_name );
4419 }
4420 }
4421
4422 if( dirty2 & WM2WindowRole ) {
4423 delete[] p->role;
4424 p->role = NULL;
4425 if (XGetWindowProperty(p->display, p->window, wm_window_role, 0l,
4426 MAX_PROP_SIZE, False, XA_STRING, &type_ret,
4427 &format_ret, &nitems_ret, &unused, &data_ret)
4428 == Success) {
4429 if (type_ret == XA_STRING && format_ret == 8 && nitems_ret > 0) {
4430 p->role = nstrndup((const char *) data_ret, nitems_ret);
4431 }
4432 if( data_ret )
4433 XFree(data_ret);
4434 }
4435 }
4436
4437 if( dirty2 & WM2ClientMachine ) {
4438 delete[] p->client_machine;
4439 p->client_machine = NULL;
4440 if (XGetWindowProperty(p->display, p->window, XA_WM_CLIENT_MACHINE, 0l,
4441 MAX_PROP_SIZE, False, XA_STRING, &type_ret,
4442 &format_ret, &nitems_ret, &unused, &data_ret)
4443 == Success) {
4444 if (type_ret == XA_STRING && format_ret == 8 && nitems_ret > 0) {
4445 p->client_machine = nstrndup((const char *) data_ret, nitems_ret);
4446 }
4447 if( data_ret )
4448 XFree(data_ret);
4449 }
4450 }
4451}
4452
4453
4454NETRect NETWinInfo::iconGeometry() const {
4455 return p->icon_geom;
4456}
4457
4458
4459unsigned long NETWinInfo::state() const {
4460 return p->state;
4461}
4462
4463
4464NETStrut NETWinInfo::strut() const {
4465 return p->strut;
4466}
4467
4468NETExtendedStrut NETWinInfo::extendedStrut() const {
4469 return p->extended_strut;
4470}
4471
4472bool NET::typeMatchesMask( WindowType type, unsigned long mask ) {
4473 switch( type ) {
4474#define CHECK_TYPE_MASK( type ) \
4475 case type: \
4476 if( mask & type##Mask ) \
4477 return true; \
4478 break;
4479 CHECK_TYPE_MASK( Normal )
4480 CHECK_TYPE_MASK( Desktop )
4481 CHECK_TYPE_MASK( Dock )
4482 CHECK_TYPE_MASK( Toolbar )
4483 CHECK_TYPE_MASK( Menu )
4484 CHECK_TYPE_MASK( Dialog )
4485 CHECK_TYPE_MASK( Override )
4486 CHECK_TYPE_MASK( TopMenu )
4487 CHECK_TYPE_MASK( Utility )
4488 CHECK_TYPE_MASK( Splash )
4489 CHECK_TYPE_MASK( DropdownMenu )
4490 CHECK_TYPE_MASK( PopupMenu )
4491 CHECK_TYPE_MASK( Tooltip )
4492 CHECK_TYPE_MASK( Notification )
4493 CHECK_TYPE_MASK( ComboBox )
4494 CHECK_TYPE_MASK( DNDIcon )
4495#undef CHECK_TYPE_MASK
4496 default:
4497 break;
4498 }
4499 return false;
4500}
4501
4502NET::WindowType NETWinInfo::windowType( unsigned long supported_types ) const {
4503 for( int i = 0;
4504 i < p->types.size();
4505 ++i ) {
4506 // return the type only if the application supports it
4507 if( typeMatchesMask( p->types[ i ], supported_types ))
4508 return p->types[ i ];
4509 }
4510 return Unknown;
4511}
4512
4513NET::WindowType NETWinInfo::windowType() const {
4514 return p->types[ 0 ];
4515}
4516
4517
4518const char *NETWinInfo::name() const {
4519 return p->name;
4520}
4521
4522
4523const char *NETWinInfo::visibleName() const {
4524 return p->visible_name;
4525}
4526
4527
4528const char *NETWinInfo::iconName() const {
4529 return p->icon_name;
4530}
4531
4532
4533const char *NETWinInfo::visibleIconName() const {
4534 return p->visible_icon_name;
4535}
4536
4537
4538int NETWinInfo::desktop() const {
4539 return p->desktop;
4540}
4541
4542int NETWinInfo::pid() const {
4543 return p->pid;
4544}
4545
4546Time NETWinInfo::userTime() const {
4547 return p->user_time;
4548}
4549
4550const char* NETWinInfo::startupId() const {
4551 return p->startup_id;
4552}
4553
4554unsigned long NETWinInfo::allowedActions() const {
4555 return p->allowed_actions;
4556}
4557
4558bool NETWinInfo::hasNETSupport() const {
4559 return p->has_net_support;
4560}
4561
4562Window NETWinInfo::transientFor() const {
4563 return p->transient_for;
4564}
4565
4566Window NETWinInfo::groupLeader() const {
4567 return p->window_group;
4568}
4569
4570const char* NETWinInfo::windowClassClass() const {
4571 return p->class_class;
4572}
4573
4574const char* NETWinInfo::windowClassName() const {
4575 return p->class_name;
4576}
4577
4578const char* NETWinInfo::windowRole() const {
4579 return p->role;
4580}
4581
4582const char* NETWinInfo::clientMachine() const {
4583 return p->client_machine;
4584}
4585
4586Bool NETWinInfo::handledIcons() const {
4587 return p->handled_icons;
4588}
4589
4590
4591Window NETWinInfo::kdeSystemTrayWinFor() const {
4592 return p->kde_system_tray_win_for;
4593}
4594
4595const unsigned long* NETWinInfo::passedProperties() const {
4596 return p->properties;
4597}
4598
4599unsigned long NETWinInfo::properties() const {
4600 return p->properties[ PROTOCOLS ];
4601}
4602
4603
4604NET::MappingState NETWinInfo::mappingState() const {
4605 return p->mapping_state;
4606}
4607
4608void NETRootInfo::virtual_hook( int, void* )
4609{ /*BASE::virtual_hook( id, data );*/ }
4610
4611void NETWinInfo::virtual_hook( int, void* )
4612{ /*BASE::virtual_hook( id, data );*/ }
4613
4614// Functions for X timestamp comparing. For Time being 32bit they're fairly simple
4615// (the #if 0 part), but on 64bit architectures Time is 64bit unsigned long,
4616// so there special care needs to be taken to always use only the lower 32bits.
4617#if 0
4618int NET::timestampCompare( Time time1, Time time2 ) // like strcmp()
4619 {
4620 if( time1 == time2 )
4621 return 0;
4622 return ( time1 - time2 ) < 0x7fffffffU ? 1 : -1; // time1 > time2 -> 1, handle wrapping
4623 }
4624
4625Time NET::timestampDiff( Time time1, Time time2 ) // returns time2 - time1
4626 { // no need to handle wrapping?
4627 return time2 - time1;
4628 }
4629#else
4630int NET::timestampCompare( unsigned long time1_, unsigned long time2_ ) // like strcmp()
4631 {
4632 TQ_UINT32 time1 = time1_;
4633 TQ_UINT32 time2 = time2_;
4634 if( time1 == time2 )
4635 return 0;
4636 return TQ_UINT32( time1 - time2 ) < 0x7fffffffU ? 1 : -1; // time1 > time2 -> 1, handle wrapping
4637 }
4638
4639int NET::timestampDiff( unsigned long time1_, unsigned long time2_ ) // returns time2 - time1
4640 { // no need to handle wrapping?
4641 TQ_UINT32 time1 = time1_;
4642 TQ_UINT32 time2 = time2_;
4643 return TQ_UINT32( time2 - time1 );
4644 }
4645#endif
4646
4647
4648#endif
NET::State
State
Window state.
Definition: netwm_def.h:389
NET::timestampDiff
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,...
NET::DesktopLayoutCorner
DesktopLayoutCorner
Starting corner for desktop layout.
Definition: netwm_def.h:648
NET::typeMatchesMask
static bool typeMatchesMask(WindowType type, unsigned long mask)
Returns true if the given window type matches the mask given using WindowTypeMask flags.
NET::WindowType
WindowType
Window type.
Definition: netwm_def.h:294
NET::Splash
@ Splash
Definition: netwm_def.h:306
NET::Notification
@ Notification
Definition: netwm_def.h:310
NET::Override
@ Override
Definition: netwm_def.h:302
NET::DNDIcon
@ DNDIcon
Definition: netwm_def.h:312
NET::Tooltip
@ Tooltip
Definition: netwm_def.h:309
NET::DropdownMenu
@ DropdownMenu
Definition: netwm_def.h:307
NET::PopupMenu
@ PopupMenu
Definition: netwm_def.h:308
NET::ComboBox
@ ComboBox
Definition: netwm_def.h:311
NET::Utility
@ Utility
Definition: netwm_def.h:305
NET::Property2
Property2
Supported properties.
Definition: netwm_def.h:598
NET::Property
Property
Supported properties.
Definition: netwm_def.h:534
NET::RequestSource
RequestSource
Source of the request.
Definition: netwm_def.h:631
NET::timestampCompare
static int timestampCompare(unsigned long time1, unsigned long time2)
Compares two X timestamps, taking into account wrapping and 64bit architectures.
NET::Action
Action
Actions that can be done with a window (_NET_WM_ALLOWED_ACTIONS).
Definition: netwm_def.h:474
NET::Orientation
Orientation
Orientation.
Definition: netwm_def.h:640
NET::MappingState
MappingState
Client window mapping state.
Definition: netwm_def.h:464
KNotifyClient::event
int event(const TQString &message, const TQString &text=TQString::null) TDE_DEPRECATED
Definition: knotifyclient.cpp:125
KStdAction::action
TDEAction * action(StdAction act_enum, const TQObject *recvr, const char *slot, TDEActionCollection *parent, const char *name=0L)
KStdAction::FullScreen
FullScreen
NETExtendedStrut
Partial strut class for NET classes.
Definition: netwm_def.h:153
NETExtendedStrut::bottom_width
int bottom_width
Bottom border of the strut, width and range.
Definition: netwm_def.h:179
NETExtendedStrut::left_width
int left_width
Left border of the strut, width and range.
Definition: netwm_def.h:164
NETExtendedStrut::right_width
int right_width
Right border of the strut, width and range.
Definition: netwm_def.h:169
NETExtendedStrut::top_width
int top_width
Top border of the strut, width and range.
Definition: netwm_def.h:174
NETIcon
Simple icon class for NET classes.
Definition: netwm_def.h:122
NETIcon::size
NETSize size
Size of the icon.
Definition: netwm_def.h:133
NETIcon::data
unsigned char * data
Image data for the icon.
Definition: netwm_def.h:140
NETPoint
Simple point class for NET classes.
Definition: netwm_def.h:44
NETPoint::x
int x
x coordinate.
Definition: netwm_def.h:53
NETPoint::y
int y
y coordinate
Definition: netwm_def.h:54
NETRect
Simple rectangle class for NET classes.
Definition: netwm_def.h:94
NETRect::pos
NETPoint pos
Position of the rectangle.
Definition: netwm_def.h:100
NETRect::size
NETSize size
Size of the rectangle.
Definition: netwm_def.h:107
NETSize
Simple size class for NET classes.
Definition: netwm_def.h:71
NETSize::height
int height
Height.
Definition: netwm_def.h:81
NETSize::width
int width
Width.
Definition: netwm_def.h:80
NETStrut
Definition: netwm_def.h:195
NETStrut::bottom
int bottom
Bottom border of the strut.
Definition: netwm_def.h:219
NETStrut::left
int left
Left border of the strut.
Definition: netwm_def.h:204
NETStrut::right
int right
Right border of the strut.
Definition: netwm_def.h:209
NETStrut::top
int top
Top border of the strut.
Definition: netwm_def.h:214

tdecore

Skip menu "tdecore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

tdecore

Skip menu "tdecore"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdecore by doxygen 1.9.4
This website is maintained by Timothy Pearson.