3
Copyright (c) 2000 Troll Tech AS
4
Copyright (c) 2003 Lubos Lunak <l.lunak@kde.org>
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:
13
The above copyright notice and this permission notice shall be included in
14
all copies or substantial portions of the Software.
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.
29
#ifdef Q_WS_X11 //FIXME
31
#include <QtGui/qx11info_x11.h>
45
static Atom UTF8_STRING = 0;
47
// root window properties
48
static Atom net_supported = 0;
49
static Atom net_client_list = 0;
50
static Atom net_client_list_stacking = 0;
51
static Atom net_desktop_geometry = 0;
52
static Atom net_desktop_viewport = 0;
53
static Atom net_current_desktop = 0;
54
static Atom net_desktop_names = 0;
55
static Atom net_number_of_desktops = 0;
56
static Atom net_active_window = 0;
57
static Atom net_workarea = 0;
58
static Atom net_supporting_wm_check = 0;
59
static Atom net_virtual_roots = 0;
60
static Atom net_showing_desktop = 0;
61
static Atom net_desktop_layout = 0;
63
// root window messages
64
static Atom net_close_window = 0;
65
static Atom net_restack_window = 0;
66
static Atom net_wm_moveresize = 0;
67
static Atom net_moveresize_window = 0;
69
// application window properties
70
static Atom net_wm_name = 0;
71
static Atom net_wm_visible_name = 0;
72
static Atom net_wm_icon_name = 0;
73
static Atom net_wm_visible_icon_name = 0;
74
static Atom net_wm_desktop = 0;
75
static Atom net_wm_window_type = 0;
76
static Atom net_wm_state = 0;
77
static Atom net_wm_strut = 0;
78
static Atom net_wm_extended_strut = 0; // the atom is called _NET_WM_STRUT_PARTIAL
79
static Atom net_wm_icon_geometry = 0;
80
static Atom net_wm_icon = 0;
81
static Atom net_wm_pid = 0;
82
static Atom net_wm_user_time = 0;
83
static Atom net_wm_handled_icons = 0;
84
static Atom net_startup_id = 0;
85
static Atom net_wm_allowed_actions = 0;
86
static Atom wm_window_role = 0;
87
static Atom net_frame_extents = 0;
88
static Atom net_wm_window_opacity = 0;
91
static Atom kde_net_system_tray_windows = 0;
92
static Atom kde_net_wm_system_tray_window_for = 0;
93
static Atom kde_net_wm_frame_strut = 0;
94
static Atom kde_net_wm_window_type_override = 0;
95
static Atom kde_net_wm_window_type_topmenu = 0;
96
static Atom kde_net_wm_temporary_rules = 0;
98
// application protocols
99
static Atom wm_protocols = 0;
100
static Atom net_wm_ping = 0;
101
static Atom net_wm_take_activity = 0;
103
// application window types
104
static Atom net_wm_window_type_normal = 0;
105
static Atom net_wm_window_type_desktop = 0;
106
static Atom net_wm_window_type_dock = 0;
107
static Atom net_wm_window_type_toolbar = 0;
108
static Atom net_wm_window_type_menu = 0;
109
static Atom net_wm_window_type_dialog = 0;
110
static Atom net_wm_window_type_utility = 0;
111
static Atom net_wm_window_type_splash = 0;
112
static Atom net_wm_window_type_dropdown_menu = 0;
113
static Atom net_wm_window_type_popup_menu = 0;
114
static Atom net_wm_window_type_tooltip = 0;
115
static Atom net_wm_window_type_notification = 0;
116
static Atom net_wm_window_type_combobox = 0;
117
static Atom net_wm_window_type_dnd = 0;
119
// application window state
120
static Atom net_wm_state_modal = 0;
121
static Atom net_wm_state_sticky = 0;
122
static Atom net_wm_state_max_vert = 0;
123
static Atom net_wm_state_max_horiz = 0;
124
static Atom net_wm_state_shaded = 0;
125
static Atom net_wm_state_skip_taskbar = 0;
126
static Atom net_wm_state_skip_pager = 0;
127
static Atom net_wm_state_hidden = 0;
128
static Atom net_wm_state_fullscreen = 0;
129
static Atom net_wm_state_above = 0;
130
static Atom net_wm_state_below = 0;
131
static Atom net_wm_state_demands_attention = 0;
134
static Atom net_wm_action_move = 0;
135
static Atom net_wm_action_resize = 0;
136
static Atom net_wm_action_minimize = 0;
137
static Atom net_wm_action_shade = 0;
138
static Atom net_wm_action_stick = 0;
139
static Atom net_wm_action_max_vert = 0;
140
static Atom net_wm_action_max_horiz = 0;
141
static Atom net_wm_action_fullscreen = 0;
142
static Atom net_wm_action_change_desk = 0;
143
static Atom net_wm_action_close = 0;
145
// KDE extension that's not in the specs - Replaced by state_above now?
146
static Atom net_wm_state_stays_on_top = 0;
148
// used to determine whether application window is managed or not
149
static Atom xa_wm_state = 0;
151
static Bool netwm_atoms_created = False;
152
const unsigned long netwm_sendevent_mask = (SubstructureRedirectMask|
153
SubstructureNotifyMask);
156
const long MAX_PROP_SIZE = 100000;
158
static char *nstrdup(const char *s1) {
159
if (! s1) return (char *) 0;
161
int l = strlen(s1) + 1;
162
char *s2 = new char[l];
168
static char *nstrndup(const char *s1, int l) {
169
if (! s1 || l == 0) return (char *) 0;
171
char *s2 = new char[l+1];
178
static Window *nwindup(Window *w1, int n) {
179
if (! w1 || n == 0) return (Window *) 0;
181
Window *w2 = new Window[n];
182
while (n--) w2[n] = w1[n];
187
static void refdec_nri(NETRootInfoPrivate *p) {
190
fprintf(stderr, "NET: decrementing NETRootInfoPrivate::ref (%d)\n", p->ref - 1);
196
fprintf(stderr, "NET: \tno more references, deleting\n");
200
delete [] p->stacking;
201
delete [] p->clients;
202
delete [] p->virtual_roots;
203
delete [] p->kde_system_tray_windows;
206
for (i = 0; i < p->desktop_names.size(); i++)
207
delete [] p->desktop_names[i];
212
static void refdec_nwi(NETWinInfoPrivate *p) {
215
fprintf(stderr, "NET: decrementing NETWinInfoPrivate::ref (%d)\n", p->ref - 1);
221
fprintf(stderr, "NET: \tno more references, deleting\n");
225
delete [] p->visible_name;
226
delete [] p->icon_name;
227
delete [] p->visible_icon_name;
228
delete [] p->startup_id;
231
for (i = 0; i < p->icons.size(); i++)
232
delete [] p->icons[i].data;
237
static int wcmp(const void *a, const void *b) {
238
return *((Window *) a) - *((Window *) b);
242
static const int netAtomCount = 85;
243
static void create_atoms(Display *d) {
244
static const char * const names[netAtomCount] =
248
"_NET_SUPPORTING_WM_CHECK",
250
"_NET_CLIENT_LIST_STACKING",
251
"_NET_NUMBER_OF_DESKTOPS",
252
"_NET_DESKTOP_GEOMETRY",
253
"_NET_DESKTOP_VIEWPORT",
254
"_NET_CURRENT_DESKTOP",
255
"_NET_DESKTOP_NAMES",
256
"_NET_ACTIVE_WINDOW",
258
"_NET_VIRTUAL_ROOTS",
259
"_NET_DESKTOP_LAYOUT",
260
"_NET_SHOWING_DESKTOP",
262
"_NET_RESTACK_WINDOW",
264
"_NET_WM_MOVERESIZE",
265
"_NET_MOVERESIZE_WINDOW",
267
"_NET_WM_VISIBLE_NAME",
269
"_NET_WM_VISIBLE_ICON_NAME",
271
"_NET_WM_WINDOW_TYPE",
274
"_NET_WM_STRUT_PARTIAL",
275
"_NET_WM_ICON_GEOMETRY",
279
"_NET_WM_HANDLED_ICONS",
281
"_NET_WM_ALLOWED_ACTIONS",
283
"_NET_WM_TAKE_ACTIVITY",
285
"_NET_FRAME_EXTENTS",
286
"_NET_WM_WINDOW_OPACITY",
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",
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",
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",
327
"_NET_WM_STATE_STAYS_ON_TOP",
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",
340
Atom atoms[netAtomCount], *atomsp[netAtomCount] =
344
&net_supporting_wm_check,
346
&net_client_list_stacking,
347
&net_number_of_desktops,
348
&net_desktop_geometry,
349
&net_desktop_viewport,
350
&net_current_desktop,
356
&net_showing_desktop,
361
&net_moveresize_window,
363
&net_wm_visible_name,
365
&net_wm_visible_icon_name,
370
&net_wm_extended_strut,
371
&net_wm_icon_geometry,
375
&net_wm_handled_icons,
377
&net_wm_allowed_actions,
379
&net_wm_take_activity,
382
&net_wm_window_opacity,
384
&net_wm_window_type_normal,
385
&net_wm_window_type_desktop,
386
&net_wm_window_type_dock,
387
&net_wm_window_type_toolbar,
388
&net_wm_window_type_menu,
389
&net_wm_window_type_dialog,
390
&net_wm_window_type_utility,
391
&net_wm_window_type_splash,
392
&net_wm_window_type_dropdown_menu,
393
&net_wm_window_type_popup_menu,
394
&net_wm_window_type_tooltip,
395
&net_wm_window_type_notification,
396
&net_wm_window_type_combobox,
397
&net_wm_window_type_dnd,
400
&net_wm_state_sticky,
401
&net_wm_state_max_vert,
402
&net_wm_state_max_horiz,
403
&net_wm_state_shaded,
404
&net_wm_state_skip_taskbar,
405
&net_wm_state_skip_pager,
406
&net_wm_state_hidden,
407
&net_wm_state_fullscreen,
410
&net_wm_state_demands_attention,
413
&net_wm_action_resize,
414
&net_wm_action_minimize,
415
&net_wm_action_shade,
416
&net_wm_action_stick,
417
&net_wm_action_max_vert,
418
&net_wm_action_max_horiz,
419
&net_wm_action_fullscreen,
420
&net_wm_action_change_desk,
421
&net_wm_action_close,
423
&net_wm_state_stays_on_top,
425
&kde_net_system_tray_windows,
426
&kde_net_wm_system_tray_window_for,
427
&kde_net_wm_frame_strut,
428
&kde_net_wm_window_type_override,
429
&kde_net_wm_window_type_topmenu,
430
&kde_net_wm_temporary_rules,
436
assert( !netwm_atoms_created );
438
int i = netAtomCount;
442
XInternAtoms(d, (char **) names, netAtomCount, False, atoms);
446
*atomsp[i] = atoms[i];
448
netwm_atoms_created = True;
452
static void readIcon(Display* display, Window window, Atom property, NETRArray<NETIcon>& icons, int& icon_count) {
455
fprintf(stderr, "NET: readIcon\n");
460
unsigned long nitems_ret = 0, after_ret = 0;
461
unsigned char *data_ret = 0;
464
for (int i = 0; i < icons.size(); i++)
465
delete [] icons[i].data;
470
unsigned char *buffer = 0;
471
unsigned long offset = 0;
472
unsigned long buffer_offset = 0;
473
unsigned long bufsize = 0;
477
if (XGetWindowProperty(display, window, property, offset,
478
MAX_PROP_SIZE, False, XA_CARDINAL, &type_ret,
479
&format_ret, &nitems_ret, &after_ret, &data_ret)
483
if (nitems_ret < 3 || type_ret != XA_CARDINAL ||
485
// either we didn't get the property, or the property has less than
487
// NOTE: 3 is the ABSOLUTE minimum:
488
// width = 1, height = 1, length(data) = 1 (width * height)
494
bufsize = nitems_ret * sizeof(long) + after_ret;
495
buffer = (unsigned char *) malloc(bufsize);
497
else if (buffer_offset + nitems_ret*sizeof(long) > bufsize)
499
fprintf(stderr, "NETWM: Warning readIcon() needs buffer adjustment!\n");
500
bufsize = buffer_offset + nitems_ret * sizeof(long) + after_ret;
501
buffer = (unsigned char *) realloc(buffer, bufsize);
503
memcpy((buffer + buffer_offset), data_ret, nitems_ret * sizeof(long));
504
buffer_offset += nitems_ret * sizeof(long);
505
offset += nitems_ret;
512
return; // Some error occurred cq. property didn't exist.
515
while (after_ret > 0);
518
unsigned long i, j, k, sz, s;
519
unsigned long *d = (unsigned long *) buffer;
520
for (i = 0, j = 0; i < bufsize; i++) {
521
icons[j].size.width = *d++;
523
icons[j].size.height = *d++;
526
sz = icons[j].size.width * icons[j].size.height;
527
s = sz * sizeof(long);
529
if ( i + s - 1 > bufsize || sz == 0 || sz > 1024 * 1024 ) {
533
delete [] icons[j].data;
534
data32 = new CARD32[sz];
535
icons[j].data = (unsigned char *) data32;
536
for (k = 0; k < sz; k++, i += sizeof(long)) {
537
*data32++ = (CARD32) *d++;
544
fprintf(stderr, "NET: readIcon got %d icons\n", icon_count);
552
NETRArray<Z>::NETRArray()
555
d = (Z*) calloc(capacity, sizeof(Z)); // allocate 2 elts and set to zero
560
NETRArray<Z>::~NETRArray() {
566
void NETRArray<Z>::reset() {
569
d = (Z*) realloc(d, sizeof(Z)*capacity);
570
memset( (void*) d, 0, sizeof(Z)*capacity );
574
Z &NETRArray<Z>::operator[](int index) {
575
if (index >= capacity) {
576
// allocate space for the new data
577
// open table has amortized O(1) access time
578
// when N elements appended consecutively -- exa
579
int newcapacity = 2*capacity > index+1 ? 2*capacity : index+1; // max
580
// copy into new larger memory block using realloc
581
d = (Z*) realloc(d, sizeof(Z)*newcapacity);
582
memset( (void*) &d[capacity], 0, sizeof(Z)*(newcapacity-capacity) );
583
capacity = newcapacity;
585
if (index >= sz) // at this point capacity>index
592
// Construct a new NETRootInfo object.
594
NETRootInfo::NETRootInfo(Display *display, Window supportWindow, const char *wmName,
595
const unsigned long properties[], int properties_size,
596
int screen, bool doActivate)
600
fprintf(stderr, "NETRootInfo::NETRootInfo: using window manager constructor\n");
603
p = new NETRootInfoPrivate;
606
p->display = display;
607
p->name = nstrdup(wmName);
612
p->screen = DefaultScreen(p->display);
615
p->root = RootWindow(p->display, p->screen);
616
p->supportwindow = supportWindow;
617
p->number_of_desktops = p->current_desktop = 0;
619
p->clients = p->stacking = p->virtual_roots = (Window *) 0;
620
p->clients_count = p->stacking_count = p->virtual_roots_count = 0;
621
p->kde_system_tray_windows = 0;
622
p->kde_system_tray_windows_count = 0;
623
p->showing_desktop = false;
624
p->desktop_layout_orientation = OrientationHorizontal;
625
p->desktop_layout_corner = DesktopLayoutCornerTopLeft;
626
p->desktop_layout_columns = p->desktop_layout_rows = 0;
627
setDefaultProperties();
628
if( properties_size > PROPERTIES_SIZE ) {
629
fprintf( stderr, "NETRootInfo::NETRootInfo(): properties array too large\n");
630
properties_size = PROPERTIES_SIZE;
632
for( int i = 0; i < properties_size; ++i )
633
p->properties[ i ] = properties[ i ];
634
// force support for Supported and SupportingWMCheck for window managers
635
p->properties[ PROTOCOLS ] |= ( Supported | SupportingWMCheck );
636
p->client_properties[ PROTOCOLS ] = DesktopNames // the only thing that can be changed by clients
637
| WMPing; // or they can reply to this
638
p->client_properties[ PROTOCOLS2 ] = WM2TakeActivity;
640
role = WindowManager;
642
if (! netwm_atoms_created) create_atoms(p->display);
644
if (doActivate) activate();
648
NETRootInfo::NETRootInfo(Display *display, const unsigned long properties[], int properties_size,
649
int screen, bool doActivate)
653
fprintf(stderr, "NETRootInfo::NETRootInfo: using Client constructor\n");
656
p = new NETRootInfoPrivate;
661
p->display = display;
666
p->screen = DefaultScreen(p->display);
669
p->root = RootWindow(p->display, p->screen);
670
p->rootSize.width = WidthOfScreen(ScreenOfDisplay(p->display, p->screen));
671
p->rootSize.height = HeightOfScreen(ScreenOfDisplay(p->display, p->screen));
673
p->supportwindow = None;
674
p->number_of_desktops = p->current_desktop = 0;
676
p->clients = p->stacking = p->virtual_roots = (Window *) 0;
677
p->clients_count = p->stacking_count = p->virtual_roots_count = 0;
678
p->kde_system_tray_windows = 0;
679
p->kde_system_tray_windows_count = 0;
680
p->showing_desktop = false;
681
p->desktop_layout_orientation = OrientationHorizontal;
682
p->desktop_layout_corner = DesktopLayoutCornerTopLeft;
683
p->desktop_layout_columns = p->desktop_layout_rows = 0;
684
setDefaultProperties();
685
if( properties_size > 2 ) {
686
fprintf( stderr, "NETWinInfo::NETWinInfo(): properties array too large\n");
689
for( int i = 0; i < properties_size; ++i )
690
// remap from [0]=NET::Property,[1]=NET::Property2
693
p->client_properties[ PROTOCOLS ] = properties[ i ];
696
p->client_properties[ PROTOCOLS2 ] = properties[ i ];
699
for( int i = 0; i < PROPERTIES_SIZE; ++i )
700
p->properties[ i ] = 0;
704
if (! netwm_atoms_created) create_atoms(p->display);
706
if (doActivate) activate();
709
NETRootInfo::NETRootInfo(Display *display, unsigned long properties, int screen,
714
fprintf(stderr, "NETRootInfo::NETRootInfo: using Client constructor\n");
717
p = new NETRootInfoPrivate;
722
p->display = display;
727
p->screen = DefaultScreen(p->display);
730
p->root = RootWindow(p->display, p->screen);
731
p->rootSize.width = WidthOfScreen(ScreenOfDisplay(p->display, p->screen));
732
p->rootSize.height = HeightOfScreen(ScreenOfDisplay(p->display, p->screen));
734
p->supportwindow = None;
735
p->number_of_desktops = p->current_desktop = 0;
737
p->clients = p->stacking = p->virtual_roots = (Window *) 0;
738
p->clients_count = p->stacking_count = p->virtual_roots_count = 0;
739
p->kde_system_tray_windows = 0;
740
p->kde_system_tray_windows_count = 0;
741
p->showing_desktop = false;
742
p->desktop_layout_orientation = OrientationHorizontal;
743
p->desktop_layout_corner = DesktopLayoutCornerTopLeft;
744
p->desktop_layout_columns = p->desktop_layout_rows = 0;
745
setDefaultProperties();
746
p->client_properties[ PROTOCOLS ] = properties;
747
for( int i = 0; i < PROPERTIES_SIZE; ++i )
748
p->properties[ i ] = 0;
752
if (! netwm_atoms_created) create_atoms(p->display);
754
if (doActivate) activate();
758
NETRootInfo2::NETRootInfo2(Display *display, Window supportWindow, const char *wmName,
759
unsigned long properties[], int properties_size,
760
int screen, bool doActivate)
761
: NETRootInfo( display, supportWindow, wmName, properties, properties_size,
766
NETRootInfo2::NETRootInfo2(Display *display, const unsigned long properties[], int properties_size,
767
int screen, bool doActivate)
768
: NETRootInfo( display, properties, properties_size, screen, doActivate )
772
NETRootInfo3::NETRootInfo3(Display *display, Window supportWindow, const char *wmName,
773
unsigned long properties[], int properties_size,
774
int screen, bool doActivate)
775
: NETRootInfo2( display, supportWindow, wmName, properties, properties_size,
780
NETRootInfo3::NETRootInfo3(Display *display, const unsigned long properties[], int properties_size,
781
int screen, bool doActivate)
782
: NETRootInfo2( display, properties, properties_size, screen, doActivate )
786
NETRootInfo4::NETRootInfo4(Display *display, Window supportWindow, const char *wmName,
787
unsigned long properties[], int properties_size,
788
int screen, bool doActivate)
789
: NETRootInfo3( display, supportWindow, wmName, properties, properties_size,
794
NETRootInfo4::NETRootInfo4(Display *display, const unsigned long properties[], int properties_size,
795
int screen, bool doActivate)
796
: NETRootInfo3( display, properties, properties_size, screen, doActivate )
800
// Copy an existing NETRootInfo object.
802
NETRootInfo::NETRootInfo(const NETRootInfo &rootinfo) {
805
fprintf(stderr, "NETRootInfo::NETRootInfo: using copy constructor\n");
809
role = rootinfo.role;
815
// Be gone with our NETRootInfo.
817
NETRootInfo::~NETRootInfo() {
820
if (! p->ref) delete p;
824
void NETRootInfo::setDefaultProperties()
826
p->properties[ PROTOCOLS ] = Supported | SupportingWMCheck;
827
p->properties[ WINDOW_TYPES ] = NormalMask | DesktopMask | DockMask
828
| ToolbarMask | MenuMask | DialogMask;
829
p->properties[ STATES ] = Modal | Sticky | MaxVert | MaxHoriz | Shaded
830
| SkipTaskbar | StaysOnTop;
831
p->properties[ PROTOCOLS2 ] = 0;
832
p->properties[ ACTIONS ] = 0;
833
p->client_properties[ PROTOCOLS ] = 0;
834
p->client_properties[ WINDOW_TYPES ] = 0; // these two actually don't
835
p->client_properties[ STATES ] = 0; // make sense in client_properties
836
p->client_properties[ PROTOCOLS2 ] = 0;
837
p->client_properties[ ACTIONS ] = 0;
840
void NETRootInfo::activate() {
841
if (role == WindowManager) {
845
"NETRootInfo::activate: setting supported properties on root\n");
852
fprintf(stderr, "NETRootInfo::activate: updating client information\n");
855
update(p->client_properties);
860
void NETRootInfo::setClientList(Window *windows, unsigned int count) {
861
if (role != WindowManager) return;
863
p->clients_count = count;
865
delete [] p->clients;
866
p->clients = nwindup(windows, count);
869
fprintf(stderr, "NETRootInfo::setClientList: setting list with %ld windows\n",
873
XChangeProperty(p->display, p->root, net_client_list, XA_WINDOW, 32,
874
PropModeReplace, (unsigned char *)p->clients,
879
void NETRootInfo::setClientListStacking(Window *windows, unsigned int count) {
880
if (role != WindowManager) return;
882
p->stacking_count = count;
883
delete [] p->stacking;
884
p->stacking = nwindup(windows, count);
888
"NETRootInfo::setClientListStacking: setting list with %ld windows\n",
892
XChangeProperty(p->display, p->root, net_client_list_stacking, XA_WINDOW, 32,
893
PropModeReplace, (unsigned char *) p->stacking,
898
void NETRootInfo::setKDESystemTrayWindows(Window *windows, unsigned int count) {
899
if (role != WindowManager) return;
901
p->kde_system_tray_windows_count = count;
902
delete [] p->kde_system_tray_windows;
903
p->kde_system_tray_windows = nwindup(windows, count);
907
"NETRootInfo::setKDESystemTrayWindows: setting list with %ld windows\n",
908
p->kde_system_tray_windows_count);
911
XChangeProperty(p->display, p->root, kde_net_system_tray_windows, XA_WINDOW, 32,
913
(unsigned char *) p->kde_system_tray_windows,
914
p->kde_system_tray_windows_count);
918
void NETRootInfo::setNumberOfDesktops(int numberOfDesktops) {
922
"NETRootInfo::setNumberOfDesktops: setting desktop count to %d (%s)\n",
923
numberOfDesktops, (role == WindowManager) ? "WM" : "Client");
926
if (role == WindowManager) {
927
p->number_of_desktops = numberOfDesktops;
928
long d = numberOfDesktops;
929
XChangeProperty(p->display, p->root, net_number_of_desktops, XA_CARDINAL, 32,
930
PropModeReplace, (unsigned char *) &d, 1);
934
e.xclient.type = ClientMessage;
935
e.xclient.message_type = net_number_of_desktops;
936
e.xclient.display = p->display;
937
e.xclient.window = p->root;
938
e.xclient.format = 32;
939
e.xclient.data.l[0] = numberOfDesktops;
940
e.xclient.data.l[1] = 0l;
941
e.xclient.data.l[2] = 0l;
942
e.xclient.data.l[3] = 0l;
943
e.xclient.data.l[4] = 0l;
945
XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
950
void NETRootInfo::setCurrentDesktop(int desktop) {
954
"NETRootInfo::setCurrentDesktop: setting current desktop = %d (%s)\n",
955
desktop, (role == WindowManager) ? "WM" : "Client");
958
if (role == WindowManager) {
959
p->current_desktop = desktop;
960
long d = p->current_desktop - 1;
961
XChangeProperty(p->display, p->root, net_current_desktop, XA_CARDINAL, 32,
962
PropModeReplace, (unsigned char *) &d, 1);
966
e.xclient.type = ClientMessage;
967
e.xclient.message_type = net_current_desktop;
968
e.xclient.display = p->display;
969
e.xclient.window = p->root;
970
e.xclient.format = 32;
971
e.xclient.data.l[0] = desktop - 1;
972
e.xclient.data.l[1] = 0l;
973
e.xclient.data.l[2] = 0l;
974
e.xclient.data.l[3] = 0l;
975
e.xclient.data.l[4] = 0l;
977
XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
982
void NETRootInfo::setDesktopName(int desktop, const char *desktopName) {
983
// allow setting desktop names even for non-existant desktops, see the spec, sect.3.7.
984
if (desktop < 1) return;
986
delete [] p->desktop_names[desktop - 1];
987
p->desktop_names[desktop - 1] = nstrdup(desktopName);
989
unsigned int i, proplen,
990
num = ((p->number_of_desktops > p->desktop_names.size()) ?
991
p->number_of_desktops : p->desktop_names.size());
992
for (i = 0, proplen = 0; i < num; i++)
993
proplen += (p->desktop_names[i] != 0 ? strlen(p->desktop_names[i])+1 : 1 );
995
char *prop = new char[proplen], *propp = prop;
997
for (i = 0; i < num; i++)
998
if (p->desktop_names[i]) {
999
strcpy(propp, p->desktop_names[i]);
1000
propp += strlen(p->desktop_names[i]) + 1;
1006
"NETRootInfo::setDesktopName(%d, '%s')\n"
1007
"NETRootInfo::setDesktopName: total property length = %d",
1008
desktop, desktopName, proplen);
1011
XChangeProperty(p->display, p->root, net_desktop_names, UTF8_STRING, 8,
1012
PropModeReplace, (unsigned char *) prop, proplen);
1018
void NETRootInfo::setDesktopGeometry(int , const NETSize &geometry) {
1021
fprintf(stderr, "NETRootInfo::setDesktopGeometry( -- , { %d, %d }) (%s)\n",
1022
geometry.width, geometry.height, (role == WindowManager) ? "WM" : "Client");
1025
if (role == WindowManager) {
1026
p->geometry = geometry;
1029
data[0] = p->geometry.width;
1030
data[1] = p->geometry.height;
1032
XChangeProperty(p->display, p->root, net_desktop_geometry, XA_CARDINAL, 32,
1033
PropModeReplace, (unsigned char *) data, 2);
1037
e.xclient.type = ClientMessage;
1038
e.xclient.message_type = net_desktop_geometry;
1039
e.xclient.display = p->display;
1040
e.xclient.window = p->root;
1041
e.xclient.format = 32;
1042
e.xclient.data.l[0] = geometry.width;
1043
e.xclient.data.l[1] = geometry.height;
1044
e.xclient.data.l[2] = 0l;
1045
e.xclient.data.l[3] = 0l;
1046
e.xclient.data.l[4] = 0l;
1048
XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
1053
void NETRootInfo::setDesktopViewport(int desktop, const NETPoint &viewport) {
1056
fprintf(stderr, "NETRootInfo::setDesktopViewport(%d, { %d, %d }) (%s)\n",
1057
desktop, viewport.x, viewport.y, (role == WindowManager) ? "WM" : "Client");
1060
if (desktop < 1) return;
1062
if (role == WindowManager) {
1063
p->viewport[desktop - 1] = viewport;
1066
l = p->number_of_desktops * 2;
1067
long *data = new long[l];
1068
for (d = 0, i = 0; d < p->number_of_desktops; d++) {
1069
data[i++] = p->viewport[d].x;
1070
data[i++] = p->viewport[d].y;
1073
XChangeProperty(p->display, p->root, net_desktop_viewport, XA_CARDINAL, 32,
1074
PropModeReplace, (unsigned char *) data, l);
1080
e.xclient.type = ClientMessage;
1081
e.xclient.message_type = net_desktop_viewport;
1082
e.xclient.display = p->display;
1083
e.xclient.window = p->root;
1084
e.xclient.format = 32;
1085
e.xclient.data.l[0] = viewport.x;
1086
e.xclient.data.l[1] = viewport.y;
1087
e.xclient.data.l[2] = 0l;
1088
e.xclient.data.l[3] = 0l;
1089
e.xclient.data.l[4] = 0l;
1091
XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
1096
void NETRootInfo::setSupported() {
1097
if (role != WindowManager) {
1099
fprintf(stderr, "NETRootInfo::setSupported - role != WindowManager\n");
1105
Atom atoms[netAtomCount];
1108
// Root window properties/messages
1109
atoms[0] = net_supported;
1110
atoms[1] = net_supporting_wm_check;
1112
if (p->properties[ PROTOCOLS ] & ClientList)
1113
atoms[pnum++] = net_client_list;
1115
if (p->properties[ PROTOCOLS ] & ClientListStacking)
1116
atoms[pnum++] = net_client_list_stacking;
1118
if (p->properties[ PROTOCOLS ] & NumberOfDesktops)
1119
atoms[pnum++] = net_number_of_desktops;
1121
if (p->properties[ PROTOCOLS ] & DesktopGeometry)
1122
atoms[pnum++] = net_desktop_geometry;
1124
if (p->properties[ PROTOCOLS ] & DesktopViewport)
1125
atoms[pnum++] = net_desktop_viewport;
1127
if (p->properties[ PROTOCOLS ] & CurrentDesktop)
1128
atoms[pnum++] = net_current_desktop;
1130
if (p->properties[ PROTOCOLS ] & DesktopNames)
1131
atoms[pnum++] = net_desktop_names;
1133
if (p->properties[ PROTOCOLS ] & ActiveWindow)
1134
atoms[pnum++] = net_active_window;
1136
if (p->properties[ PROTOCOLS ] & WorkArea)
1137
atoms[pnum++] = net_workarea;
1139
if (p->properties[ PROTOCOLS ] & VirtualRoots)
1140
atoms[pnum++] = net_virtual_roots;
1142
if (p->properties[ PROTOCOLS2 ] & WM2DesktopLayout)
1143
atoms[pnum++] = net_desktop_layout;
1145
if (p->properties[ PROTOCOLS ] & CloseWindow)
1146
atoms[pnum++] = net_close_window;
1148
if (p->properties[ PROTOCOLS2 ] & WM2RestackWindow)
1149
atoms[pnum++] = net_restack_window;
1151
if (p->properties[ PROTOCOLS2 ] & WM2ShowingDesktop)
1152
atoms[pnum++] = net_showing_desktop;
1154
// Application window properties/messages
1155
if (p->properties[ PROTOCOLS ] & WMMoveResize)
1156
atoms[pnum++] = net_wm_moveresize;
1158
if (p->properties[ PROTOCOLS2 ] & WM2MoveResizeWindow)
1159
atoms[pnum++] = net_moveresize_window;
1161
if (p->properties[ PROTOCOLS ] & WMName)
1162
atoms[pnum++] = net_wm_name;
1164
if (p->properties[ PROTOCOLS ] & WMVisibleName)
1165
atoms[pnum++] = net_wm_visible_name;
1167
if (p->properties[ PROTOCOLS ] & WMIconName)
1168
atoms[pnum++] = net_wm_icon_name;
1170
if (p->properties[ PROTOCOLS ] & WMVisibleIconName)
1171
atoms[pnum++] = net_wm_visible_icon_name;
1173
if (p->properties[ PROTOCOLS ] & WMDesktop)
1174
atoms[pnum++] = net_wm_desktop;
1176
if (p->properties[ PROTOCOLS ] & WMWindowType) {
1177
atoms[pnum++] = net_wm_window_type;
1179
// Application window types
1180
if (p->properties[ WINDOW_TYPES ] & NormalMask)
1181
atoms[pnum++] = net_wm_window_type_normal;
1182
if (p->properties[ WINDOW_TYPES ] & DesktopMask)
1183
atoms[pnum++] = net_wm_window_type_desktop;
1184
if (p->properties[ WINDOW_TYPES ] & DockMask)
1185
atoms[pnum++] = net_wm_window_type_dock;
1186
if (p->properties[ WINDOW_TYPES ] & ToolbarMask)
1187
atoms[pnum++] = net_wm_window_type_toolbar;
1188
if (p->properties[ WINDOW_TYPES ] & MenuMask)
1189
atoms[pnum++] = net_wm_window_type_menu;
1190
if (p->properties[ WINDOW_TYPES ] & DialogMask)
1191
atoms[pnum++] = net_wm_window_type_dialog;
1192
if (p->properties[ WINDOW_TYPES ] & UtilityMask)
1193
atoms[pnum++] = net_wm_window_type_utility;
1194
if (p->properties[ WINDOW_TYPES ] & SplashMask)
1195
atoms[pnum++] = net_wm_window_type_splash;
1196
if (p->properties[ WINDOW_TYPES ] & DropdownMenuMask)
1197
atoms[pnum++] = net_wm_window_type_dropdown_menu;
1198
if (p->properties[ WINDOW_TYPES ] & PopupMenuMask)
1199
atoms[pnum++] = net_wm_window_type_popup_menu;
1200
if (p->properties[ WINDOW_TYPES ] & TooltipMask)
1201
atoms[pnum++] = net_wm_window_type_tooltip;
1202
if (p->properties[ WINDOW_TYPES ] & NotificationMask)
1203
atoms[pnum++] = net_wm_window_type_notification;
1204
if (p->properties[ WINDOW_TYPES ] & ComboBoxMask)
1205
atoms[pnum++] = net_wm_window_type_combobox;
1206
if (p->properties[ WINDOW_TYPES ] & DNDIconMask)
1207
atoms[pnum++] = net_wm_window_type_dnd;
1209
if (p->properties[ WINDOW_TYPES ] & OverrideMask)
1210
atoms[pnum++] = kde_net_wm_window_type_override;
1211
if (p->properties[ WINDOW_TYPES ] & TopMenuMask)
1212
atoms[pnum++] = kde_net_wm_window_type_topmenu;
1215
if (p->properties[ PROTOCOLS ] & WMState) {
1216
atoms[pnum++] = net_wm_state;
1218
// Application window states
1219
if (p->properties[ STATES ] & Modal)
1220
atoms[pnum++] = net_wm_state_modal;
1221
if (p->properties[ STATES ] & Sticky)
1222
atoms[pnum++] = net_wm_state_sticky;
1223
if (p->properties[ STATES ] & MaxVert)
1224
atoms[pnum++] = net_wm_state_max_vert;
1225
if (p->properties[ STATES ] & MaxHoriz)
1226
atoms[pnum++] = net_wm_state_max_horiz;
1227
if (p->properties[ STATES ] & Shaded)
1228
atoms[pnum++] = net_wm_state_shaded;
1229
if (p->properties[ STATES ] & SkipTaskbar)
1230
atoms[pnum++] = net_wm_state_skip_taskbar;
1231
if (p->properties[ STATES ] & SkipPager)
1232
atoms[pnum++] = net_wm_state_skip_pager;
1233
if (p->properties[ STATES ] & Hidden)
1234
atoms[pnum++] = net_wm_state_hidden;
1235
if (p->properties[ STATES ] & FullScreen)
1236
atoms[pnum++] = net_wm_state_fullscreen;
1237
if (p->properties[ STATES ] & KeepAbove)
1238
atoms[pnum++] = net_wm_state_above;
1239
if (p->properties[ STATES ] & KeepBelow)
1240
atoms[pnum++] = net_wm_state_below;
1241
if (p->properties[ STATES ] & DemandsAttention)
1242
atoms[pnum++] = net_wm_state_demands_attention;
1244
if (p->properties[ STATES ] & StaysOnTop)
1245
atoms[pnum++] = net_wm_state_stays_on_top;
1248
if (p->properties[ PROTOCOLS ] & WMStrut)
1249
atoms[pnum++] = net_wm_strut;
1251
if (p->properties[ PROTOCOLS2 ] & WM2ExtendedStrut)
1252
atoms[pnum++] = net_wm_extended_strut;
1254
if (p->properties[ PROTOCOLS ] & WMIconGeometry)
1255
atoms[pnum++] = net_wm_icon_geometry;
1257
if (p->properties[ PROTOCOLS ] & WMIcon)
1258
atoms[pnum++] = net_wm_icon;
1260
if (p->properties[ PROTOCOLS ] & WMPid)
1261
atoms[pnum++] = net_wm_pid;
1263
if (p->properties[ PROTOCOLS ] & WMHandledIcons)
1264
atoms[pnum++] = net_wm_handled_icons;
1266
if (p->properties[ PROTOCOLS ] & WMPing)
1267
atoms[pnum++] = net_wm_ping;
1269
if (p->properties[ PROTOCOLS2 ] & WM2TakeActivity)
1270
atoms[pnum++] = net_wm_take_activity;
1272
if (p->properties[ PROTOCOLS2 ] & WM2UserTime)
1273
atoms[pnum++] = net_wm_user_time;
1275
if (p->properties[ PROTOCOLS2 ] & WM2StartupId)
1276
atoms[pnum++] = net_startup_id;
1278
if (p->properties[ PROTOCOLS2 ] & WM2Opacity)
1279
atoms[pnum++] = net_wm_window_opacity;
1281
if (p->properties[ PROTOCOLS2 ] & WM2AllowedActions) {
1282
atoms[pnum++] = net_wm_allowed_actions;
1285
if (p->properties[ ACTIONS ] & ActionMove)
1286
atoms[pnum++] = net_wm_action_move;
1287
if (p->properties[ ACTIONS ] & ActionResize)
1288
atoms[pnum++] = net_wm_action_resize;
1289
if (p->properties[ ACTIONS ] & ActionMinimize)
1290
atoms[pnum++] = net_wm_action_minimize;
1291
if (p->properties[ ACTIONS ] & ActionShade)
1292
atoms[pnum++] = net_wm_action_shade;
1293
if (p->properties[ ACTIONS ] & ActionStick)
1294
atoms[pnum++] = net_wm_action_stick;
1295
if (p->properties[ ACTIONS ] & ActionMaxVert)
1296
atoms[pnum++] = net_wm_action_max_vert;
1297
if (p->properties[ ACTIONS ] & ActionMaxHoriz)
1298
atoms[pnum++] = net_wm_action_max_horiz;
1299
if (p->properties[ ACTIONS ] & ActionFullScreen)
1300
atoms[pnum++] = net_wm_action_fullscreen;
1301
if (p->properties[ ACTIONS ] & ActionChangeDesktop)
1302
atoms[pnum++] = net_wm_action_change_desk;
1303
if (p->properties[ ACTIONS ] & ActionClose)
1304
atoms[pnum++] = net_wm_action_close;
1307
// KDE specific extensions
1308
if (p->properties[ PROTOCOLS ] & KDESystemTrayWindows)
1309
atoms[pnum++] = kde_net_system_tray_windows;
1311
if (p->properties[ PROTOCOLS ] & WMKDESystemTrayWinFor)
1312
atoms[pnum++] = kde_net_wm_system_tray_window_for;
1314
if (p->properties[ PROTOCOLS ] & WMFrameExtents) {
1315
atoms[pnum++] = net_frame_extents;
1316
atoms[pnum++] = kde_net_wm_frame_strut;
1319
if (p->properties[ PROTOCOLS2 ] & WM2KDETemporaryRules)
1320
atoms[pnum++] = kde_net_wm_temporary_rules;
1322
XChangeProperty(p->display, p->root, net_supported, XA_ATOM, 32,
1323
PropModeReplace, (unsigned char *) atoms, pnum);
1324
XChangeProperty(p->display, p->root, net_supporting_wm_check, XA_WINDOW, 32,
1325
PropModeReplace, (unsigned char *) &(p->supportwindow), 1);
1329
"NETRootInfo::setSupported: _NET_SUPPORTING_WM_CHECK = 0x%lx on 0x%lx\n"
1330
" : _NET_WM_NAME = '%s' on 0x%lx\n",
1331
p->supportwindow, p->supportwindow, p->name, p->supportwindow);
1334
XChangeProperty(p->display, p->supportwindow, net_supporting_wm_check,
1335
XA_WINDOW, 32, PropModeReplace,
1336
(unsigned char *) &(p->supportwindow), 1);
1337
XChangeProperty(p->display, p->supportwindow, net_wm_name, UTF8_STRING, 8,
1338
PropModeReplace, (unsigned char *) p->name,
1342
void NETRootInfo::updateSupportedProperties( Atom atom )
1344
if( atom == net_supported )
1345
p->properties[ PROTOCOLS ] |= Supported;
1347
else if( atom == net_supporting_wm_check )
1348
p->properties[ PROTOCOLS ] |= SupportingWMCheck;
1350
else if( atom == net_client_list )
1351
p->properties[ PROTOCOLS ] |= ClientList;
1353
else if( atom == net_client_list_stacking )
1354
p->properties[ PROTOCOLS ] |= ClientListStacking;
1356
else if( atom == net_number_of_desktops )
1357
p->properties[ PROTOCOLS ] |= NumberOfDesktops;
1359
else if( atom == net_desktop_geometry )
1360
p->properties[ PROTOCOLS ] |= DesktopGeometry;
1362
else if( atom == net_desktop_viewport )
1363
p->properties[ PROTOCOLS ] |= DesktopViewport;
1365
else if( atom == net_current_desktop )
1366
p->properties[ PROTOCOLS ] |= CurrentDesktop;
1368
else if( atom == net_desktop_names )
1369
p->properties[ PROTOCOLS ] |= DesktopNames;
1371
else if( atom == net_active_window )
1372
p->properties[ PROTOCOLS ] |= ActiveWindow;
1374
else if( atom == net_workarea )
1375
p->properties[ PROTOCOLS ] |= WorkArea;
1377
else if( atom == net_virtual_roots )
1378
p->properties[ PROTOCOLS ] |= VirtualRoots;
1380
else if( atom == net_desktop_layout )
1381
p->properties[ PROTOCOLS2 ] |= WM2DesktopLayout;
1383
else if( atom == net_close_window )
1384
p->properties[ PROTOCOLS ] |= CloseWindow;
1386
else if( atom == net_restack_window )
1387
p->properties[ PROTOCOLS2 ] |= WM2RestackWindow;
1389
else if( atom == net_showing_desktop )
1390
p->properties[ PROTOCOLS2 ] |= WM2ShowingDesktop;
1392
// Application window properties/messages
1393
else if( atom == net_wm_moveresize )
1394
p->properties[ PROTOCOLS ] |= WMMoveResize;
1396
else if( atom == net_moveresize_window )
1397
p->properties[ PROTOCOLS2 ] |= WM2MoveResizeWindow;
1399
else if( atom == net_wm_name )
1400
p->properties[ PROTOCOLS ] |= WMName;
1402
else if( atom == net_wm_visible_name )
1403
p->properties[ PROTOCOLS ] |= WMVisibleName;
1405
else if( atom == net_wm_icon_name )
1406
p->properties[ PROTOCOLS ] |= WMIconName;
1408
else if( atom == net_wm_visible_icon_name )
1409
p->properties[ PROTOCOLS ] |= WMVisibleIconName;
1411
else if( atom == net_wm_desktop )
1412
p->properties[ PROTOCOLS ] |= WMDesktop;
1414
else if( atom == net_wm_window_type )
1415
p->properties[ PROTOCOLS ] |= WMWindowType;
1417
// Application window types
1418
else if( atom == net_wm_window_type_normal )
1419
p->properties[ WINDOW_TYPES ] |= NormalMask;
1420
else if( atom == net_wm_window_type_desktop )
1421
p->properties[ WINDOW_TYPES ] |= DesktopMask;
1422
else if( atom == net_wm_window_type_dock )
1423
p->properties[ WINDOW_TYPES ] |= DockMask;
1424
else if( atom == net_wm_window_type_toolbar )
1425
p->properties[ WINDOW_TYPES ] |= ToolbarMask;
1426
else if( atom == net_wm_window_type_menu )
1427
p->properties[ WINDOW_TYPES ] |= MenuMask;
1428
else if( atom == net_wm_window_type_dialog )
1429
p->properties[ WINDOW_TYPES ] |= DialogMask;
1430
else if( atom == net_wm_window_type_utility )
1431
p->properties[ WINDOW_TYPES ] |= UtilityMask;
1432
else if( atom == net_wm_window_type_splash )
1433
p->properties[ WINDOW_TYPES ] |= SplashMask;
1434
else if( atom == net_wm_window_type_dropdown_menu )
1435
p->properties[ WINDOW_TYPES ] |= DropdownMenuMask;
1436
else if( atom == net_wm_window_type_popup_menu )
1437
p->properties[ WINDOW_TYPES ] |= PopupMenuMask;
1438
else if( atom == net_wm_window_type_tooltip )
1439
p->properties[ WINDOW_TYPES ] |= TooltipMask;
1440
else if( atom == net_wm_window_type_notification )
1441
p->properties[ WINDOW_TYPES ] |= NotificationMask;
1442
else if( atom == net_wm_window_type_combobox )
1443
p->properties[ WINDOW_TYPES ] |= ComboBoxMask;
1444
else if( atom == net_wm_window_type_dnd )
1445
p->properties[ WINDOW_TYPES ] |= DNDIconMask;
1447
else if( atom == kde_net_wm_window_type_override )
1448
p->properties[ WINDOW_TYPES ] |= OverrideMask;
1449
else if( atom == kde_net_wm_window_type_topmenu )
1450
p->properties[ WINDOW_TYPES ] |= TopMenuMask;
1452
else if( atom == net_wm_state )
1453
p->properties[ PROTOCOLS ] |= WMState;
1455
// Application window states
1456
else if( atom == net_wm_state_modal )
1457
p->properties[ STATES ] |= Modal;
1458
else if( atom == net_wm_state_sticky )
1459
p->properties[ STATES ] |= Sticky;
1460
else if( atom == net_wm_state_max_vert )
1461
p->properties[ STATES ] |= MaxVert;
1462
else if( atom == net_wm_state_max_horiz )
1463
p->properties[ STATES ] |= MaxHoriz;
1464
else if( atom == net_wm_state_shaded )
1465
p->properties[ STATES ] |= Shaded;
1466
else if( atom == net_wm_state_skip_taskbar )
1467
p->properties[ STATES ] |= SkipTaskbar;
1468
else if( atom == net_wm_state_skip_pager )
1469
p->properties[ STATES ] |= SkipPager;
1470
else if( atom == net_wm_state_hidden )
1471
p->properties[ STATES ] |= Hidden;
1472
else if( atom == net_wm_state_fullscreen )
1473
p->properties[ STATES ] |= FullScreen;
1474
else if( atom == net_wm_state_above )
1475
p->properties[ STATES ] |= KeepAbove;
1476
else if( atom == net_wm_state_below )
1477
p->properties[ STATES ] |= KeepBelow;
1478
else if( atom == net_wm_state_demands_attention )
1479
p->properties[ STATES ] |= DemandsAttention;
1481
else if( atom == net_wm_state_stays_on_top )
1482
p->properties[ STATES ] |= StaysOnTop;
1484
else if( atom == net_wm_strut )
1485
p->properties[ PROTOCOLS ] |= WMStrut;
1487
else if( atom == net_wm_extended_strut )
1488
p->properties[ PROTOCOLS2 ] |= WM2ExtendedStrut;
1490
else if( atom == net_wm_icon_geometry )
1491
p->properties[ PROTOCOLS ] |= WMIconGeometry;
1493
else if( atom == net_wm_icon )
1494
p->properties[ PROTOCOLS ] |= WMIcon;
1496
else if( atom == net_wm_pid )
1497
p->properties[ PROTOCOLS ] |= WMPid;
1499
else if( atom == net_wm_handled_icons )
1500
p->properties[ PROTOCOLS ] |= WMHandledIcons;
1502
else if( atom == net_wm_ping )
1503
p->properties[ PROTOCOLS ] |= WMPing;
1505
else if( atom == net_wm_take_activity )
1506
p->properties[ PROTOCOLS2 ] |= WM2TakeActivity;
1508
else if( atom == net_wm_user_time )
1509
p->properties[ PROTOCOLS2 ] |= WM2UserTime;
1511
else if( atom == net_startup_id )
1512
p->properties[ PROTOCOLS2 ] |= WM2StartupId;
1514
else if( atom == net_wm_window_opacity )
1515
p->properties[ PROTOCOLS2 ] |= WM2Opacity;
1517
else if( atom == net_wm_allowed_actions )
1518
p->properties[ PROTOCOLS2 ] |= WM2AllowedActions;
1521
else if( atom == net_wm_action_move )
1522
p->properties[ ACTIONS ] |= ActionMove;
1523
else if( atom == net_wm_action_resize )
1524
p->properties[ ACTIONS ] |= ActionResize;
1525
else if( atom == net_wm_action_minimize )
1526
p->properties[ ACTIONS ] |= ActionMinimize;
1527
else if( atom == net_wm_action_shade )
1528
p->properties[ ACTIONS ] |= ActionShade;
1529
else if( atom == net_wm_action_stick )
1530
p->properties[ ACTIONS ] |= ActionStick;
1531
else if( atom == net_wm_action_max_vert )
1532
p->properties[ ACTIONS ] |= ActionMaxVert;
1533
else if( atom == net_wm_action_max_horiz )
1534
p->properties[ ACTIONS ] |= ActionMaxHoriz;
1535
else if( atom == net_wm_action_fullscreen )
1536
p->properties[ ACTIONS ] |= ActionFullScreen;
1537
else if( atom == net_wm_action_change_desk )
1538
p->properties[ ACTIONS ] |= ActionChangeDesktop;
1539
else if( atom == net_wm_action_close )
1540
p->properties[ ACTIONS ] |= ActionClose;
1542
// KDE specific extensions
1543
else if( atom == kde_net_system_tray_windows )
1544
p->properties[ PROTOCOLS ] |= KDESystemTrayWindows;
1546
else if( atom == kde_net_wm_system_tray_window_for )
1547
p->properties[ PROTOCOLS ] |= WMKDESystemTrayWinFor;
1549
else if( atom == net_frame_extents )
1550
p->properties[ PROTOCOLS ] |= WMFrameExtents;
1551
else if( atom == kde_net_wm_frame_strut )
1552
p->properties[ PROTOCOLS ] |= WMKDEFrameStrut;
1554
else if( atom == kde_net_wm_temporary_rules )
1555
p->properties[ PROTOCOLS2 ] |= WM2KDETemporaryRules;
1558
void NETRootInfo::setActiveWindow(Window window) {
1559
setActiveWindow( window, FromUnknown, QX11Info::appUserTime(), None );
1562
void NETRootInfo::setActiveWindow(Window window, NET::RequestSource src,
1563
Time timestamp, Window active_window ) {
1566
fprintf(stderr, "NETRootInfo::setActiveWindow(0x%lx) (%s)\n",
1567
window, (role == WindowManager) ? "WM" : "Client");
1570
if (role == WindowManager) {
1572
XChangeProperty(p->display, p->root, net_active_window, XA_WINDOW, 32,
1573
PropModeReplace, (unsigned char *) &(p->active), 1);
1577
e.xclient.type = ClientMessage;
1578
e.xclient.message_type = net_active_window;
1579
e.xclient.display = p->display;
1580
e.xclient.window = window;
1581
e.xclient.format = 32;
1582
e.xclient.data.l[0] = src;
1583
e.xclient.data.l[1] = timestamp;
1584
e.xclient.data.l[2] = active_window;
1585
e.xclient.data.l[3] = 0l;
1586
e.xclient.data.l[4] = 0l;
1588
XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
1593
void NETRootInfo::setWorkArea(int desktop, const NETRect &workarea) {
1596
fprintf(stderr, "NETRootInfo::setWorkArea(%d, { %d, %d, %d, %d }) (%s)\n",
1597
desktop, workarea.pos.x, workarea.pos.y, workarea.size.width, workarea.size.height,
1598
(role == WindowManager) ? "WM" : "Client");
1601
if (role != WindowManager || desktop < 1) return;
1603
p->workarea[desktop - 1] = workarea;
1605
long *wa = new long[p->number_of_desktops * 4];
1607
for (i = 0, o = 0; i < p->number_of_desktops; i++) {
1608
wa[o++] = p->workarea[i].pos.x;
1609
wa[o++] = p->workarea[i].pos.y;
1610
wa[o++] = p->workarea[i].size.width;
1611
wa[o++] = p->workarea[i].size.height;
1614
XChangeProperty(p->display, p->root, net_workarea, XA_CARDINAL, 32,
1615
PropModeReplace, (unsigned char *) wa,
1616
p->number_of_desktops * 4);
1622
void NETRootInfo::setVirtualRoots(Window *windows, unsigned int count) {
1623
if (role != WindowManager) return;
1625
p->virtual_roots_count = count;
1626
p->virtual_roots = windows;
1629
fprintf(stderr, "NETRootInfo::setVirtualRoots: setting list with %ld windows\n",
1630
p->virtual_roots_count);
1633
XChangeProperty(p->display, p->root, net_virtual_roots, XA_WINDOW, 32,
1634
PropModeReplace, (unsigned char *) p->virtual_roots,
1635
p->virtual_roots_count);
1639
void NETRootInfo::setDesktopLayout(NET::Orientation orientation, int columns, int rows,
1640
NET::DesktopLayoutCorner corner)
1642
p->desktop_layout_orientation = orientation;
1643
p->desktop_layout_columns = columns;
1644
p->desktop_layout_rows = rows;
1645
p->desktop_layout_corner = corner;
1648
fprintf(stderr, "NETRootInfo::setDesktopLayout: %d %d %d %d\n",
1649
orientation, columns, rows, corner);
1653
data[ 0 ] = orientation;
1654
data[ 1 ] = columns;
1657
XChangeProperty(p->display, p->root, net_desktop_layout, XA_CARDINAL, 32,
1658
PropModeReplace, (unsigned char *) &data, 4);
1662
void NETRootInfo::setShowingDesktop( bool showing ) {
1663
if (role == WindowManager) {
1664
long d = p->showing_desktop = showing;
1665
XChangeProperty(p->display, p->root, net_showing_desktop, XA_CARDINAL, 32,
1666
PropModeReplace, (unsigned char *) &d, 1);
1670
e.xclient.type = ClientMessage;
1671
e.xclient.message_type = net_showing_desktop;
1672
e.xclient.display = p->display;
1673
e.xclient.window = 0;
1674
e.xclient.format = 32;
1675
e.xclient.data.l[0] = showing ? 1 : 0;
1676
e.xclient.data.l[1] = 0;
1677
e.xclient.data.l[2] = 0;
1678
e.xclient.data.l[3] = 0;
1679
e.xclient.data.l[4] = 0;
1681
XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
1686
bool NETRootInfo::showingDesktop() const {
1687
return p->showing_desktop;
1691
void NETRootInfo::closeWindowRequest(Window window) {
1694
fprintf(stderr, "NETRootInfo::closeWindowRequest: requesting close for 0x%lx\n",
1700
e.xclient.type = ClientMessage;
1701
e.xclient.message_type = net_close_window;
1702
e.xclient.display = p->display;
1703
e.xclient.window = window;
1704
e.xclient.format = 32;
1705
e.xclient.data.l[0] = 0l;
1706
e.xclient.data.l[1] = 0l;
1707
e.xclient.data.l[2] = 0l;
1708
e.xclient.data.l[3] = 0l;
1709
e.xclient.data.l[4] = 0l;
1711
XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
1715
void NETRootInfo::moveResizeRequest(Window window, int x_root, int y_root,
1716
Direction direction)
1721
"NETRootInfo::moveResizeRequest: requesting resize/move for 0x%lx (%d, %d, %d)\n",
1722
window, x_root, y_root, direction);
1727
e.xclient.type = ClientMessage;
1728
e.xclient.message_type = net_wm_moveresize;
1729
e.xclient.display = p->display;
1730
e.xclient.window = window,
1731
e.xclient.format = 32;
1732
e.xclient.data.l[0] = x_root;
1733
e.xclient.data.l[1] = y_root;
1734
e.xclient.data.l[2] = direction;
1735
e.xclient.data.l[3] = 0l;
1736
e.xclient.data.l[4] = 0l;
1738
XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
1741
void NETRootInfo::moveResizeWindowRequest(Window window, int flags, int x, int y, int width, int height )
1746
"NETRootInfo::moveResizeWindowRequest: resizing/moving 0x%lx (%d, %d, %d, %d, %d)\n",
1747
window, flags, x, y, width, height);
1752
e.xclient.type = ClientMessage;
1753
e.xclient.message_type = net_moveresize_window;
1754
e.xclient.display = p->display;
1755
e.xclient.window = window,
1756
e.xclient.format = 32;
1757
e.xclient.data.l[0] = flags;
1758
e.xclient.data.l[1] = x;
1759
e.xclient.data.l[2] = y;
1760
e.xclient.data.l[3] = width;
1761
e.xclient.data.l[4] = height;
1763
XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
1766
void NETRootInfo::restackRequest(Window window, Window above, int detail)
1768
restackRequest( window, FromTool, above, detail, QX11Info::appUserTime() );
1771
void NETRootInfo::restackRequest(Window window, RequestSource src, Window above, int detail, Time timestamp )
1775
"NETRootInfo::restackRequest: requesting restack for 0x%lx (%lx, %d)\n",
1776
window, above, detail);
1781
e.xclient.type = ClientMessage;
1782
e.xclient.message_type = net_restack_window;
1783
e.xclient.display = p->display;
1784
e.xclient.window = window,
1785
e.xclient.format = 32;
1786
e.xclient.data.l[0] = src;
1787
e.xclient.data.l[1] = above;
1788
e.xclient.data.l[2] = detail;
1789
e.xclient.data.l[3] = timestamp;
1790
e.xclient.data.l[4] = 0l;
1792
XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
1795
void NETRootInfo2::sendPing( Window window, Time timestamp )
1797
if (role != WindowManager) return;
1799
fprintf(stderr, "NETRootInfo2::setPing: window 0x%lx, timestamp %lu\n",
1800
window, timestamp );
1803
e.xclient.type = ClientMessage;
1804
e.xclient.message_type = wm_protocols;
1805
e.xclient.display = p->display;
1806
e.xclient.window = window,
1807
e.xclient.format = 32;
1808
e.xclient.data.l[0] = net_wm_ping;
1809
e.xclient.data.l[1] = timestamp;
1810
e.xclient.data.l[2] = window;
1811
e.xclient.data.l[3] = 0;
1812
e.xclient.data.l[4] = 0;
1814
XSendEvent(p->display, window, False, 0, &e);
1817
void NETRootInfo3::takeActivity( Window window, Time timestamp, long flags )
1819
if (role != WindowManager) return;
1821
fprintf(stderr, "NETRootInfo2::takeActivity: window 0x%lx, timestamp %lu, flags 0x%lx\n",
1822
window, timestamp, flags );
1825
e.xclient.type = ClientMessage;
1826
e.xclient.message_type = wm_protocols;
1827
e.xclient.display = p->display;
1828
e.xclient.window = window,
1829
e.xclient.format = 32;
1830
e.xclient.data.l[0] = net_wm_take_activity;
1831
e.xclient.data.l[1] = timestamp;
1832
e.xclient.data.l[2] = window;
1833
e.xclient.data.l[3] = flags;
1834
e.xclient.data.l[4] = 0;
1836
XSendEvent(p->display, window, False, 0, &e);
1841
// assignment operator
1843
const NETRootInfo &NETRootInfo::operator=(const NETRootInfo &rootinfo) {
1846
fprintf(stderr, "NETRootInfo::operator=()\n");
1849
if (p != rootinfo.p) {
1852
if (! p->ref) delete p;
1856
role = rootinfo.role;
1862
unsigned long NETRootInfo::event(XEvent *ev )
1864
unsigned long props[ 1 ];
1865
event( ev, props, 1 );
1869
void NETRootInfo::event(XEvent *event, unsigned long* properties, int properties_size )
1871
unsigned long props[ PROPERTIES_SIZE ] = { 0, 0, 0, 0, 0 };
1872
assert( PROPERTIES_SIZE == 5 ); // add elements above
1873
unsigned long& dirty = props[ PROTOCOLS ];
1874
unsigned long& dirty2 = props[ PROTOCOLS2 ];
1875
bool do_update = false;
1877
// the window manager will be interested in client messages... no other
1878
// client should get these messages
1879
if (role == WindowManager && event->type == ClientMessage &&
1880
event->xclient.format == 32) {
1882
fprintf(stderr, "NETRootInfo::event: handling ClientMessage event\n");
1885
if (event->xclient.message_type == net_number_of_desktops) {
1886
dirty = NumberOfDesktops;
1889
fprintf(stderr, "NETRootInfo::event: changeNumberOfDesktops(%ld)\n",
1890
event->xclient.data.l[0]);
1893
changeNumberOfDesktops(event->xclient.data.l[0]);
1894
} else if (event->xclient.message_type == net_desktop_geometry) {
1895
dirty = DesktopGeometry;
1898
sz.width = event->xclient.data.l[0];
1899
sz.height = event->xclient.data.l[1];
1902
fprintf(stderr, "NETRootInfo::event: changeDesktopGeometry( -- , { %d, %d })\n",
1903
sz.width, sz.height);
1906
changeDesktopGeometry(~0, sz);
1907
} else if (event->xclient.message_type == net_desktop_viewport) {
1908
dirty = DesktopViewport;
1911
pt.x = event->xclient.data.l[0];
1912
pt.y = event->xclient.data.l[1];
1915
fprintf(stderr, "NETRootInfo::event: changeDesktopViewport(%d, { %d, %d })\n",
1916
p->current_desktop, pt.x, pt.y);
1919
changeDesktopViewport(p->current_desktop, pt);
1920
} else if (event->xclient.message_type == net_current_desktop) {
1921
dirty = CurrentDesktop;
1924
fprintf(stderr, "NETRootInfo::event: changeCurrentDesktop(%ld)\n",
1925
event->xclient.data.l[0] + 1);
1928
changeCurrentDesktop(event->xclient.data.l[0] + 1);
1929
} else if (event->xclient.message_type == net_active_window) {
1930
dirty = ActiveWindow;
1933
fprintf(stderr, "NETRootInfo::event: changeActiveWindow(0x%lx)\n",
1934
event->xclient.window);
1937
changeActiveWindow(event->xclient.window);
1938
if( NETRootInfo2* this2 = dynamic_cast< NETRootInfo2* >( this ))
1940
RequestSource src = FromUnknown;
1941
Time timestamp = CurrentTime;
1942
Window active_window = None;
1943
// make sure there aren't unknown values
1944
if( event->xclient.data.l[0] >= FromUnknown
1945
&& event->xclient.data.l[0] <= FromTool )
1947
src = static_cast< RequestSource >( event->xclient.data.l[0] );
1948
timestamp = event->xclient.data.l[1];
1949
active_window = event->xclient.data.l[2];
1951
this2->changeActiveWindow( event->xclient.window, src, timestamp, active_window );
1953
} else if (event->xclient.message_type == net_wm_moveresize) {
1956
fprintf(stderr, "NETRootInfo::event: moveResize(%ld, %ld, %ld, %ld)\n",
1957
event->xclient.window,
1958
event->xclient.data.l[0],
1959
event->xclient.data.l[1],
1960
event->xclient.data.l[2]
1964
moveResize(event->xclient.window,
1965
event->xclient.data.l[0],
1966
event->xclient.data.l[1],
1967
event->xclient.data.l[2]);
1968
} else if (event->xclient.message_type == net_moveresize_window) {
1971
fprintf(stderr, "NETRootInfo::event: moveResizeWindow(%ld, %ld, %ld, %ld, %ld, %ld)\n",
1972
event->xclient.window,
1973
event->xclient.data.l[0],
1974
event->xclient.data.l[1],
1975
event->xclient.data.l[2],
1976
event->xclient.data.l[3],
1977
event->xclient.data.l[4]
1981
if( NETRootInfo2* this2 = dynamic_cast< NETRootInfo2* >( this ))
1982
this2->moveResizeWindow(event->xclient.window,
1983
event->xclient.data.l[0],
1984
event->xclient.data.l[1],
1985
event->xclient.data.l[2],
1986
event->xclient.data.l[3],
1987
event->xclient.data.l[4]);
1988
} else if (event->xclient.message_type == net_close_window) {
1991
fprintf(stderr, "NETRootInfo::event: closeWindow(0x%lx)\n",
1992
event->xclient.window);
1995
closeWindow(event->xclient.window);
1996
} else if (event->xclient.message_type == net_restack_window) {
1999
fprintf(stderr, "NETRootInfo::event: restackWindow(0x%lx)\n",
2000
event->xclient.window);
2003
if( NETRootInfo3* this3 = dynamic_cast< NETRootInfo3* >( this ))
2005
RequestSource src = FromUnknown;
2006
Time timestamp = CurrentTime;
2007
// make sure there aren't unknown values
2008
if( event->xclient.data.l[0] >= FromUnknown
2009
&& event->xclient.data.l[0] <= FromTool )
2011
src = static_cast< RequestSource >( event->xclient.data.l[0] );
2012
timestamp = event->xclient.data.l[3];
2014
this3->restackWindow(event->xclient.window, src,
2015
event->xclient.data.l[1], event->xclient.data.l[2], timestamp);
2017
else if( NETRootInfo2* this2 = dynamic_cast< NETRootInfo2* >( this ))
2018
this2->restackWindow(event->xclient.window,
2019
event->xclient.data.l[1], event->xclient.data.l[2]);
2020
} else if (event->xclient.message_type == wm_protocols
2021
&& (Atom)event->xclient.data.l[ 0 ] == net_wm_ping) {
2025
fprintf(stderr, "NETRootInfo2::event: gotPing(0x%lx,%lu)\n",
2026
event->xclient.window, event->xclient.data.l[1]);
2028
if( NETRootInfo2* this2 = dynamic_cast< NETRootInfo2* >( this ))
2029
this2->gotPing( event->xclient.data.l[2], event->xclient.data.l[1]);
2030
} else if (event->xclient.message_type == wm_protocols
2031
&& (Atom)event->xclient.data.l[ 0 ] == net_wm_take_activity) {
2032
dirty2 = WM2TakeActivity;
2035
fprintf(stderr, "NETRootInfo2::event: gotTakeActivity(0x%lx,%lu,0x%lx)\n",
2036
event->xclient.window, event->xclient.data.l[1], event->xclient.data.l[3]);
2038
if( NETRootInfo3* this3 = dynamic_cast< NETRootInfo3* >( this ))
2039
this3->gotTakeActivity( event->xclient.data.l[2], event->xclient.data.l[1],
2040
event->xclient.data.l[3]);
2041
} else if (event->xclient.message_type == net_showing_desktop) {
2042
dirty2 = WM2ShowingDesktop;
2045
fprintf(stderr, "NETRootInfo::event: changeShowingDesktop(%ld)\n",
2046
event->xclient.data.l[0]);
2049
if( NETRootInfo4* this4 = dynamic_cast< NETRootInfo4* >( this ))
2050
this4->changeShowingDesktop(event->xclient.data.l[0]);
2054
if (event->type == PropertyNotify) {
2057
fprintf(stderr, "NETRootInfo::event: handling PropertyNotify event\n");
2063
Bool compaction = False;
2067
fprintf(stderr, "NETRootInfo::event: loop fire\n");
2070
if (pe.xproperty.atom == net_client_list)
2071
dirty |= ClientList;
2072
else if (pe.xproperty.atom == net_client_list_stacking)
2073
dirty |= ClientListStacking;
2074
else if (pe.xproperty.atom == kde_net_system_tray_windows)
2075
dirty |= KDESystemTrayWindows;
2076
else if (pe.xproperty.atom == net_desktop_names)
2077
dirty |= DesktopNames;
2078
else if (pe.xproperty.atom == net_workarea)
2080
else if (pe.xproperty.atom == net_number_of_desktops)
2081
dirty |= NumberOfDesktops;
2082
else if (pe.xproperty.atom == net_desktop_geometry)
2083
dirty |= DesktopGeometry;
2084
else if (pe.xproperty.atom == net_desktop_viewport)
2085
dirty |= DesktopViewport;
2086
else if (pe.xproperty.atom == net_current_desktop)
2087
dirty |= CurrentDesktop;
2088
else if (pe.xproperty.atom == net_active_window)
2089
dirty |= ActiveWindow;
2090
else if (pe.xproperty.atom == net_showing_desktop)
2091
dirty2 |= WM2ShowingDesktop;
2095
fprintf(stderr, "NETRootInfo::event: putting back event and breaking\n");
2099
XPutBackEvent(p->display, &pe);
2103
if (XCheckTypedWindowEvent(p->display, p->root, PropertyNotify, &pe) )
2116
fprintf(stderr, "NETRootInfo::event: handled events, returning dirty = 0x%lx, 0x%lx\n",
2120
if( properties_size > PROPERTIES_SIZE )
2121
properties_size = PROPERTIES_SIZE;
2123
i < properties_size;
2125
properties[ i ] = props[ i ];
2129
// private functions to update the data we keep
2131
void NETRootInfo::update( const unsigned long dirty_props[] )
2135
unsigned char *data_ret;
2136
unsigned long nitems_ret, unused;
2137
unsigned long props[ PROPERTIES_SIZE ];
2139
i < PROPERTIES_SIZE;
2141
props[ i ] = dirty_props[ i ] & p->client_properties[ i ];
2142
const unsigned long& dirty = props[ PROTOCOLS ];
2143
const unsigned long& dirty2 = props[ PROTOCOLS2 ];
2145
if (dirty & Supported ) {
2146
// only in Client mode
2147
for( int i = 0; i < PROPERTIES_SIZE; ++i )
2148
p->properties[ i ] = 0;
2149
if( XGetWindowProperty(p->display, p->root, net_supported,
2150
0l, MAX_PROP_SIZE, False, XA_ATOM, &type_ret,
2151
&format_ret, &nitems_ret, &unused, &data_ret)
2153
if( type_ret == XA_ATOM && format_ret == 32 ) {
2154
Atom* atoms = (Atom*) data_ret;
2155
for( unsigned int i = 0;
2158
updateSupportedProperties( atoms[ i ] );
2165
if (dirty & ClientList) {
2166
bool read_ok = false;
2167
if (XGetWindowProperty(p->display, p->root, net_client_list,
2168
0l, MAX_PROP_SIZE, False, XA_WINDOW, &type_ret,
2169
&format_ret, &nitems_ret, &unused, &data_ret)
2171
if (type_ret == XA_WINDOW && format_ret == 32) {
2172
Window *wins = (Window *) data_ret;
2174
qsort(wins, nitems_ret, sizeof(Window), wcmp);
2177
if (role == Client) {
2178
unsigned long new_index = 0, old_index = 0;
2179
unsigned long new_count = nitems_ret,
2180
old_count = p->clients_count;
2182
while (old_index < old_count || new_index < new_count) {
2183
if (old_index == old_count) {
2184
addClient(wins[new_index++]);
2185
} else if (new_index == new_count) {
2186
removeClient(p->clients[old_index++]);
2188
if (p->clients[old_index] <
2190
removeClient(p->clients[old_index++]);
2191
} else if (wins[new_index] <
2192
p->clients[old_index]) {
2193
addClient(wins[new_index++]);
2202
delete [] p->clients;
2205
fprintf(stderr, "NETRootInfo::update: client list null, creating\n");
2209
for (n = 0; n < nitems_ret; n++) {
2214
p->clients_count = nitems_ret;
2215
p->clients = nwindup(wins, p->clients_count);
2223
for( unsigned int i = 0; i < p->clients_count; ++ i )
2224
removeClient(p->clients[i]);
2225
p->clients_count = 0;
2226
delete[] p->clients;
2231
fprintf(stderr, "NETRootInfo::update: client list updated (%ld clients)\n",
2236
if (dirty & KDESystemTrayWindows) {
2237
bool read_ok = false;
2238
if (XGetWindowProperty(p->display, p->root, kde_net_system_tray_windows,
2239
0l, MAX_PROP_SIZE, False, XA_WINDOW, &type_ret,
2240
&format_ret, &nitems_ret, &unused, &data_ret)
2242
if (type_ret == XA_WINDOW && format_ret == 32) {
2243
Window *wins = (Window *) data_ret;
2245
qsort(wins, nitems_ret, sizeof(Window), wcmp);
2247
if (p->kde_system_tray_windows) {
2248
if (role == Client) {
2249
unsigned long new_index = 0, new_count = nitems_ret;
2250
unsigned long old_index = 0,
2251
old_count = p->kde_system_tray_windows_count;
2253
while(old_index < old_count || new_index < new_count) {
2254
if (old_index == old_count) {
2255
addSystemTrayWin(wins[new_index++]);
2256
} else if (new_index == new_count) {
2257
removeSystemTrayWin(p->kde_system_tray_windows[old_index++]);
2259
if (p->kde_system_tray_windows[old_index] <
2261
removeSystemTrayWin(p->kde_system_tray_windows[old_index++]);
2262
} else if (wins[new_index] <
2263
p->kde_system_tray_windows[old_index]) {
2264
addSystemTrayWin(wins[new_index++]);
2275
for (n = 0; n < nitems_ret; n++) {
2276
addSystemTrayWin(wins[n]);
2280
p->kde_system_tray_windows_count = nitems_ret;
2281
delete [] p->kde_system_tray_windows;
2282
p->kde_system_tray_windows =
2283
nwindup(wins, p->kde_system_tray_windows_count);
2291
for( unsigned int i = 0; i < p->kde_system_tray_windows_count; ++i )
2292
removeSystemTrayWin(p->kde_system_tray_windows[i]);
2293
p->kde_system_tray_windows_count = 0;
2294
delete [] p->kde_system_tray_windows;
2295
p->kde_system_tray_windows = NULL;
2299
if (dirty & ClientListStacking) {
2300
p->stacking_count = 0;
2301
delete[] p->stacking;
2303
if (XGetWindowProperty(p->display, p->root, net_client_list_stacking,
2304
0, MAX_PROP_SIZE, False, XA_WINDOW, &type_ret,
2305
&format_ret, &nitems_ret, &unused, &data_ret)
2307
if (type_ret == XA_WINDOW && format_ret == 32) {
2308
Window *wins = (Window *) data_ret;
2310
p->stacking_count = nitems_ret;
2311
p->stacking = nwindup(wins, p->stacking_count);
2315
fprintf(stderr,"NETRootInfo::update: client stacking updated (%ld clients)\n",
2324
if (dirty & NumberOfDesktops) {
2325
p->number_of_desktops = 0;
2327
if (XGetWindowProperty(p->display, p->root, net_number_of_desktops,
2328
0l, 1l, False, XA_CARDINAL, &type_ret, &format_ret,
2329
&nitems_ret, &unused, &data_ret)
2331
if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 1) {
2332
p->number_of_desktops = *((long *) data_ret);
2336
fprintf(stderr, "NETRootInfo::update: number of desktops = %d\n",
2337
p->number_of_desktops);
2344
if (dirty & DesktopGeometry) {
2345
p->geometry = p->rootSize;
2346
if (XGetWindowProperty(p->display, p->root, net_desktop_geometry,
2347
0l, 2l, False, XA_CARDINAL, &type_ret, &format_ret,
2348
&nitems_ret, &unused, &data_ret)
2350
if (type_ret == XA_CARDINAL && format_ret == 32 &&
2352
long *data = (long *) data_ret;
2354
p->geometry.width = data[0];
2355
p->geometry.height = data[1];
2358
fprintf(stderr, "NETRootInfo::update: desktop geometry updated\n");
2366
if (dirty & DesktopViewport) {
2367
for (int i = 0; i < p->viewport.size(); i++)
2368
p->viewport[i].x = p->viewport[i].y = 0;
2369
if (XGetWindowProperty(p->display, p->root, net_desktop_viewport,
2370
0l, 2l, False, XA_CARDINAL, &type_ret, &format_ret,
2371
&nitems_ret, &unused, &data_ret)
2373
if (type_ret == XA_CARDINAL && format_ret == 32 &&
2375
long *data = (long *) data_ret;
2379
for (d = 0, i = 0; d < n; d++) {
2380
p->viewport[d].x = data[i++];
2381
p->viewport[d].y = data[i++];
2386
"NETRootInfo::update: desktop viewport array updated (%d entries)\n",
2387
p->viewport.size());
2389
if (nitems_ret % 2 != 0) {
2391
"NETRootInfo::update(): desktop viewport array "
2392
"size not a multiple of 2\n");
2401
if (dirty & CurrentDesktop) {
2402
p->current_desktop = 0;
2403
if (XGetWindowProperty(p->display, p->root, net_current_desktop,
2404
0l, 1l, False, XA_CARDINAL, &type_ret, &format_ret,
2405
&nitems_ret, &unused, &data_ret)
2407
if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 1) {
2408
p->current_desktop = *((long *) data_ret) + 1;
2412
fprintf(stderr, "NETRootInfo::update: current desktop = %d\n",
2413
p->current_desktop);
2420
if (dirty & DesktopNames) {
2421
for( int i = 0; i < p->desktop_names.size(); ++i )
2422
delete[] p->desktop_names[ i ];
2423
p->desktop_names.reset();
2424
if (XGetWindowProperty(p->display, p->root, net_desktop_names,
2425
0l, MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
2426
&format_ret, &nitems_ret, &unused, &data_ret)
2428
if (type_ret == UTF8_STRING && format_ret == 8) {
2429
const char *d = (const char *) data_ret;
2430
unsigned int s, n, index;
2432
for (s = 0, n = 0, index = 0; n < nitems_ret; n++) {
2434
delete [] p->desktop_names[index];
2435
p->desktop_names[index++] = nstrndup((d + s), n - s + 1);
2442
fprintf(stderr, "NETRootInfo::update: desktop names array updated (%d entries)\n",
2443
p->desktop_names.size());
2450
if (dirty & ActiveWindow) {
2452
if (XGetWindowProperty(p->display, p->root, net_active_window, 0l, 1l,
2453
False, XA_WINDOW, &type_ret, &format_ret,
2454
&nitems_ret, &unused, &data_ret)
2456
if (type_ret == XA_WINDOW && format_ret == 32 && nitems_ret == 1) {
2457
p->active = *((Window *) data_ret);
2461
fprintf(stderr, "NETRootInfo::update: active window = 0x%lx\n",
2469
if (dirty & WorkArea) {
2470
p->workarea.reset();
2471
if (XGetWindowProperty(p->display, p->root, net_workarea, 0l,
2472
(p->number_of_desktops * 4), False, XA_CARDINAL,
2473
&type_ret, &format_ret, &nitems_ret, &unused,
2476
if (type_ret == XA_CARDINAL && format_ret == 32 &&
2477
nitems_ret == (unsigned) (p->number_of_desktops * 4)) {
2478
long *d = (long *) data_ret;
2480
for (i = 0, j = 0; i < p->number_of_desktops; i++) {
2481
p->workarea[i].pos.x = d[j++];
2482
p->workarea[i].pos.y = d[j++];
2483
p->workarea[i].size.width = d[j++];
2484
p->workarea[i].size.height = d[j++];
2489
fprintf(stderr, "NETRootInfo::update: work area array updated (%d entries)\n",
2490
p->workarea.size());
2498
if (dirty & SupportingWMCheck) {
2499
p->supportwindow = None;
2502
if (XGetWindowProperty(p->display, p->root, net_supporting_wm_check,
2503
0l, 1l, False, XA_WINDOW, &type_ret, &format_ret,
2504
&nitems_ret, &unused, &data_ret)
2506
if (type_ret == XA_WINDOW && format_ret == 32 && nitems_ret == 1) {
2507
p->supportwindow = *((Window *) data_ret);
2509
unsigned char *name_ret;
2510
if (XGetWindowProperty(p->display, p->supportwindow,
2511
net_wm_name, 0l, MAX_PROP_SIZE, False,
2512
UTF8_STRING, &type_ret, &format_ret,
2513
&nitems_ret, &unused, &name_ret)
2515
if (type_ret == UTF8_STRING && format_ret == 8)
2516
p->name = nstrndup((const char *) name_ret, nitems_ret);
2525
"NETRootInfo::update: supporting window manager = '%s'\n",
2533
if (dirty & VirtualRoots) {
2534
p->virtual_roots_count = 0;
2535
delete[] p->virtual_roots;
2536
p->virtual_roots = NULL;
2537
if (XGetWindowProperty(p->display, p->root, net_virtual_roots,
2538
0, MAX_PROP_SIZE, False, XA_WINDOW, &type_ret,
2539
&format_ret, &nitems_ret, &unused, &data_ret)
2541
if (type_ret == XA_WINDOW && format_ret == 32) {
2542
Window *wins = (Window *) data_ret;
2544
p->virtual_roots_count = nitems_ret;
2545
p->virtual_roots = nwindup(wins, p->virtual_roots_count);
2549
fprintf(stderr, "NETRootInfo::updated: virtual roots updated (%ld windows)\n",
2550
p->virtual_roots_count);
2557
if (dirty2 & WM2DesktopLayout) {
2558
p->desktop_layout_orientation = OrientationHorizontal;
2559
p->desktop_layout_corner = DesktopLayoutCornerTopLeft;
2560
p->desktop_layout_columns = p->desktop_layout_rows = 0;
2561
if (XGetWindowProperty(p->display, p->root, net_desktop_layout,
2562
0, MAX_PROP_SIZE, False, XA_CARDINAL, &type_ret,
2563
&format_ret, &nitems_ret, &unused, &data_ret)
2565
if (type_ret == XA_CARDINAL && format_ret == 32) {
2566
long* data = (long*) data_ret;
2567
if( nitems_ret >= 4 && data[ 3 ] >= 0 && data[ 3 ] <= 3 )
2568
p->desktop_layout_corner = (NET::DesktopLayoutCorner)data[ 3 ];
2569
if( nitems_ret >= 3 ) {
2570
if( data[ 0 ] >= 0 && data[ 0 ] <= 1 )
2571
p->desktop_layout_orientation = (NET::Orientation)data[ 0 ];
2572
p->desktop_layout_columns = data[ 1 ];
2573
p->desktop_layout_rows = data[ 2 ];
2578
fprintf(stderr, "NETRootInfo::updated: desktop layout updated (%d %d %d %d)\n",
2579
p->desktop_layout_orientation, p->desktop_layout_columns,
2580
p->desktop_layout_rows, p->desktop_layout_corner );
2587
if (dirty2 & WM2ShowingDesktop) {
2588
p->showing_desktop = false;
2589
if (XGetWindowProperty(p->display, p->root, net_showing_desktop,
2590
0, MAX_PROP_SIZE, False, XA_CARDINAL, &type_ret,
2591
&format_ret, &nitems_ret, &unused, &data_ret)
2593
if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 1) {
2594
p->showing_desktop = *((long *) data_ret);
2598
fprintf(stderr, "NETRootInfo::update: showing desktop = %d\n",
2599
p->showing_desktop);
2608
Display *NETRootInfo::x11Display() const {
2613
Window NETRootInfo::rootWindow() const {
2618
Window NETRootInfo::supportWindow() const {
2619
return p->supportwindow;
2623
const char *NETRootInfo::wmName() const {
2627
int NETRootInfo::screenNumber() const {
2633
const unsigned long* NETRootInfo::supportedProperties() const {
2634
return p->properties;
2637
const unsigned long* NETRootInfo::passedProperties() const {
2638
return role == WindowManager
2640
: p->client_properties;
2643
bool NETRootInfo::isSupported( NET::Property property ) const {
2644
return p->properties[ PROTOCOLS ] & property;
2647
bool NETRootInfo::isSupported( NET::Property2 property ) const {
2648
return p->properties[ PROTOCOLS2 ] & property;
2651
bool NETRootInfo::isSupported( NET::WindowType type ) const {
2652
return p->properties[ WINDOW_TYPES ] & type;
2655
bool NETRootInfo::isSupported( NET::State state ) const {
2656
return p->properties[ STATES ] & state;
2659
bool NETRootInfo::isSupported( NET::Action action ) const {
2660
return p->properties[ ACTIONS ] & action;
2663
const Window *NETRootInfo::clientList() const {
2668
int NETRootInfo::clientListCount() const {
2669
return p->clients_count;
2673
const Window *NETRootInfo::clientListStacking() const {
2678
int NETRootInfo::clientListStackingCount() const {
2679
return p->stacking_count;
2683
const Window *NETRootInfo::kdeSystemTrayWindows() const {
2684
return p->kde_system_tray_windows;
2688
int NETRootInfo::kdeSystemTrayWindowsCount() const {
2689
return p->kde_system_tray_windows_count;
2693
NETSize NETRootInfo::desktopGeometry(int) const {
2694
return p->geometry.width != 0 ? p->geometry : p->rootSize;
2698
NETPoint NETRootInfo::desktopViewport(int desktop) const {
2700
NETPoint pt; // set to (0,0)
2704
return p->viewport[desktop - 1];
2708
NETRect NETRootInfo::workArea(int desktop) const {
2714
return p->workarea[desktop - 1];
2718
const char *NETRootInfo::desktopName(int desktop) const {
2723
return p->desktop_names[desktop - 1];
2727
const Window *NETRootInfo::virtualRoots( ) const {
2728
return p->virtual_roots;
2732
int NETRootInfo::virtualRootsCount() const {
2733
return p->virtual_roots_count;
2737
NET::Orientation NETRootInfo::desktopLayoutOrientation() const {
2738
return p->desktop_layout_orientation;
2742
QSize NETRootInfo::desktopLayoutColumnsRows() const {
2743
return QSize( p->desktop_layout_columns, p->desktop_layout_rows );
2747
NET::DesktopLayoutCorner NETRootInfo::desktopLayoutCorner() const {
2748
return p->desktop_layout_corner;
2752
int NETRootInfo::numberOfDesktops() const {
2753
return p->number_of_desktops == 0 ? 1 : p->number_of_desktops;
2757
int NETRootInfo::currentDesktop() const {
2758
return p->current_desktop == 0 ? 1 : p->current_desktop;
2762
Window NETRootInfo::activeWindow() const {
2767
// NETWinInfo stuffs
2769
const int NETWinInfo::OnAllDesktops = NET::OnAllDesktops;
2771
NETWinInfo::NETWinInfo(Display *display, Window window, Window rootWindow,
2772
const unsigned long properties[], int properties_size,
2777
fprintf(stderr, "NETWinInfo::NETWinInfo: constructing object with role '%s'\n",
2778
(role == WindowManager) ? "WindowManager" : "Client");
2781
p = new NETWinInfoPrivate;
2784
p->display = display;
2786
p->root = rootWindow;
2787
p->mapping_state = Withdrawn;
2788
p->mapping_state_dirty = True;
2790
p->types[ 0 ] = Unknown;
2791
p->name = (char *) 0;
2792
p->visible_name = (char *) 0;
2793
p->icon_name = (char *) 0;
2794
p->visible_icon_name = (char *) 0;
2795
p->desktop = p->pid = p->handled_icons = 0;
2797
p->startup_id = NULL;
2798
p->transient_for = None;
2799
p->opacity = 0xffffffff;
2800
p->window_group = None;
2801
p->allowed_actions = 0;
2802
p->has_net_support = false;
2803
p->class_class = (char*) 0;
2804
p->class_name = (char*) 0;
2805
p->role = (char*) 0;
2806
p->client_machine = (char*) 0;
2808
// p->strut.left = p->strut.right = p->strut.top = p->strut.bottom = 0;
2809
// p->frame_strut.left = p->frame_strut.right = p->frame_strut.top =
2810
// p->frame_strut.bottom = 0;
2812
p->kde_system_tray_win_for = 0;
2815
i < PROPERTIES_SIZE;
2817
p->properties[ i ] = 0;
2818
if( properties_size > PROPERTIES_SIZE )
2819
properties_size = PROPERTIES_SIZE;
2821
i < properties_size;
2823
p->properties[ i ] = properties[ i ];
2829
if (! netwm_atoms_created) create_atoms(p->display);
2831
update(p->properties);
2835
NETWinInfo::NETWinInfo(Display *display, Window window, Window rootWindow,
2836
unsigned long properties, Role role)
2840
fprintf(stderr, "NETWinInfo::NETWinInfo: constructing object with role '%s'\n",
2841
(role == WindowManager) ? "WindowManager" : "Client");
2844
p = new NETWinInfoPrivate;
2847
p->display = display;
2849
p->root = rootWindow;
2850
p->mapping_state = Withdrawn;
2851
p->mapping_state_dirty = True;
2853
p->types[ 0 ] = Unknown;
2854
p->name = (char *) 0;
2855
p->visible_name = (char *) 0;
2856
p->icon_name = (char *) 0;
2857
p->visible_icon_name = (char *) 0;
2858
p->desktop = p->pid = p->handled_icons = 0;
2860
p->startup_id = NULL;
2861
p->transient_for = None;
2862
p->opacity = 0xffffffff;
2863
p->window_group = None;
2864
p->allowed_actions = 0;
2865
p->has_net_support = false;
2866
p->class_class = (char*) 0;
2867
p->class_name = (char*) 0;
2868
p->role = (char*) 0;
2869
p->client_machine = (char*) 0;
2871
// p->strut.left = p->strut.right = p->strut.top = p->strut.bottom = 0;
2872
// p->frame_strut.left = p->frame_strut.right = p->frame_strut.top =
2873
// p->frame_strut.bottom = 0;
2875
p->kde_system_tray_win_for = 0;
2878
i < PROPERTIES_SIZE;
2880
p->properties[ i ] = 0;
2881
p->properties[ PROTOCOLS ] = properties;
2887
if (! netwm_atoms_created) create_atoms(p->display);
2889
update(p->properties);
2893
NETWinInfo::NETWinInfo(const NETWinInfo &wininfo) {
2899
NETWinInfo::~NETWinInfo() {
2902
if (! p->ref) delete p;
2906
// assignment operator
2908
const NETWinInfo &NETWinInfo::operator=(const NETWinInfo &wininfo) {
2911
fprintf(stderr, "NETWinInfo::operator=()\n");
2914
if (p != wininfo.p) {
2917
if (! p->ref) delete p;
2921
role = wininfo.role;
2928
void NETWinInfo::setIcon(NETIcon icon, Bool replace) {
2929
setIconInternal( p->icons, p->icon_count, net_wm_icon, icon, replace );
2932
void NETWinInfo::setIconInternal(NETRArray<NETIcon>& icons, int& icon_count, Atom property, NETIcon icon, Bool replace) {
2933
if (role != Client) return;
2935
int proplen, i, sz, j;
2939
for (i = 0; i < icons.size(); i++) {
2940
delete [] icons[i].data;
2942
icons[i].size.width = 0;
2943
icons[i].size.height = 0;
2950
icons[icon_count] = icon;
2953
// do a deep copy, we want to own the data
2954
NETIcon &ni = icons[icon_count - 1];
2955
sz = ni.size.width * ni.size.height;
2956
CARD32 *d = new CARD32[sz];
2957
ni.data = (unsigned char *) d;
2958
memcpy(d, icon.data, sz * sizeof(CARD32));
2960
// compute property length
2961
for (i = 0, proplen = 0; i < icon_count; i++) {
2962
proplen += 2 + (icons[i].size.width *
2963
icons[i].size.height);
2967
long *prop = new long[proplen], *pprop = prop;
2968
for (i = 0; i < icon_count; i++) {
2969
// copy size into property
2970
*pprop++ = icons[i].size.width;
2971
*pprop++ = icons[i].size.height;
2973
// copy data into property
2974
sz = (icons[i].size.width * icons[i].size.height);
2975
d32 = (CARD32 *) icons[i].data;
2976
for (j = 0; j < sz; j++) *pprop++ = *d32++;
2979
XChangeProperty(p->display, p->window, property, XA_CARDINAL, 32,
2980
PropModeReplace, (unsigned char *) prop, proplen);
2986
void NETWinInfo::setIconGeometry(NETRect geometry) {
2987
if (role != Client) return;
2989
p->icon_geom = geometry;
2991
if( geometry.size.width == 0 ) // empty
2992
XDeleteProperty(p->display, p->window, net_wm_icon_geometry);
2995
data[0] = geometry.pos.x;
2996
data[1] = geometry.pos.y;
2997
data[2] = geometry.size.width;
2998
data[3] = geometry.size.height;
3000
XChangeProperty(p->display, p->window, net_wm_icon_geometry, XA_CARDINAL,
3001
32, PropModeReplace, (unsigned char *) data, 4);
3006
void NETWinInfo::setExtendedStrut(const NETExtendedStrut& extended_strut ) {
3007
if (role != Client) return;
3009
p->extended_strut = extended_strut;
3012
data[0] = extended_strut.left_width;
3013
data[1] = extended_strut.right_width;
3014
data[2] = extended_strut.top_width;
3015
data[3] = extended_strut.bottom_width;
3016
data[4] = extended_strut.left_start;
3017
data[5] = extended_strut.left_end;
3018
data[6] = extended_strut.right_start;
3019
data[7] = extended_strut.right_end;
3020
data[8] = extended_strut.top_start;
3021
data[9] = extended_strut.top_end;
3022
data[10] = extended_strut.bottom_start;
3023
data[11] = extended_strut.bottom_end;
3025
XChangeProperty(p->display, p->window, net_wm_extended_strut, XA_CARDINAL, 32,
3026
PropModeReplace, (unsigned char *) data, 12);
3030
void NETWinInfo::setStrut(NETStrut strut) {
3031
if (role != Client) return;
3036
data[0] = strut.left;
3037
data[1] = strut.right;
3038
data[2] = strut.top;
3039
data[3] = strut.bottom;
3041
XChangeProperty(p->display, p->window, net_wm_strut, XA_CARDINAL, 32,
3042
PropModeReplace, (unsigned char *) data, 4);
3046
void NETWinInfo::setState(unsigned long state, unsigned long mask) {
3047
if (p->mapping_state_dirty)
3050
// setState() needs to know the current state, so read it even if not requested
3051
if( ( p->properties[ PROTOCOLS ] & WMState ) == 0 ) {
3052
p->properties[ PROTOCOLS ] |= WMState;
3053
unsigned long props[ PROPERTIES_SIZE ] = { WMState, 0 };
3054
assert( PROPERTIES_SIZE == 2 ); // add elements above
3056
p->properties[ PROTOCOLS ] &= ~WMState;
3059
if (role == Client && p->mapping_state != Withdrawn) {
3062
fprintf(stderr, "NETWinInfo::setState (0x%lx, 0x%lx) (Client)\n",
3064
#endif // NETWMDEBUG
3067
e.xclient.type = ClientMessage;
3068
e.xclient.message_type = net_wm_state;
3069
e.xclient.display = p->display;
3070
e.xclient.window = p->window;
3071
e.xclient.format = 32;
3072
e.xclient.data.l[3] = 0l;
3073
e.xclient.data.l[4] = 0l;
3075
if ((mask & Modal) && ((p->state & Modal) != (state & Modal))) {
3076
e.xclient.data.l[0] = (state & Modal) ? 1 : 0;
3077
e.xclient.data.l[1] = net_wm_state_modal;
3078
e.xclient.data.l[2] = 0l;
3080
XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3083
if ((mask & Sticky) && ((p->state & Sticky) != (state & Sticky))) {
3084
e.xclient.data.l[0] = (state & Sticky) ? 1 : 0;
3085
e.xclient.data.l[1] = net_wm_state_sticky;
3086
e.xclient.data.l[2] = 0l;
3088
XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3091
if ((mask & Max) && (( (p->state&mask) & Max) != (state & Max))) {
3093
unsigned long wishstate = (p->state & ~mask) | (state & mask);
3094
if ( ( (wishstate & MaxHoriz) != (p->state & MaxHoriz) )
3095
&& ( (wishstate & MaxVert) != (p->state & MaxVert) ) ) {
3096
if ( (wishstate & Max) == Max ) {
3097
e.xclient.data.l[0] = 1;
3098
e.xclient.data.l[1] = net_wm_state_max_horiz;
3099
e.xclient.data.l[2] = net_wm_state_max_vert;
3100
XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3101
} else if ( (wishstate & Max) == 0 ) {
3102
e.xclient.data.l[0] = 0;
3103
e.xclient.data.l[1] = net_wm_state_max_horiz;
3104
e.xclient.data.l[2] = net_wm_state_max_vert;
3105
XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3107
e.xclient.data.l[0] = ( wishstate & MaxHoriz ) ? 1 : 0;
3108
e.xclient.data.l[1] = net_wm_state_max_horiz;
3109
e.xclient.data.l[2] = 0;
3110
XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3111
e.xclient.data.l[0] = ( wishstate & MaxVert ) ? 1 : 0;
3112
e.xclient.data.l[1] = net_wm_state_max_vert;
3113
e.xclient.data.l[2] = 0;
3114
XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3116
} else if ( (wishstate & MaxVert) != (p->state & MaxVert) ) {
3117
e.xclient.data.l[0] = ( wishstate & MaxVert ) ? 1 : 0;
3118
e.xclient.data.l[1] = net_wm_state_max_vert;
3119
e.xclient.data.l[2] = 0;
3120
XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3121
} else if ( (wishstate & MaxHoriz) != (p->state & MaxHoriz) ) {
3122
e.xclient.data.l[0] = ( wishstate & MaxHoriz ) ? 1 : 0;
3123
e.xclient.data.l[1] = net_wm_state_max_horiz;
3124
e.xclient.data.l[2] = 0;
3125
XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3129
if ((mask & Shaded) && ((p->state & Shaded) != (state & Shaded))) {
3130
e.xclient.data.l[0] = (state & Shaded) ? 1 : 0;
3131
e.xclient.data.l[1] = net_wm_state_shaded;
3132
e.xclient.data.l[2] = 0l;
3134
XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3137
if ((mask & SkipTaskbar) &&
3138
((p->state & SkipTaskbar) != (state & SkipTaskbar))) {
3139
e.xclient.data.l[0] = (state & SkipTaskbar) ? 1 : 0;
3140
e.xclient.data.l[1] = net_wm_state_skip_taskbar;
3141
e.xclient.data.l[2] = 0l;
3143
XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3146
if ((mask & SkipPager) &&
3147
((p->state & SkipPager) != (state & SkipPager))) {
3148
e.xclient.data.l[0] = (state & SkipPager) ? 1 : 0;
3149
e.xclient.data.l[1] = net_wm_state_skip_pager;
3150
e.xclient.data.l[2] = 0l;
3152
XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3155
if ((mask & Hidden) &&
3156
((p->state & Hidden) != (state & Hidden))) {
3157
e.xclient.data.l[0] = (state & Hidden) ? 1 : 0;
3158
e.xclient.data.l[1] = net_wm_state_hidden;
3159
e.xclient.data.l[2] = 0l;
3161
XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3164
if ((mask & FullScreen) &&
3165
((p->state & FullScreen) != (state & FullScreen))) {
3166
e.xclient.data.l[0] = (state & FullScreen) ? 1 : 0;
3167
e.xclient.data.l[1] = net_wm_state_fullscreen;
3168
e.xclient.data.l[2] = 0l;
3170
XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3173
if ((mask & KeepAbove) &&
3174
((p->state & KeepAbove) != (state & KeepAbove))) {
3175
e.xclient.data.l[0] = (state & KeepAbove) ? 1 : 0;
3176
e.xclient.data.l[1] = net_wm_state_above;
3177
e.xclient.data.l[2] = 0l;
3179
XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3182
if ((mask & KeepBelow) &&
3183
((p->state & KeepBelow) != (state & KeepBelow))) {
3184
e.xclient.data.l[0] = (state & KeepBelow) ? 1 : 0;
3185
e.xclient.data.l[1] = net_wm_state_below;
3186
e.xclient.data.l[2] = 0l;
3188
XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3191
if ((mask & StaysOnTop) && ((p->state & StaysOnTop) != (state & StaysOnTop))) {
3192
e.xclient.data.l[0] = (state & StaysOnTop) ? 1 : 0;
3193
e.xclient.data.l[1] = net_wm_state_stays_on_top;
3194
e.xclient.data.l[2] = 0l;
3196
XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3199
if ((mask & DemandsAttention) &&
3200
((p->state & DemandsAttention) != (state & DemandsAttention))) {
3201
e.xclient.data.l[0] = (state & DemandsAttention) ? 1 : 0;
3202
e.xclient.data.l[1] = net_wm_state_demands_attention;
3203
e.xclient.data.l[2] = 0l;
3205
XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3216
if (p->state & Modal) data[count++] = net_wm_state_modal;
3217
if (p->state & MaxVert) data[count++] = net_wm_state_max_vert;
3218
if (p->state & MaxHoriz) data[count++] = net_wm_state_max_horiz;
3219
if (p->state & Shaded) data[count++] = net_wm_state_shaded;
3220
if (p->state & Hidden) data[count++] = net_wm_state_hidden;
3221
if (p->state & FullScreen) data[count++] = net_wm_state_fullscreen;
3222
if (p->state & DemandsAttention) data[count++] = net_wm_state_demands_attention;
3225
if (p->state & KeepAbove) data[count++] = net_wm_state_above;
3226
if (p->state & KeepBelow) data[count++] = net_wm_state_below;
3227
if (p->state & StaysOnTop) data[count++] = net_wm_state_stays_on_top;
3228
if (p->state & Sticky) data[count++] = net_wm_state_sticky;
3229
if (p->state & SkipTaskbar) data[count++] = net_wm_state_skip_taskbar;
3230
if (p->state & SkipPager) data[count++] = net_wm_state_skip_pager;
3233
fprintf(stderr, "NETWinInfo::setState: setting state property (%d)\n", count);
3234
for (int i = 0; i < count; i++) {
3235
char* data_ret = XGetAtomName(p->display, (Atom) data[i]);
3236
fprintf(stderr, "NETWinInfo::setState: state %ld '%s'\n",
3244
XChangeProperty(p->display, p->window, net_wm_state, XA_ATOM, 32,
3245
PropModeReplace, (unsigned char *) data, count);
3250
void NETWinInfo::setWindowType(WindowType type) {
3251
if (role != Client) return;
3258
// spec extension: override window type. we must comply with the spec
3259
// and provide a fall back (normal seems best)
3260
data[0] = kde_net_wm_window_type_override;
3261
data[1] = net_wm_window_type_normal;
3266
data[0] = net_wm_window_type_dialog;
3272
data[0] = net_wm_window_type_menu;
3278
// spec extension: override window type. we must comply with the spec
3279
// and provide a fall back (dock seems best)
3280
data[0] = kde_net_wm_window_type_topmenu;
3281
data[1] = net_wm_window_type_dock;
3286
data[0] = net_wm_window_type_toolbar;
3292
data[0] = net_wm_window_type_dock;
3298
data[0] = net_wm_window_type_desktop;
3304
data[0] = net_wm_window_type_utility;
3305
data[1] = net_wm_window_type_dialog; // fallback for old netwm version
3310
data[0] = net_wm_window_type_splash;
3311
data[1] = net_wm_window_type_dock; // fallback (dock seems best)
3316
data[0] = net_wm_window_type_dropdown_menu;
3322
data[0] = net_wm_window_type_popup_menu;
3328
data[0] = net_wm_window_type_tooltip;
3334
data[0] = net_wm_window_type_notification;
3340
data[0] = net_wm_window_type_combobox;
3346
data[0] = net_wm_window_type_dnd;
3353
data[0] = net_wm_window_type_normal;
3359
XChangeProperty(p->display, p->window, net_wm_window_type, XA_ATOM, 32,
3360
PropModeReplace, (unsigned char *) &data, len);
3364
void NETWinInfo::setName(const char *name) {
3365
if (role != Client) return;
3368
p->name = nstrdup(name);
3369
if( p->name[ 0 ] != '\0' )
3370
XChangeProperty(p->display, p->window, net_wm_name, UTF8_STRING, 8,
3371
PropModeReplace, (unsigned char *) p->name,
3374
XDeleteProperty(p->display, p->window, net_wm_name);
3378
void NETWinInfo::setVisibleName(const char *visibleName) {
3379
if (role != WindowManager) return;
3381
delete [] p->visible_name;
3382
p->visible_name = nstrdup(visibleName);
3383
if( p->visible_name[ 0 ] != '\0' )
3384
XChangeProperty(p->display, p->window, net_wm_visible_name, UTF8_STRING, 8,
3385
PropModeReplace, (unsigned char *) p->visible_name,
3386
strlen(p->visible_name));
3388
XDeleteProperty(p->display, p->window, net_wm_visible_name);
3392
void NETWinInfo::setIconName(const char *iconName) {
3393
if (role != Client) return;
3395
delete [] p->icon_name;
3396
p->icon_name = nstrdup(iconName);
3397
if( p->icon_name[ 0 ] != '\0' )
3398
XChangeProperty(p->display, p->window, net_wm_icon_name, UTF8_STRING, 8,
3399
PropModeReplace, (unsigned char *) p->icon_name,
3400
strlen(p->icon_name));
3402
XDeleteProperty(p->display, p->window, net_wm_icon_name);
3406
void NETWinInfo::setVisibleIconName(const char *visibleIconName) {
3407
if (role != WindowManager) return;
3409
delete [] p->visible_icon_name;
3410
p->visible_icon_name = nstrdup(visibleIconName);
3411
if( p->visible_icon_name[ 0 ] != '\0' )
3412
XChangeProperty(p->display, p->window, net_wm_visible_icon_name, UTF8_STRING, 8,
3413
PropModeReplace, (unsigned char *) p->visible_icon_name,
3414
strlen(p->visible_icon_name));
3416
XDeleteProperty(p->display, p->window, net_wm_visible_icon_name);
3420
void NETWinInfo::setDesktop(int desktop) {
3421
if (p->mapping_state_dirty)
3424
if (role == Client && p->mapping_state != Withdrawn) {
3425
// we only send a ClientMessage if we are 1) a client and 2) managed
3428
return; // we can't do that while being managed
3432
e.xclient.type = ClientMessage;
3433
e.xclient.message_type = net_wm_desktop;
3434
e.xclient.display = p->display;
3435
e.xclient.window = p->window;
3436
e.xclient.format = 32;
3437
e.xclient.data.l[0] = desktop == OnAllDesktops ? OnAllDesktops : desktop - 1;
3438
e.xclient.data.l[1] = 0l;
3439
e.xclient.data.l[2] = 0l;
3440
e.xclient.data.l[3] = 0l;
3441
e.xclient.data.l[4] = 0l;
3443
XSendEvent(p->display, p->root, False, netwm_sendevent_mask, &e);
3445
// otherwise we just set or remove the property directly
3446
p->desktop = desktop;
3449
if ( d != OnAllDesktops ) {
3451
XDeleteProperty( p->display, p->window, net_wm_desktop );
3458
XChangeProperty(p->display, p->window, net_wm_desktop, XA_CARDINAL, 32,
3459
PropModeReplace, (unsigned char *) &d, 1);
3464
void NETWinInfo::setPid(int pid) {
3465
if (role != Client) return;
3469
XChangeProperty(p->display, p->window, net_wm_pid, XA_CARDINAL, 32,
3470
PropModeReplace, (unsigned char *) &d, 1);
3474
void NETWinInfo::setHandledIcons(Bool handled) {
3475
if (role != Client) return;
3477
p->handled_icons = handled;
3479
XChangeProperty(p->display, p->window, net_wm_handled_icons, XA_CARDINAL, 32,
3480
PropModeReplace, (unsigned char *) &d, 1);
3483
void NETWinInfo::setStartupId(const char* id) {
3484
if (role != Client) return;
3486
delete[] p->startup_id;
3487
p->startup_id = nstrdup(id);
3488
XChangeProperty(p->display, p->window, net_startup_id, UTF8_STRING, 8,
3489
PropModeReplace, reinterpret_cast< unsigned char* >( p->startup_id ),
3490
strlen( p->startup_id ));
3493
void NETWinInfo::setOpacity(unsigned long opacity) {
3494
// if (role != Client) return;
3496
p->opacity = opacity;
3497
XChangeProperty(p->display, p->window, net_wm_window_opacity, XA_CARDINAL, 32,
3498
PropModeReplace, reinterpret_cast< unsigned char* >( &p->opacity ), 1);
3501
void NETWinInfo::setAllowedActions( unsigned long actions ) {
3502
if( role != WindowManager )
3507
p->allowed_actions = actions;
3508
if (p->allowed_actions & ActionMove) data[count++] = net_wm_action_move;
3509
if (p->allowed_actions & ActionResize) data[count++] = net_wm_action_resize;
3510
if (p->allowed_actions & ActionMinimize) data[count++] = net_wm_action_minimize;
3511
if (p->allowed_actions & ActionShade) data[count++] = net_wm_action_shade;
3512
if (p->allowed_actions & ActionStick) data[count++] = net_wm_action_stick;
3513
if (p->allowed_actions & ActionMaxVert) data[count++] = net_wm_action_max_vert;
3514
if (p->allowed_actions & ActionMaxHoriz) data[count++] = net_wm_action_max_horiz;
3515
if (p->allowed_actions & ActionFullScreen) data[count++] = net_wm_action_fullscreen;
3516
if (p->allowed_actions & ActionChangeDesktop) data[count++] = net_wm_action_change_desk;
3517
if (p->allowed_actions & ActionClose) data[count++] = net_wm_action_close;
3520
fprintf(stderr, "NETWinInfo::setAllowedActions: setting property (%d)\n", count);
3521
for (int i = 0; i < count; i++) {
3522
char* data_ret = XGetAtomName(p->display, (Atom) data[i]);
3523
fprintf(stderr, "NETWinInfo::setAllowedActions: action %ld '%s'\n",
3530
XChangeProperty(p->display, p->window, net_wm_allowed_actions, XA_ATOM, 32,
3531
PropModeReplace, (unsigned char *) data, count);
3534
void NETWinInfo::setKDESystemTrayWinFor(Window window) {
3535
if (role != Client) return;
3537
p->kde_system_tray_win_for = window;
3538
XChangeProperty(p->display, p->window, kde_net_wm_system_tray_window_for,
3539
XA_WINDOW, 32, PropModeReplace,
3540
(unsigned char *) &(p->kde_system_tray_win_for), 1);
3544
void NETWinInfo::setKDEFrameStrut(NETStrut strut) {
3545
setFrameExtents( strut );
3548
void NETWinInfo::setFrameExtents(NETStrut strut) {
3549
if (role != WindowManager) return;
3551
p->frame_strut = strut;
3557
d[3] = strut.bottom;
3559
XChangeProperty(p->display, p->window, net_frame_extents, XA_CARDINAL, 32,
3560
PropModeReplace, (unsigned char *) d, 4);
3561
XChangeProperty(p->display, p->window, kde_net_wm_frame_strut, XA_CARDINAL, 32,
3562
PropModeReplace, (unsigned char *) d, 4);
3566
void NETWinInfo::kdeGeometry(NETRect& frame, NETRect& window) {
3567
if (p->win_geom.size.width == 0 || p->win_geom.size.height == 0) {
3570
unsigned int w, h, junk;
3571
XGetGeometry(p->display, p->window, &unused, &x, &y, &w, &h, &junk, &junk);
3572
XTranslateCoordinates(p->display, p->window, p->root, 0, 0, &x, &y, &unused
3575
p->win_geom.pos.x = x;
3576
p->win_geom.pos.y = y;
3578
p->win_geom.size.width = w;
3579
p->win_geom.size.height = h;
3581
// TODO try to work also without _KDE_NET_WM_FRAME_STRUT
3582
window = p->win_geom;
3584
frame.pos.x = window.pos.x - p->frame_strut.left;
3585
frame.pos.y = window.pos.y - p->frame_strut.top;
3586
frame.size.width = window.size.width + p->frame_strut.left + p->frame_strut.right;
3587
frame.size.height = window.size.height + p->frame_strut.top + p->frame_strut.bottom;
3591
NETIcon NETWinInfo::icon(int width, int height) const {
3592
return iconInternal( p->icons, p->icon_count, width, height );
3595
NETIcon NETWinInfo::iconInternal(NETRArray<NETIcon>& icons, int icon_count, int width, int height) const {
3598
if ( !icon_count ) {
3599
result.size.width = 0;
3600
result.size.height = 0;
3605
// find the largest icon
3607
for (int i = 1; i < icons.size(); i++) {
3608
if( icons[i].size.width >= result.size.width &&
3609
icons[i].size.height >= result.size.height )
3613
// return the largest icon if w and h are -1
3614
if (width == -1 && height == -1) return result;
3616
// find the icon that's closest in size to w x h...
3617
for (int i = 0; i < icons.size(); i++) {
3618
if ((icons[i].size.width >= width &&
3619
icons[i].size.width < result.size.width) &&
3620
(icons[i].size.height >= height &&
3621
icons[i].size.height < result.size.height))
3628
void NETWinInfo::setUserTime( Time time ) {
3629
if (role != Client) return;
3631
p->user_time = time;
3633
XChangeProperty(p->display, p->window, net_wm_user_time, XA_CARDINAL, 32,
3634
PropModeReplace, (unsigned char *) &d, 1);
3638
unsigned long NETWinInfo::event(XEvent *ev )
3640
unsigned long props[ 1 ];
3641
event( ev, props, 1 );
3645
void NETWinInfo::event(XEvent *event, unsigned long* properties, int properties_size ) {
3646
unsigned long props[ PROPERTIES_SIZE ] = { 0, 0 };
3647
assert( PROPERTIES_SIZE == 2 ); // add elements above
3648
unsigned long& dirty = props[ PROTOCOLS ];
3649
unsigned long& dirty2 = props[ PROTOCOLS2 ];
3650
bool do_update = false;
3652
if (role == WindowManager && event->type == ClientMessage &&
3653
event->xclient.format == 32) {
3656
fprintf(stderr, "NETWinInfo::event: handling ClientMessage event\n");
3657
#endif // NETWMDEBUG
3659
if (event->xclient.message_type == net_wm_state) {
3662
// we need to generate a change mask
3666
"NETWinInfo::event: state client message, getting new state/mask\n");
3670
long state = 0, mask = 0;
3672
for (i = 1; i < 3; i++) {
3674
char* debug_txt = XGetAtomName(p->display, (Atom) event->xclient.data.l[i]);
3675
fprintf(stderr, "NETWinInfo::event: message %ld '%s'\n",
3676
event->xclient.data.l[i], debug_txt );
3681
if ((Atom) event->xclient.data.l[i] == net_wm_state_modal)
3683
else if ((Atom) event->xclient.data.l[i] == net_wm_state_sticky)
3685
else if ((Atom) event->xclient.data.l[i] == net_wm_state_max_vert)
3687
else if ((Atom) event->xclient.data.l[i] == net_wm_state_max_horiz)
3689
else if ((Atom) event->xclient.data.l[i] == net_wm_state_shaded)
3691
else if ((Atom) event->xclient.data.l[i] == net_wm_state_skip_taskbar)
3692
mask |= SkipTaskbar;
3693
else if ((Atom) event->xclient.data.l[i] == net_wm_state_skip_pager)
3695
else if ((Atom) event->xclient.data.l[i] == net_wm_state_hidden)
3697
else if ((Atom) event->xclient.data.l[i] == net_wm_state_fullscreen)
3699
else if ((Atom) event->xclient.data.l[i] == net_wm_state_above)
3701
else if ((Atom) event->xclient.data.l[i] == net_wm_state_below)
3703
else if ((Atom) event->xclient.data.l[i] == net_wm_state_demands_attention)
3704
mask |= DemandsAttention;
3705
else if ((Atom) event->xclient.data.l[i] == net_wm_state_stays_on_top)
3709
// when removing, we just leave newstate == 0
3710
switch (event->xclient.data.l[0]) {
3712
// to set... the change state should be the same as the mask
3717
// to toggle, we need to xor the current state with the new state
3718
state = (p->state & mask) ^ mask;
3722
// to clear state, the new state should stay zero
3727
fprintf(stderr, "NETWinInfo::event: calling changeState(%lx, %lx)\n",
3731
changeState(state, mask);
3732
} else if (event->xclient.message_type == net_wm_desktop) {
3735
if( event->xclient.data.l[0] == OnAllDesktops )
3736
changeDesktop( OnAllDesktops );
3738
changeDesktop(event->xclient.data.l[0] + 1);
3742
if (event->type == PropertyNotify) {
3745
fprintf(stderr, "NETWinInfo::event: handling PropertyNotify event\n");
3751
Bool compaction = False;
3755
fprintf(stderr, "NETWinInfo::event: loop fire\n");
3758
if (pe.xproperty.atom == net_wm_name)
3760
else if (pe.xproperty.atom == net_wm_visible_name)
3761
dirty |= WMVisibleName;
3762
else if (pe.xproperty.atom == net_wm_desktop)
3764
else if (pe.xproperty.atom == net_wm_window_type)
3765
dirty |=WMWindowType;
3766
else if (pe.xproperty.atom == net_wm_state)
3768
else if (pe.xproperty.atom == net_wm_strut)
3770
else if (pe.xproperty.atom == net_wm_extended_strut)
3771
dirty2 |= WM2ExtendedStrut;
3772
else if (pe.xproperty.atom == net_wm_icon_geometry)
3773
dirty |= WMIconGeometry;
3774
else if (pe.xproperty.atom == net_wm_icon)
3776
else if (pe.xproperty.atom == net_wm_pid)
3778
else if (pe.xproperty.atom == net_wm_handled_icons)
3779
dirty |= WMHandledIcons;
3780
else if (pe.xproperty.atom == net_startup_id)
3781
dirty2 |= WM2StartupId;
3782
else if (pe.xproperty.atom == net_wm_window_opacity)
3783
dirty2 |= WM2Opacity;
3784
else if (pe.xproperty.atom == net_wm_allowed_actions)
3785
dirty2 |= WM2AllowedActions;
3786
else if (pe.xproperty.atom == kde_net_wm_system_tray_window_for)
3787
dirty |= WMKDESystemTrayWinFor;
3788
else if (pe.xproperty.atom == xa_wm_state)
3790
else if (pe.xproperty.atom == net_frame_extents)
3791
dirty |= WMFrameExtents;
3792
else if (pe.xproperty.atom == kde_net_wm_frame_strut)
3793
dirty |= WMKDEFrameStrut;
3794
else if (pe.xproperty.atom == net_wm_icon_name)
3795
dirty |= WMIconName;
3796
else if (pe.xproperty.atom == net_wm_visible_icon_name)
3797
dirty |= WMVisibleIconName;
3798
else if (pe.xproperty.atom == net_wm_user_time)
3799
dirty2 |= WM2UserTime;
3800
else if (pe.xproperty.atom == XA_WM_HINTS)
3801
dirty2 |= WM2GroupLeader;
3802
else if (pe.xproperty.atom == XA_WM_TRANSIENT_FOR)
3803
dirty2 |= WM2TransientFor;
3804
else if (pe.xproperty.atom == XA_WM_CLASS)
3805
dirty2 |= WM2WindowClass;
3806
else if (pe.xproperty.atom == wm_window_role)
3807
dirty2 |= WM2WindowRole;
3808
else if (pe.xproperty.atom == XA_WM_CLIENT_MACHINE)
3809
dirty2 |= WM2ClientMachine;
3813
fprintf(stderr, "NETWinInfo::event: putting back event and breaking\n");
3817
XPutBackEvent(p->display, &pe);
3821
if (XCheckTypedWindowEvent(p->display, p->window, PropertyNotify, &pe) )
3828
} else if (event->type == ConfigureNotify) {
3831
fprintf(stderr, "NETWinInfo::event: handling ConfigureNotify event\n");
3834
dirty |= WMGeometry;
3836
// update window geometry
3837
p->win_geom.pos.x = event->xconfigure.x;
3838
p->win_geom.pos.y = event->xconfigure.y;
3839
p->win_geom.size.width = event->xconfigure.width;
3840
p->win_geom.size.height = event->xconfigure.height;
3846
if( properties_size > PROPERTIES_SIZE )
3847
properties_size = PROPERTIES_SIZE;
3849
i < properties_size;
3851
properties[ i ] = props[ i ];
3854
void NETWinInfo::updateWMState() {
3855
unsigned long props[ PROPERTIES_SIZE ] = { XAWMState, 0 };
3856
assert( PROPERTIES_SIZE == 2 ); // add elements above
3860
void NETWinInfo::update(const unsigned long dirty_props[]) {
3863
unsigned long nitems_ret, unused;
3864
unsigned char *data_ret;
3865
unsigned long props[ PROPERTIES_SIZE ];
3867
i < PROPERTIES_SIZE;
3869
props[ i ] = dirty_props[ i ] & p->properties[ i ];
3870
const unsigned long& dirty = props[ PROTOCOLS ];
3871
const unsigned long& dirty2 = props[ PROTOCOLS2 ];
3873
// we *always* want to update WM_STATE if set in dirty_props
3874
if( dirty_props[ PROTOCOLS ] & XAWMState )
3875
props[ PROTOCOLS ] |= XAWMState;
3877
if (dirty & XAWMState) {
3878
p->mapping_state = Withdrawn;
3879
if (XGetWindowProperty(p->display, p->window, xa_wm_state, 0l, 1l,
3880
False, xa_wm_state, &type_ret, &format_ret,
3881
&nitems_ret, &unused, &data_ret)
3883
if (type_ret == xa_wm_state && format_ret == 32 &&
3885
long *state = (long *) data_ret;
3889
p->mapping_state = Iconic;
3892
p->mapping_state = Visible;
3894
case WithdrawnState:
3896
p->mapping_state = Withdrawn;
3900
p->mapping_state_dirty = False;
3907
if (dirty & WMState) {
3909
if (XGetWindowProperty(p->display, p->window, net_wm_state, 0l, 2048l,
3910
False, XA_ATOM, &type_ret, &format_ret,
3911
&nitems_ret, &unused, &data_ret)
3913
if (type_ret == XA_ATOM && format_ret == 32 && nitems_ret > 0) {
3914
// determine window state
3916
fprintf(stderr, "NETWinInfo::update: updating window state (%ld)\n",
3920
long *states = (long *) data_ret;
3921
unsigned long count;
3923
for (count = 0; count < nitems_ret; count++) {
3925
char* data_ret = XGetAtomName(p->display, (Atom) states[count]);
3927
"NETWinInfo::update: adding window state %ld '%s'\n",
3928
states[count], data_ret );
3933
if ((Atom) states[count] == net_wm_state_modal)
3935
else if ((Atom) states[count] == net_wm_state_sticky)
3937
else if ((Atom) states[count] == net_wm_state_max_vert)
3938
p->state |= MaxVert;
3939
else if ((Atom) states[count] == net_wm_state_max_horiz)
3940
p->state |= MaxHoriz;
3941
else if ((Atom) states[count] == net_wm_state_shaded)
3943
else if ((Atom) states[count] == net_wm_state_skip_taskbar)
3944
p->state |= SkipTaskbar;
3945
else if ((Atom) states[count] == net_wm_state_skip_pager)
3946
p->state |= SkipPager;
3947
else if ((Atom) states[count] == net_wm_state_hidden)
3949
else if ((Atom) states[count] == net_wm_state_fullscreen)
3950
p->state |= FullScreen;
3951
else if ((Atom) states[count] == net_wm_state_above)
3952
p->state |= KeepAbove;
3953
else if ((Atom) states[count] == net_wm_state_below)
3954
p->state |= KeepBelow;
3955
else if ((Atom) states[count] == net_wm_state_demands_attention)
3956
p->state |= DemandsAttention;
3957
else if ((Atom) states[count] == net_wm_state_stays_on_top)
3958
p->state |= StaysOnTop;
3966
if (dirty & WMDesktop) {
3968
if (XGetWindowProperty(p->display, p->window, net_wm_desktop, 0l, 1l,
3969
False, XA_CARDINAL, &type_ret,
3970
&format_ret, &nitems_ret,
3973
if (type_ret == XA_CARDINAL && format_ret == 32 &&
3975
p->desktop = *((long *) data_ret);
3976
if ((signed) p->desktop != OnAllDesktops)
3979
if ( p->desktop == 0 )
3980
p->desktop = OnAllDesktops;
3987
if (dirty & WMName) {
3990
if (XGetWindowProperty(p->display, p->window, net_wm_name, 0l,
3991
MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
3992
&format_ret, &nitems_ret, &unused, &data_ret)
3994
if (type_ret == UTF8_STRING && format_ret == 8 && nitems_ret > 0) {
3995
p->name = nstrndup((const char *) data_ret, nitems_ret);
4003
if (dirty & WMVisibleName) {
4004
delete[] p->visible_name;
4005
p->visible_name = NULL;
4006
if (XGetWindowProperty(p->display, p->window, net_wm_visible_name, 0l,
4007
MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
4008
&format_ret, &nitems_ret, &unused, &data_ret)
4010
if (type_ret == UTF8_STRING && format_ret == 8 && nitems_ret > 0) {
4011
p->visible_name = nstrndup((const char *) data_ret, nitems_ret);
4019
if (dirty & WMIconName) {
4020
delete[] p->icon_name;
4021
p->icon_name = NULL;
4022
if (XGetWindowProperty(p->display, p->window, net_wm_icon_name, 0l,
4023
MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
4024
&format_ret, &nitems_ret, &unused, &data_ret)
4026
if (type_ret == UTF8_STRING && format_ret == 8 && nitems_ret > 0) {
4027
p->icon_name = nstrndup((const char *) data_ret, nitems_ret);
4035
if (dirty & WMVisibleIconName)
4037
delete[] p->visible_icon_name;
4038
p->visible_icon_name = NULL;
4039
if (XGetWindowProperty(p->display, p->window, net_wm_visible_icon_name, 0l,
4040
MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
4041
&format_ret, &nitems_ret, &unused, &data_ret)
4043
if (type_ret == UTF8_STRING && format_ret == 8 && nitems_ret > 0) {
4044
p->visible_icon_name = nstrndup((const char *) data_ret, nitems_ret);
4052
if (dirty & WMWindowType) {
4054
p->types[ 0 ] = Unknown;
4055
p->has_net_support = false;
4056
if (XGetWindowProperty(p->display, p->window, net_wm_window_type, 0l, 2048l,
4057
False, XA_ATOM, &type_ret, &format_ret,
4058
&nitems_ret, &unused, &data_ret)
4060
if (type_ret == XA_ATOM && format_ret == 32 && nitems_ret > 0) {
4061
// determine the window type
4063
fprintf(stderr, "NETWinInfo::update: getting window type (%ld)\n",
4067
p->has_net_support = true;
4069
unsigned long count = 0;
4070
long *types = (long *) data_ret;
4073
while (count < nitems_ret) {
4074
// remember all window types we know
4076
char* debug_type = XGetAtomName(p->display, (Atom) types[count]);
4078
"NETWinInfo::update: examining window type %ld %s\n",
4079
types[count], debug_type );
4081
XFree( debug_type );
4084
if ((Atom) types[count] == net_wm_window_type_normal)
4085
p->types[ pos++ ] = Normal;
4086
else if ((Atom) types[count] == net_wm_window_type_desktop)
4087
p->types[ pos++ ] = Desktop;
4088
else if ((Atom) types[count] == net_wm_window_type_dock)
4089
p->types[ pos++ ] = Dock;
4090
else if ((Atom) types[count] == net_wm_window_type_toolbar)
4091
p->types[ pos++ ] = Toolbar;
4092
else if ((Atom) types[count] == net_wm_window_type_menu)
4093
p->types[ pos++ ] = Menu;
4094
else if ((Atom) types[count] == net_wm_window_type_dialog)
4095
p->types[ pos++ ] = Dialog;
4096
else if ((Atom) types[count] == net_wm_window_type_utility)
4097
p->types[ pos++ ] = Utility;
4098
else if ((Atom) types[count] == net_wm_window_type_splash)
4099
p->types[ pos++ ] = Splash;
4100
else if ((Atom) types[count] == net_wm_window_type_dropdown_menu)
4101
p->types[ pos++ ] = DropdownMenu;
4102
else if ((Atom) types[count] == net_wm_window_type_popup_menu)
4103
p->types[ pos++ ] = PopupMenu;
4104
else if ((Atom) types[count] == net_wm_window_type_tooltip)
4105
p->types[ pos++ ] = Tooltip;
4106
else if ((Atom) types[count] == net_wm_window_type_notification)
4107
p->types[ pos++ ] = Notification;
4108
else if ((Atom) types[count] == net_wm_window_type_combobox)
4109
p->types[ pos++ ] = ComboBox;
4110
else if ((Atom) types[count] == net_wm_window_type_dnd)
4111
p->types[ pos++ ] = DNDIcon;
4112
else if ((Atom) types[count] == kde_net_wm_window_type_override)
4113
p->types[ pos++ ] = Override;
4114
else if ((Atom) types[count] == kde_net_wm_window_type_topmenu)
4115
p->types[ pos++ ] = TopMenu;
4126
if (dirty & WMStrut) {
4127
p->strut = NETStrut();
4128
if (XGetWindowProperty(p->display, p->window, net_wm_strut, 0l, 4l,
4129
False, XA_CARDINAL, &type_ret, &format_ret,
4130
&nitems_ret, &unused, &data_ret)
4132
if (type_ret == XA_CARDINAL && format_ret == 32 &&
4134
long *d = (long *) data_ret;
4135
p->strut.left = d[0];
4136
p->strut.right = d[1];
4137
p->strut.top = d[2];
4138
p->strut.bottom = d[3];
4145
if (dirty2 & WM2ExtendedStrut) {
4146
p->extended_strut = NETExtendedStrut();
4147
if (XGetWindowProperty(p->display, p->window, net_wm_extended_strut, 0l, 12l,
4148
False, XA_CARDINAL, &type_ret, &format_ret,
4149
&nitems_ret, &unused, &data_ret)
4151
if (type_ret == XA_CARDINAL && format_ret == 32 &&
4153
long *d = (long *) data_ret;
4154
p->extended_strut.left_width = d[0];
4155
p->extended_strut.right_width = d[1];
4156
p->extended_strut.top_width = d[2];
4157
p->extended_strut.bottom_width = d[3];
4158
p->extended_strut.left_start = d[4];
4159
p->extended_strut.left_end = d[5];
4160
p->extended_strut.right_start = d[6];
4161
p->extended_strut.right_end = d[7];
4162
p->extended_strut.top_start = d[8];
4163
p->extended_strut.top_end = d[9];
4164
p->extended_strut.bottom_start = d[10];
4165
p->extended_strut.bottom_end = d[11];
4172
if (dirty & WMIconGeometry) {
4173
p->icon_geom = NETRect();
4174
if (XGetWindowProperty(p->display, p->window, net_wm_icon_geometry, 0l, 4l,
4175
False, XA_CARDINAL, &type_ret, &format_ret,
4176
&nitems_ret, &unused, &data_ret)
4178
if (type_ret == XA_CARDINAL && format_ret == 32 &&
4180
long *d = (long *) data_ret;
4181
p->icon_geom.pos.x = d[0];
4182
p->icon_geom.pos.y = d[1];
4183
p->icon_geom.size.width = d[2];
4184
p->icon_geom.size.height = d[3];
4191
if (dirty & WMIcon) {
4192
readIcon(p->display,p->window,net_wm_icon,p->icons,p->icon_count);
4195
if (dirty & WMKDESystemTrayWinFor) {
4196
p->kde_system_tray_win_for = 0;
4197
if (XGetWindowProperty(p->display, p->window, kde_net_wm_system_tray_window_for,
4198
0l, 1l, False, XA_WINDOW, &type_ret, &format_ret,
4199
&nitems_ret, &unused, &data_ret)
4201
if (type_ret == XA_WINDOW && format_ret == 32 &&
4203
p->kde_system_tray_win_for = *((Window *) data_ret);
4204
if ( p->kde_system_tray_win_for == 0 )
4205
p->kde_system_tray_win_for = p->root;
4212
if (dirty & WMFrameExtents) {
4213
p->frame_strut = NETStrut();
4215
if (XGetWindowProperty(p->display, p->window, net_frame_extents,
4216
0l, 4l, False, XA_CARDINAL, &type_ret, &format_ret,
4217
&nitems_ret, &unused, &data_ret) == Success) {
4218
if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 4) {
4220
long *d = (long *) data_ret;
4222
p->frame_strut.left = d[0];
4223
p->frame_strut.right = d[1];
4224
p->frame_strut.top = d[2];
4225
p->frame_strut.bottom = d[3];
4230
if (!ok && XGetWindowProperty(p->display, p->window, kde_net_wm_frame_strut,
4231
0l, 4l, False, XA_CARDINAL, &type_ret, &format_ret,
4232
&nitems_ret, &unused, &data_ret) == Success) {
4233
if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 4) {
4235
long *d = (long *) data_ret;
4237
p->frame_strut.left = d[0];
4238
p->frame_strut.right = d[1];
4239
p->frame_strut.top = d[2];
4240
p->frame_strut.bottom = d[3];
4247
if (dirty & WMPid) {
4249
if (XGetWindowProperty(p->display, p->window, net_wm_pid, 0l, 1l,
4250
False, XA_CARDINAL, &type_ret, &format_ret,
4251
&nitems_ret, &unused, &data_ret) == Success) {
4252
if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 1) {
4253
p->pid = *((long *) data_ret);
4260
if (dirty2 & WM2StartupId)
4262
delete[] p->startup_id;
4263
p->startup_id = NULL;
4264
if (XGetWindowProperty(p->display, p->window, net_startup_id, 0l,
4265
MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
4266
&format_ret, &nitems_ret, &unused, &data_ret)
4268
if (type_ret == UTF8_STRING && format_ret == 8 && nitems_ret > 0) {
4269
p->startup_id = nstrndup((const char *) data_ret, nitems_ret);
4277
if (dirty2 & WM2Opacity)
4279
p->opacity = 0xffffffff;
4280
if (XGetWindowProperty(p->display, p->window, net_wm_window_opacity, 0l,
4281
MAX_PROP_SIZE, False, XA_CARDINAL, &type_ret,
4282
&format_ret, &nitems_ret, &unused, &data_ret)
4284
if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 1) {
4285
p->opacity = *((long*)data_ret);
4293
if( dirty2 & WM2AllowedActions ) {
4294
p->allowed_actions = 0;
4295
if (XGetWindowProperty(p->display, p->window, net_wm_allowed_actions, 0l, 2048l,
4296
False, XA_ATOM, &type_ret, &format_ret,
4297
&nitems_ret, &unused, &data_ret)
4299
if (type_ret == XA_ATOM && format_ret == 32 && nitems_ret > 0) {
4300
// determine actions
4302
fprintf(stderr, "NETWinInfo::update: updating allowed actions (%ld)\n",
4306
long *actions = (long *) data_ret;
4307
unsigned long count;
4309
for (count = 0; count < nitems_ret; count++) {
4312
"NETWinInfo::update: adding allowed action %ld '%s'\n",
4314
XGetAtomName(p->display, (Atom) actions[count]));
4317
if ((Atom) actions[count] == net_wm_action_move)
4318
p->allowed_actions |= ActionMove;
4319
if ((Atom) actions[count] == net_wm_action_resize)
4320
p->allowed_actions |= ActionResize;
4321
if ((Atom) actions[count] == net_wm_action_minimize)
4322
p->allowed_actions |= ActionMinimize;
4323
if ((Atom) actions[count] == net_wm_action_shade)
4324
p->allowed_actions |= ActionShade;
4325
if ((Atom) actions[count] == net_wm_action_stick)
4326
p->allowed_actions |= ActionStick;
4327
if ((Atom) actions[count] == net_wm_action_max_vert)
4328
p->allowed_actions |= ActionMaxVert;
4329
if ((Atom) actions[count] == net_wm_action_max_horiz)
4330
p->allowed_actions |= ActionMaxHoriz;
4331
if ((Atom) actions[count] == net_wm_action_fullscreen)
4332
p->allowed_actions |= ActionFullScreen;
4333
if ((Atom) actions[count] == net_wm_action_change_desk)
4334
p->allowed_actions |= ActionChangeDesktop;
4335
if ((Atom) actions[count] == net_wm_action_close)
4336
p->allowed_actions |= ActionClose;
4344
if (dirty2 & WM2UserTime) {
4346
if (XGetWindowProperty(p->display, p->window, net_wm_user_time, 0l, 1l,
4347
False, XA_CARDINAL, &type_ret, &format_ret,
4348
&nitems_ret, &unused, &data_ret) == Success) {
4349
// don't do nitems_ret check - Qt does PropModeAppend to avoid API call for it
4350
if (type_ret == XA_CARDINAL && format_ret == 32 /*&& nitems_ret == 1*/) {
4351
p->user_time = *((long *) data_ret);
4358
if (dirty2 & WM2TransientFor) {
4359
p->transient_for = None;
4360
XGetTransientForHint(p->display, p->window, &p->transient_for);
4363
if (dirty2 & WM2GroupLeader) {
4364
XWMHints *hints = XGetWMHints(p->display, p->window);
4365
p->window_group = None;
4368
if( hints->flags & WindowGroupHint )
4369
p->window_group = hints->window_group;
4370
XFree( reinterpret_cast< char* >( hints ));
4374
if( dirty2 & WM2WindowClass ) {
4375
delete[] p->class_class;
4376
delete[] p->class_name;
4377
p->class_class = NULL;
4378
p->class_name = NULL;
4380
if( XGetClassHint( p->display, p->window, &hint )) {
4381
p->class_class = strdup( hint.res_class );
4382
p->class_name = strdup( hint.res_name );
4383
XFree( hint.res_class );
4384
XFree( hint.res_name );
4388
if( dirty2 & WM2WindowRole ) {
4391
if (XGetWindowProperty(p->display, p->window, wm_window_role, 0l,
4392
MAX_PROP_SIZE, False, XA_STRING, &type_ret,
4393
&format_ret, &nitems_ret, &unused, &data_ret)
4395
if (type_ret == XA_STRING && format_ret == 8 && nitems_ret > 0) {
4396
p->role = nstrndup((const char *) data_ret, nitems_ret);
4403
if( dirty2 & WM2ClientMachine ) {
4404
delete[] p->client_machine;
4405
p->client_machine = NULL;
4406
if (XGetWindowProperty(p->display, p->window, XA_WM_CLIENT_MACHINE, 0l,
4407
MAX_PROP_SIZE, False, XA_STRING, &type_ret,
4408
&format_ret, &nitems_ret, &unused, &data_ret)
4410
if (type_ret == XA_STRING && format_ret == 8 && nitems_ret > 0) {
4411
p->client_machine = nstrndup((const char *) data_ret, nitems_ret);
4420
NETRect NETWinInfo::iconGeometry() const {
4421
return p->icon_geom;
4425
unsigned long NETWinInfo::state() const {
4430
NETStrut NETWinInfo::strut() const {
4434
NETExtendedStrut NETWinInfo::extendedStrut() const {
4435
return p->extended_strut;
4438
bool NET::typeMatchesMask( WindowType type, unsigned long mask ) {
4440
#define CHECK_TYPE_MASK( type ) \
4442
if( mask & type##Mask ) \
4445
CHECK_TYPE_MASK( Normal )
4446
CHECK_TYPE_MASK( Desktop )
4447
CHECK_TYPE_MASK( Dock )
4448
CHECK_TYPE_MASK( Toolbar )
4449
CHECK_TYPE_MASK( Menu )
4450
CHECK_TYPE_MASK( Dialog )
4451
CHECK_TYPE_MASK( Override )
4452
CHECK_TYPE_MASK( TopMenu )
4453
CHECK_TYPE_MASK( Utility )
4454
CHECK_TYPE_MASK( Splash )
4455
CHECK_TYPE_MASK( DropdownMenu )
4456
CHECK_TYPE_MASK( PopupMenu )
4457
CHECK_TYPE_MASK( Tooltip )
4458
CHECK_TYPE_MASK( Notification )
4459
CHECK_TYPE_MASK( ComboBox )
4460
CHECK_TYPE_MASK( DNDIcon )
4461
#undef CHECK_TYPE_MASK
4468
NET::WindowType NETWinInfo::windowType( unsigned long supported_types ) const {
4470
i < p->types.size();
4472
// return the type only if the application supports it
4473
if( typeMatchesMask( p->types[ i ], supported_types ))
4474
return p->types[ i ];
4480
const char *NETWinInfo::name() const {
4485
const char *NETWinInfo::visibleName() const {
4486
return p->visible_name;
4490
const char *NETWinInfo::iconName() const {
4491
return p->icon_name;
4495
const char *NETWinInfo::visibleIconName() const {
4496
return p->visible_icon_name;
4500
int NETWinInfo::desktop() const {
4504
int NETWinInfo::pid() const {
4508
Time NETWinInfo::userTime() const {
4509
return p->user_time;
4512
const char* NETWinInfo::startupId() const {
4513
return p->startup_id;
4516
unsigned long NETWinInfo::opacity() const {
4520
unsigned long NETWinInfo::allowedActions() const {
4521
return p->allowed_actions;
4524
bool NETWinInfo::hasNETSupport() const {
4525
return p->has_net_support;
4528
Window NETWinInfo::transientFor() const {
4529
return p->transient_for;
4532
Window NETWinInfo::groupLeader() const {
4533
return p->window_group;
4536
const char* NETWinInfo::windowClassClass() const {
4537
return p->class_class;
4540
const char* NETWinInfo::windowClassName() const {
4541
return p->class_name;
4544
const char* NETWinInfo::windowRole() const {
4548
const char* NETWinInfo::clientMachine() const {
4549
return p->client_machine;
4552
Bool NETWinInfo::handledIcons() const {
4553
return p->handled_icons;
4557
Window NETWinInfo::kdeSystemTrayWinFor() const {
4558
return p->kde_system_tray_win_for;
4561
const unsigned long* NETWinInfo::passedProperties() const {
4562
return p->properties;
4566
NET::MappingState NETWinInfo::mappingState() const {
4567
return p->mapping_state;
4570
void NETRootInfo::virtual_hook( int, void* )
4571
{ /*BASE::virtual_hook( id, data );*/ }
4573
void NETWinInfo::virtual_hook( int, void* )
4574
{ /*BASE::virtual_hook( id, data );*/ }
4576
// Functions for X timestamp comparing. For Time being 32bit they're fairly simple
4577
// (the #if 0 part), but on 64bit architectures Time is 64bit unsigned long,
4578
// so there special care needs to be taken to always use only the lower 32bits.
4580
int NET::timestampCompare( Time time1, Time time2 ) // like strcmp()
4582
if( time1 == time2 )
4584
return ( time1 - time2 ) < 0x7fffffffU ? 1 : -1; // time1 > time2 -> 1, handle wrapping
4587
Time NET::timestampDiff( Time time1, Time time2 ) // returns time2 - time1
4588
{ // no need to handle wrapping?
4589
return time2 - time1;
4592
int NET::timestampCompare( unsigned long time1_, unsigned long time2_ ) // like strcmp()
4594
quint32 time1 = time1_;
4595
quint32 time2 = time2_;
4596
if( time1 == time2 )
4598
return quint32( time1 - time2 ) < 0x7fffffffU ? 1 : -1; // time1 > time2 -> 1, handle wrapping
4601
int NET::timestampDiff( unsigned long time1_, unsigned long time2_ ) // returns time2 - time1
4602
{ // no need to handle wrapping?
4603
quint32 time1 = time1_;
4604
quint32 time2 = time2_;
4605
return quint32( time2 - time1 );