00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
#include <qwidget.h>
00029
#ifdef Q_WS_X11 //FIXME
00030
00031
#include "netwm.h"
00032
00033
#include <string.h>
00034
#include <stdio.h>
00035
#include <assert.h>
00036
#include <stdlib.h>
00037
00038
#include <X11/Xmd.h>
00039
00040
#include "netwm_p.h"
00041
00042
00043
static Atom UTF8_STRING = 0;
00044
00045
00046
static Atom net_supported = 0;
00047
static Atom net_client_list = 0;
00048
static Atom net_client_list_stacking = 0;
00049
static Atom net_desktop_geometry = 0;
00050
static Atom net_desktop_viewport = 0;
00051
static Atom net_current_desktop = 0;
00052
static Atom net_desktop_names = 0;
00053
static Atom net_number_of_desktops = 0;
00054
static Atom net_active_window = 0;
00055
static Atom net_workarea = 0;
00056
static Atom net_supporting_wm_check = 0;
00057
static Atom net_virtual_roots = 0;
00058
00059
00060
static Atom net_close_window = 0;
00061
static Atom net_restack_window = 0;
00062
static Atom net_wm_moveresize = 0;
00063
static Atom net_moveresize_window = 0;
00064
00065
00066
static Atom net_wm_name = 0;
00067
static Atom net_wm_visible_name = 0;
00068
static Atom net_wm_icon_name = 0;
00069
static Atom net_wm_visible_icon_name = 0;
00070
static Atom net_wm_desktop = 0;
00071
static Atom net_wm_window_type = 0;
00072
static Atom net_wm_state = 0;
00073
static Atom net_wm_strut = 0;
00074
static Atom net_wm_icon_geometry = 0;
00075
static Atom net_wm_icon = 0;
00076
static Atom net_wm_pid = 0;
00077
static Atom net_wm_user_time = 0;
00078
static Atom net_wm_handled_icons = 0;
00079
static Atom net_startup_id = 0;
00080
static Atom net_wm_allowed_actions = 0;
00081
00082
00083
static Atom kde_net_system_tray_windows = 0;
00084
static Atom kde_net_wm_system_tray_window_for = 0;
00085
static Atom kde_net_wm_frame_strut = 0;
00086
static Atom kde_net_wm_window_type_override = 0;
00087
static Atom kde_net_wm_window_type_topmenu = 0;
00088
00089
00090
static Atom wm_protocols = 0;
00091
static Atom net_wm_ping = 0;
00092
00093
00094
static Atom net_wm_window_type_normal = 0;
00095
static Atom net_wm_window_type_desktop = 0;
00096
static Atom net_wm_window_type_dock = 0;
00097
static Atom net_wm_window_type_toolbar = 0;
00098
static Atom net_wm_window_type_menu = 0;
00099
static Atom net_wm_window_type_dialog = 0;
00100
static Atom net_wm_window_type_utility = 0;
00101
static Atom net_wm_window_type_splash = 0;
00102
00103
00104
static Atom net_wm_state_modal = 0;
00105
static Atom net_wm_state_sticky = 0;
00106
static Atom net_wm_state_max_vert = 0;
00107
static Atom net_wm_state_max_horiz = 0;
00108
static Atom net_wm_state_shaded = 0;
00109
static Atom net_wm_state_skip_taskbar = 0;
00110
static Atom net_wm_state_skip_pager = 0;
00111
static Atom net_wm_state_hidden = 0;
00112
static Atom net_wm_state_fullscreen = 0;
00113
static Atom net_wm_state_above = 0;
00114
static Atom net_wm_state_below = 0;
00115
static Atom net_wm_state_demands_attention = 0;
00116
00117
00118
static Atom net_wm_action_move = 0;
00119
static Atom net_wm_action_resize = 0;
00120
static Atom net_wm_action_minimize = 0;
00121
static Atom net_wm_action_shade = 0;
00122
static Atom net_wm_action_stick = 0;
00123
static Atom net_wm_action_max_vert = 0;
00124
static Atom net_wm_action_max_horiz = 0;
00125
static Atom net_wm_action_fullscreen = 0;
00126
static Atom net_wm_action_change_desk = 0;
00127
static Atom net_wm_action_close = 0;
00128
00129
00130
static Atom net_wm_state_stays_on_top = 0;
00131
00132
00133
static Atom xa_wm_state = 0;
00134
00135
static Bool netwm_atoms_created = False;
00136
const unsigned long netwm_sendevent_mask = (SubstructureRedirectMask|
00137 SubstructureNotifyMask);
00138
00139
00140
const long MAX_PROP_SIZE = 100000;
00141
00142
static char *nstrdup(
const char *s1) {
00143
if (! s1)
return (
char *) 0;
00144
00145
int l = strlen(s1) + 1;
00146
char *s2 =
new char[l];
00147 strncpy(s2, s1, l);
00148
return s2;
00149 }
00150
00151
00152
static char *nstrndup(
const char *s1,
int l) {
00153
if (! s1 || l == 0)
return (
char *) 0;
00154
00155
char *s2 =
new char[l+1];
00156 strncpy(s2, s1, l);
00157 s2[l] =
'\0';
00158
return s2;
00159 }
00160
00161
00162
static Window *nwindup(Window *w1,
int n) {
00163
if (! w1 || n == 0)
return (Window *) 0;
00164
00165 Window *w2 =
new Window[n];
00166
while (n--) w2[n] = w1[n];
00167
return w2;
00168 }
00169
00170
00171
static void refdec_nri(
NETRootInfoPrivate *p) {
00172
00173
#ifdef NETWMDEBUG
00174
fprintf(stderr,
"NET: decrementing NETRootInfoPrivate::ref (%d)\n", p->
ref - 1);
00175
#endif
00176
00177
if (! --p->
ref) {
00178
00179
#ifdef NETWMDEBUG
00180
fprintf(stderr,
"NET: \tno more references, deleting\n");
00181
#endif
00182
00183
delete [] p->
name;
00184
delete [] p->
stacking;
00185
delete [] p->
clients;
00186
delete [] p->
virtual_roots;
00187
delete [] p->
kde_system_tray_windows;
00188
00189
int i;
00190
for (i = 0; i < p->
desktop_names.
size(); i++)
00191
delete [] p->
desktop_names[i];
00192 }
00193 }
00194
00195
00196
static void refdec_nwi(
NETWinInfoPrivate *p) {
00197
00198
#ifdef NETWMDEBUG
00199
fprintf(stderr,
"NET: decrementing NETWinInfoPrivate::ref (%d)\n", p->
ref - 1);
00200
#endif
00201
00202
if (! --p->
ref) {
00203
00204
#ifdef NETWMDEBUG
00205
fprintf(stderr,
"NET: \tno more references, deleting\n");
00206
#endif
00207
00208
delete [] p->
name;
00209
delete [] p->
visible_name;
00210
delete [] p->
icon_name;
00211
delete [] p->
visible_icon_name;
00212
delete [] p->
startup_id;
00213
00214
int i;
00215
for (i = 0; i < p->
icons.
size(); i++)
00216
delete [] p->
icons[i].data;
00217 }
00218 }
00219
00220
00221
static int wcmp(
const void *a,
const void *b) {
00222
return *((Window *) a) - *((Window *) b);
00223 }
00224
00225
00226
static const int netAtomCount = 71;
00227
static void create_atoms(Display *d) {
00228
static const char *
const names[netAtomCount] =
00229 {
00230
"UTF8_STRING",
00231
"_NET_SUPPORTED",
00232
"_NET_SUPPORTING_WM_CHECK",
00233
"_NET_CLIENT_LIST",
00234
"_NET_CLIENT_LIST_STACKING",
00235
"_NET_NUMBER_OF_DESKTOPS",
00236
"_NET_DESKTOP_GEOMETRY",
00237
"_NET_DESKTOP_VIEWPORT",
00238
"_NET_CURRENT_DESKTOP",
00239
"_NET_DESKTOP_NAMES",
00240
"_NET_ACTIVE_WINDOW",
00241
"_NET_WORKAREA",
00242
"_NET_VIRTUAL_ROOTS",
00243
"_NET_CLOSE_WINDOW",
00244
"_NET_RESTACK_WINDOW",
00245
00246
"_NET_WM_MOVERESIZE",
00247
"_NET_MOVERESIZE_WINDOW",
00248
"_NET_WM_NAME",
00249
"_NET_WM_VISIBLE_NAME",
00250
"_NET_WM_ICON_NAME",
00251
"_NET_WM_VISIBLE_ICON_NAME",
00252
"_NET_WM_DESKTOP",
00253
"_NET_WM_WINDOW_TYPE",
00254
"_NET_WM_STATE",
00255
"_NET_WM_STRUT",
00256
"_NET_WM_ICON_GEOMETRY",
00257
"_NET_WM_ICON",
00258
"_NET_WM_PID",
00259
"_NET_WM_USER_TIME",
00260
"_NET_WM_HANDLED_ICONS",
00261
"_NET_STARTUP_ID",
00262
"_NET_WM_ALLOWED_ACTIONS",
00263
"_NET_WM_PING",
00264
00265
"_NET_WM_WINDOW_TYPE_NORMAL",
00266
"_NET_WM_WINDOW_TYPE_DESKTOP",
00267
"_NET_WM_WINDOW_TYPE_DOCK",
00268
"_NET_WM_WINDOW_TYPE_TOOLBAR",
00269
"_NET_WM_WINDOW_TYPE_MENU",
00270
"_NET_WM_WINDOW_TYPE_DIALOG",
00271
"_NET_WM_WINDOW_TYPE_UTILITY",
00272
"_NET_WM_WINDOW_TYPE_SPLASH",
00273
00274
"_NET_WM_STATE_MODAL",
00275
"_NET_WM_STATE_STICKY",
00276
"_NET_WM_STATE_MAXIMIZED_VERT",
00277
"_NET_WM_STATE_MAXIMIZED_HORZ",
00278
"_NET_WM_STATE_SHADED",
00279
"_NET_WM_STATE_SKIP_TASKBAR",
00280
"_NET_WM_STATE_SKIP_PAGER",
00281
"_NET_WM_STATE_HIDDEN",
00282
"_NET_WM_STATE_FULLSCREEN",
00283
"_NET_WM_STATE_ABOVE",
00284
"_NET_WM_STATE_BELOW",
00285
"_NET_WM_STATE_DEMANDS_ATTENTION",
00286
00287
"_NET_WM_ACTION_MOVE",
00288
"_NET_WM_ACTION_RESIZE",
00289
"_NET_WM_ACTION_MINIMIZE",
00290
"_NET_WM_ACTION_SHADE",
00291
"_NET_WM_ACTION_STICK",
00292
"_NET_WM_ACTION_MAXIMIZE_VERT",
00293
"_NET_WM_ACTION_MAXIMIZE_HORZ",
00294
"_NET_WM_ACTION_FULLSCREEN",
00295
"_NET_WM_ACTION_CHANGE_DESKTOP",
00296
"_NET_WM_ACTION_CLOSE",
00297
00298
"_NET_WM_STATE_STAYS_ON_TOP",
00299
00300
"_KDE_NET_SYSTEM_TRAY_WINDOWS",
00301
"_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR",
00302
"_KDE_NET_WM_FRAME_STRUT",
00303
"_KDE_NET_WM_WINDOW_TYPE_OVERRIDE",
00304
"_KDE_NET_WM_WINDOW_TYPE_TOPMENU",
00305
00306
"WM_STATE",
00307
"WM_PROTOCOLS"
00308 };
00309
00310 Atom atoms[netAtomCount], *atomsp[netAtomCount] =
00311 {
00312 &UTF8_STRING,
00313 &net_supported,
00314 &net_supporting_wm_check,
00315 &net_client_list,
00316 &net_client_list_stacking,
00317 &net_number_of_desktops,
00318 &net_desktop_geometry,
00319 &net_desktop_viewport,
00320 &net_current_desktop,
00321 &net_desktop_names,
00322 &net_active_window,
00323 &net_workarea,
00324 &net_virtual_roots,
00325 &net_close_window,
00326 &net_restack_window,
00327
00328 &net_wm_moveresize,
00329 &net_moveresize_window,
00330 &net_wm_name,
00331 &net_wm_visible_name,
00332 &net_wm_icon_name,
00333 &net_wm_visible_icon_name,
00334 &net_wm_desktop,
00335 &net_wm_window_type,
00336 &net_wm_state,
00337 &net_wm_strut,
00338 &net_wm_icon_geometry,
00339 &net_wm_icon,
00340 &net_wm_pid,
00341 &net_wm_user_time,
00342 &net_wm_handled_icons,
00343 &net_startup_id,
00344 &net_wm_allowed_actions,
00345 &net_wm_ping,
00346
00347 &net_wm_window_type_normal,
00348 &net_wm_window_type_desktop,
00349 &net_wm_window_type_dock,
00350 &net_wm_window_type_toolbar,
00351 &net_wm_window_type_menu,
00352 &net_wm_window_type_dialog,
00353 &net_wm_window_type_utility,
00354 &net_wm_window_type_splash,
00355
00356 &net_wm_state_modal,
00357 &net_wm_state_sticky,
00358 &net_wm_state_max_vert,
00359 &net_wm_state_max_horiz,
00360 &net_wm_state_shaded,
00361 &net_wm_state_skip_taskbar,
00362 &net_wm_state_skip_pager,
00363 &net_wm_state_hidden,
00364 &net_wm_state_fullscreen,
00365 &net_wm_state_above,
00366 &net_wm_state_below,
00367 &net_wm_state_demands_attention,
00368
00369 &net_wm_action_move,
00370 &net_wm_action_resize,
00371 &net_wm_action_minimize,
00372 &net_wm_action_shade,
00373 &net_wm_action_stick,
00374 &net_wm_action_max_vert,
00375 &net_wm_action_max_horiz,
00376 &net_wm_action_fullscreen,
00377 &net_wm_action_change_desk,
00378 &net_wm_action_close,
00379
00380 &net_wm_state_stays_on_top,
00381
00382 &kde_net_system_tray_windows,
00383 &kde_net_wm_system_tray_window_for,
00384 &kde_net_wm_frame_strut,
00385 &kde_net_wm_window_type_override,
00386 &kde_net_wm_window_type_topmenu,
00387
00388 &xa_wm_state,
00389 &wm_protocols
00390 };
00391
00392 assert( !netwm_atoms_created );
00393
00394
int i = netAtomCount;
00395
while (i--)
00396 atoms[i] = 0;
00397
00398 XInternAtoms(d, (
char **) names, netAtomCount, False, atoms);
00399
00400 i = netAtomCount;
00401
while (i--)
00402 *atomsp[i] = atoms[i];
00403
00404 netwm_atoms_created = True;
00405 }
00406
00407
00408
static void readIcon(
NETWinInfoPrivate *p) {
00409
00410
#ifdef NETWMDEBUG
00411
fprintf(stderr,
"NET: readIcon\n");
00412
#endif
00413
00414 Atom type_ret;
00415
int format_ret;
00416
unsigned long nitems_ret = 0, after_ret = 0;
00417
unsigned char *data_ret = 0;
00418
00419
00420
for (
int i = 0; i < p->
icons.
size(); i++)
00421
delete [] p->
icons[i].data;
00422 p->
icons.
reset();
00423 p->
icon_count = 0;
00424
00425
00426
unsigned char *buffer = 0;
00427
unsigned long offset = 0;
00428
unsigned long buffer_offset = 0;
00429
unsigned long bufsize = 0;
00430
00431
00432
do {
00433
if (XGetWindowProperty(p->
display, p->
window, net_wm_icon, offset,
00434 MAX_PROP_SIZE, False, XA_CARDINAL, &type_ret,
00435 &format_ret, &nitems_ret, &after_ret, &data_ret)
00436 == Success) {
00437
if (!bufsize)
00438 {
00439
if (nitems_ret < 3 || type_ret != XA_CARDINAL ||
00440 format_ret != 32) {
00441
00442
00443
00444
00445
if ( data_ret )
00446 XFree(data_ret);
00447
return;
00448 }
00449
00450 bufsize = nitems_ret *
sizeof(
long) + after_ret;
00451 buffer = (
unsigned char *) malloc(bufsize);
00452 }
00453
else if (buffer_offset + nitems_ret*
sizeof(
long) > bufsize)
00454 {
00455 fprintf(stderr,
"NETWM: Warning readIcon() needs buffer adjustment!\n");
00456 bufsize = buffer_offset + nitems_ret *
sizeof(
long) + after_ret;
00457 buffer = (
unsigned char *) realloc(buffer, bufsize);
00458 }
00459 memcpy((buffer + buffer_offset), data_ret, nitems_ret *
sizeof(
long));
00460 buffer_offset += nitems_ret *
sizeof(
long);
00461 offset += nitems_ret;
00462
00463
if ( data_ret )
00464 XFree(data_ret);
00465 }
else {
00466
if (buffer)
00467 free(buffer);
00468
return;
00469 }
00470 }
00471
while (after_ret > 0);
00472
00473 CARD32 *data32;
00474
unsigned long i, j, k, sz, s;
00475
unsigned long *d = (
unsigned long *) buffer;
00476
for (i = 0, j = 0; i < bufsize; i++) {
00477 p->
icons[j].
size.width = *d++;
00478 i +=
sizeof(
long);
00479 p->
icons[j].
size.height = *d++;
00480 i +=
sizeof(
long);
00481
00482 sz = p->
icons[j].
size.width * p->
icons[j].
size.height;
00483 s = sz *
sizeof(
long);
00484
00485
if ( i + s - 1 > bufsize ) {
00486
break;
00487 }
00488
00489
delete [] p->
icons[j].data;
00490 data32 =
new CARD32[sz];
00491 p->
icons[j].data = (
unsigned char *) data32;
00492
for (k = 0; k < sz; k++, i +=
sizeof(
long)) {
00493 *data32++ = (CARD32) *d++;
00494 }
00495 j++;
00496 p->
icon_count++;
00497 }
00498
00499
#ifdef NETWMDEBUG
00500
fprintf(stderr,
"NET: readIcon got %d icons\n", p->
icon_count);
00501
#endif
00502
00503 free(buffer);
00504 }
00505
00506
00507
template <
class Z>
00508
NETRArray<Z>::NETRArray()
00509 : sz(0), capacity(2)
00510 {
00511 d = (Z*) calloc(capacity,
sizeof(Z));
00512 }
00513
00514
00515
template <
class Z>
00516
NETRArray<Z>::~NETRArray() {
00517 free(d);
00518 }
00519
00520
00521
template <
class Z>
00522
void NETRArray<Z>::reset() {
00523 sz = 0;
00524 capacity = 2;
00525 d = (Z*) realloc(d,
sizeof(Z)*capacity);
00526 memset( (
void*) d, 0,
sizeof(Z)*capacity );
00527 }
00528
00529
template <
class Z>
00530 Z &
NETRArray<Z>::operator[](
int index) {
00531
if (index >= capacity) {
00532
00533
00534
00535
int newcapacity = 2*capacity > index+1 ? 2*capacity : index+1;
00536
00537 d = (Z*) realloc(d,
sizeof(Z)*newcapacity);
00538 memset( (
void*) &d[capacity], 0,
sizeof(Z)*(newcapacity-capacity) );
00539 capacity = newcapacity;
00540 }
00541
if (index >= sz)
00542 sz = index + 1;
00543
00544
return d[index];
00545 }
00546
00547
00548
00549
00550 NETRootInfo::NETRootInfo(Display *display, Window supportWindow,
const char *wmName,
00551
const unsigned long properties[],
int properties_size,
00552
int screen,
bool doActivate)
00553 {
00554
00555
#ifdef NETWMDEBUG
00556
fprintf(stderr,
"NETRootInfo::NETRootInfo: using window manager constructor\n");
00557
#endif
00558
00559 p =
new NETRootInfoPrivate;
00560 p->
ref = 1;
00561
00562 p->
display = display;
00563 p->
name = nstrdup(wmName);
00564
00565
if (screen != -1) {
00566 p->screen = screen;
00567 }
else {
00568 p->screen = DefaultScreen(p->
display);
00569 }
00570
00571 p->
root = RootWindow(p->
display, p->screen);
00572 p->supportwindow = supportWindow;
00573 p->number_of_desktops = p->current_desktop = 0;
00574 p->active = None;
00575 p->clients = p->stacking = p->virtual_roots = (Window *) 0;
00576 p->clients_count = p->stacking_count = p->virtual_roots_count = 0;
00577 p->kde_system_tray_windows = 0;
00578 p->kde_system_tray_windows_count = 0;
00579 setDefaultProperties();
00580
if( properties_size > PROPERTIES_SIZE ) {
00581 fprintf( stderr,
"NETRootInfo::NETRootInfo(): properties array too large\n");
00582 properties_size = PROPERTIES_SIZE;
00583 }
00584
for(
int i = 0; i < properties_size; ++i )
00585 p->
properties[ i ] = properties[ i ];
00586
00587 p->
properties[ PROTOCOLS ] |= ( Supported | SupportingWMCheck );
00588 p->client_properties[ PROTOCOLS ] = DesktopNames
00589 | WMPing;
00590 p->client_properties[ PROTOCOLS2 ] = 0;
00591
00592 role = WindowManager;
00593
00594
if (! netwm_atoms_created) create_atoms(p->
display);
00595
00596
if (doActivate) activate();
00597 }
00598
00599 NETRootInfo::NETRootInfo(Display *display, Window supportWindow,
const char *wmName,
00600
unsigned long properties,
int screen,
bool doActivate)
00601 {
00602
00603
#ifdef NETWMDEBUG
00604
fprintf(stderr,
"NETRootInfo::NETRootInfo: using window manager constructor\n");
00605
#endif
00606
00607 p =
new NETRootInfoPrivate;
00608 p->
ref = 1;
00609
00610 p->
display = display;
00611 p->
name = nstrdup(wmName);
00612
00613
if (screen != -1) {
00614 p->screen = screen;
00615 }
else {
00616 p->screen = DefaultScreen(p->
display);
00617 }
00618
00619 p->
root = RootWindow(p->
display, p->screen);
00620 p->supportwindow = supportWindow;
00621 p->number_of_desktops = p->current_desktop = 0;
00622 p->active = None;
00623 p->clients = p->stacking = p->virtual_roots = (Window *) 0;
00624 p->clients_count = p->stacking_count = p->virtual_roots_count = 0;
00625 p->kde_system_tray_windows = 0;
00626 p->kde_system_tray_windows_count = 0;
00627 setDefaultProperties();
00628 p->
properties[ PROTOCOLS ] = properties;
00629
00630 p->
properties[ PROTOCOLS ] |= ( Supported | SupportingWMCheck );
00631 p->client_properties[ PROTOCOLS ] = DesktopNames
00632 | WMPing;
00633 p->client_properties[ PROTOCOLS2 ] = 0;
00634
00635 role = WindowManager;
00636
00637
if (! netwm_atoms_created) create_atoms(p->
display);
00638
00639
if (doActivate) activate();
00640 }
00641
00642
00643 NETRootInfo::NETRootInfo(Display *display,
const unsigned long properties[],
int properties_size,
00644
int screen,
bool doActivate)
00645 {
00646
00647
#ifdef NETWMDEBUG
00648
fprintf(stderr,
"NETRootInfo::NETRootInfo: using Client constructor\n");
00649
#endif
00650
00651 p =
new NETRootInfoPrivate;
00652 p->
ref = 1;
00653
00654 p->
name = 0;
00655
00656 p->
display = display;
00657
00658
if (screen != -1) {
00659 p->screen = screen;
00660 }
else {
00661 p->screen = DefaultScreen(p->
display);
00662 }
00663
00664 p->
root = RootWindow(p->
display, p->screen);
00665 p->rootSize.width = WidthOfScreen(ScreenOfDisplay(p->
display, p->screen));
00666 p->rootSize.height = HeightOfScreen(ScreenOfDisplay(p->
display, p->screen));
00667
00668 p->supportwindow = None;
00669 p->number_of_desktops = p->current_desktop = 0;
00670 p->active = None;
00671 p->clients = p->stacking = p->virtual_roots = (Window *) 0;
00672 p->clients_count = p->stacking_count = p->virtual_roots_count = 0;
00673 p->kde_system_tray_windows = 0;
00674 p->kde_system_tray_windows_count = 0;
00675 setDefaultProperties();
00676
if( properties_size > PROPERTIES_SIZE ) {
00677 fprintf( stderr,
"NETWinInfo::NETWinInfo(): properties array too large\n");
00678 properties_size = PROPERTIES_SIZE;
00679 }
00680
for(
int i = 0; i < properties_size; ++i )
00681 p->client_properties[ i ] = properties[ i ];
00682
for(
int i = 0; i < PROPERTIES_SIZE; ++i )
00683 p->
properties[ i ] = 0;
00684
00685 role = Client;
00686
00687
if (! netwm_atoms_created) create_atoms(p->
display);
00688
00689
if (doActivate) activate();
00690 }
00691
00692 NETRootInfo::NETRootInfo(Display *display,
unsigned long properties,
int screen,
00693
bool doActivate)
00694 {
00695
00696
#ifdef NETWMDEBUG
00697
fprintf(stderr,
"NETRootInfo::NETRootInfo: using Client constructor\n");
00698
#endif
00699
00700 p =
new NETRootInfoPrivate;
00701 p->
ref = 1;
00702
00703 p->
name = 0;
00704
00705 p->
display = display;
00706
00707
if (screen != -1) {
00708 p->screen = screen;
00709 }
else {
00710 p->screen = DefaultScreen(p->
display);
00711 }
00712
00713 p->
root = RootWindow(p->
display, p->screen);
00714 p->rootSize.width = WidthOfScreen(ScreenOfDisplay(p->
display, p->screen));
00715 p->rootSize.height = HeightOfScreen(ScreenOfDisplay(p->
display, p->screen));
00716
00717 p->supportwindow = None;
00718 p->number_of_desktops = p->current_desktop = 0;
00719 p->active = None;
00720 p->clients = p->stacking = p->virtual_roots = (Window *) 0;
00721 p->clients_count = p->stacking_count = p->virtual_roots_count = 0;
00722 p->kde_system_tray_windows = 0;
00723 p->kde_system_tray_windows_count = 0;
00724 setDefaultProperties();
00725 p->client_properties[ PROTOCOLS ] = properties;
00726
for(
int i = 0; i < PROPERTIES_SIZE; ++i )
00727 p->
properties[ i ] = 0;
00728
00729 role = Client;
00730
00731
if (! netwm_atoms_created) create_atoms(p->
display);
00732
00733
if (doActivate) activate();
00734 }
00735
00736
00737 NETRootInfo2::NETRootInfo2(Display *display, Window supportWindow,
const char *wmName,
00738
unsigned long properties[],
int properties_size,
00739
int screen,
bool doActivate)
00740 : NETRootInfo( display, supportWindow, wmName, properties, properties_size,
00741 screen, doActivate )
00742 {
00743 }
00744
00745
00746
00747 NETRootInfo::NETRootInfo(
const NETRootInfo &rootinfo) {
00748
00749
#ifdef NETWMDEBUG
00750
fprintf(stderr,
"NETRootInfo::NETRootInfo: using copy constructor\n");
00751
#endif
00752
00753 p = rootinfo.p;
00754 role = rootinfo.role;
00755
00756 p->
ref++;
00757 }
00758
00759
00760
00761
00762 NETRootInfo::~NETRootInfo() {
00763 refdec_nri(p);
00764
00765
if (! p->
ref)
delete p;
00766 }
00767
00768
00769
void NETRootInfo::setDefaultProperties()
00770 {
00771 p->
properties[ PROTOCOLS ] = Supported | SupportingWMCheck;
00772 p->
properties[ WINDOW_TYPES ] = NormalMask | DesktopMask | DockMask
00773 | ToolbarMask | MenuMask | DialogMask;
00774 p->
properties[ STATES ] = Modal | Sticky | MaxVert | MaxHoriz | Shaded
00775 | SkipTaskbar | StaysOnTop;
00776 p->
properties[ PROTOCOLS2 ] = 0;
00777 p->
properties[ ACTIONS ] = 0;
00778 p->client_properties[ PROTOCOLS ] = 0;
00779 p->client_properties[ WINDOW_TYPES ] = 0;
00780 p->client_properties[ STATES ] = 0;
00781 p->client_properties[ PROTOCOLS2 ] = 0;
00782 p->client_properties[ ACTIONS ] = 0;
00783 }
00784
00785
void NETRootInfo::activate() {
00786
if (role == WindowManager) {
00787
00788
#ifdef NETWMDEBUG
00789
fprintf(stderr,
00790
"NETRootInfo::activate: setting supported properties on root\n");
00791
#endif
00792
00793 setSupported();
00794 }
else {
00795
00796
#ifdef NETWMDEBUG
00797
fprintf(stderr,
"NETRootInfo::activate: updating client information\n");
00798
#endif
00799
00800 update(p->client_properties);
00801 }
00802 }
00803
00804
00805
void NETRootInfo::setClientList(Window *windows,
unsigned int count) {
00806
if (role != WindowManager)
return;
00807
00808 p->clients_count = count;
00809
00810
delete [] p->clients;
00811 p->clients = nwindup(windows, count);
00812
00813
#ifdef NETWMDEBUG
00814
fprintf(stderr,
"NETRootInfo::setClientList: setting list with %ld windows\n",
00815 p->clients_count);
00816
#endif
00817
00818 XChangeProperty(p->
display, p->
root, net_client_list, XA_WINDOW, 32,
00819 PropModeReplace, (
unsigned char *)p->clients,
00820 p->clients_count);
00821 }
00822
00823
00824
void NETRootInfo::setClientListStacking(Window *windows,
unsigned int count) {
00825
if (role != WindowManager)
return;
00826
00827 p->stacking_count = count;
00828
delete [] p->stacking;
00829 p->stacking = nwindup(windows, count);
00830
00831
#ifdef NETWMDEBUG
00832
fprintf(stderr,
00833
"NETRootInfo::setClientListStacking: setting list with %ld windows\n",
00834 p->clients_count);
00835
#endif
00836
00837 XChangeProperty(p->
display, p->
root, net_client_list_stacking, XA_WINDOW, 32,
00838 PropModeReplace, (
unsigned char *) p->stacking,
00839 p->stacking_count);
00840 }
00841
00842
00843
void NETRootInfo::setKDESystemTrayWindows(Window *windows,
unsigned int count) {
00844
if (role != WindowManager)
return;
00845
00846 p->kde_system_tray_windows_count = count;
00847
delete [] p->kde_system_tray_windows;
00848 p->kde_system_tray_windows = nwindup(windows, count);
00849
00850
#ifdef NETWMDEBUG
00851
fprintf(stderr,
00852
"NETRootInfo::setKDESystemTrayWindows: setting list with %ld windows\n",
00853 p->kde_system_tray_windows_count);
00854
#endif
00855
00856 XChangeProperty(p->
display, p->
root, kde_net_system_tray_windows, XA_WINDOW, 32,
00857 PropModeReplace,
00858 (
unsigned char *) p->kde_system_tray_windows,
00859 p->kde_system_tray_windows_count);
00860 }
00861
00862
00863
void NETRootInfo::setNumberOfDesktops(
int numberOfDesktops) {
00864
00865
#ifdef NETWMDEBUG
00866
fprintf(stderr,
00867
"NETRootInfo::setNumberOfDesktops: setting desktop count to %d (%s)\n",
00868 numberOfDesktops, (role == WindowManager) ?
"WM" :
"Client");
00869
#endif
00870
00871
if (role == WindowManager) {
00872 p->number_of_desktops = numberOfDesktops;
00873
long d = numberOfDesktops;
00874 XChangeProperty(p->
display, p->
root, net_number_of_desktops, XA_CARDINAL, 32,
00875 PropModeReplace, (
unsigned char *) &d, 1);
00876 }
else {
00877 XEvent e;
00878
00879 e.xclient.type = ClientMessage;
00880 e.xclient.message_type = net_number_of_desktops;
00881 e.xclient.display = p->
display;
00882 e.xclient.window = p->
root;
00883 e.xclient.format = 32;
00884 e.xclient.data.l[0] = numberOfDesktops;
00885 e.xclient.data.l[1] = 0l;
00886 e.xclient.data.l[2] = 0l;
00887 e.xclient.data.l[3] = 0l;
00888 e.xclient.data.l[4] = 0l;
00889
00890 XSendEvent(p->
display, p->
root, False, netwm_sendevent_mask, &e);
00891 }
00892 }
00893
00894
00895
void NETRootInfo::setCurrentDesktop(
int desktop) {
00896
00897
#ifdef NETWMDEBUG
00898
fprintf(stderr,
00899
"NETRootInfo::setCurrentDesktop: setting current desktop = %d (%s)\n",
00900 desktop, (role == WindowManager) ?
"WM" :
"Client");
00901
#endif
00902
00903
if (role == WindowManager) {
00904 p->current_desktop = desktop;
00905
long d = p->current_desktop - 1;
00906 XChangeProperty(p->
display, p->
root, net_current_desktop, XA_CARDINAL, 32,
00907 PropModeReplace, (
unsigned char *) &d, 1);
00908 }
else {
00909 XEvent e;
00910
00911 e.xclient.type = ClientMessage;
00912 e.xclient.message_type = net_current_desktop;
00913 e.xclient.display = p->
display;
00914 e.xclient.window = p->
root;
00915 e.xclient.format = 32;
00916 e.xclient.data.l[0] = desktop - 1;
00917 e.xclient.data.l[1] = 0l;
00918 e.xclient.data.l[2] = 0l;
00919 e.xclient.data.l[3] = 0l;
00920 e.xclient.data.l[4] = 0l;
00921
00922 XSendEvent(p->
display, p->
root, False, netwm_sendevent_mask, &e);
00923 }
00924 }
00925
00926
00927
void NETRootInfo::setDesktopName(
int desktop,
const char *desktopName) {
00928
00929
if (desktop < 1)
return;
00930
00931
delete [] p->desktop_names[desktop - 1];
00932 p->desktop_names[desktop - 1] = nstrdup(desktopName);
00933
00934
unsigned int i, proplen,
00935 num = ((p->number_of_desktops > p->desktop_names.size()) ?
00936 p->number_of_desktops : p->desktop_names.size());
00937
for (i = 0, proplen = 0; i < num; i++)
00938 proplen += (p->desktop_names[i] != 0 ? strlen(p->desktop_names[i])+1 : 1 );
00939
00940
char *prop =
new char[proplen], *propp = prop;
00941
00942
for (i = 0; i < num; i++)
00943
if (p->desktop_names[i]) {
00944 strcpy(propp, p->desktop_names[i]);
00945 propp += strlen(p->desktop_names[i]) + 1;
00946 }
else
00947 *propp++ =
'\0';
00948
00949
#ifdef NETWMDEBUG
00950
fprintf(stderr,
00951
"NETRootInfo::setDesktopName(%d, '%s')\n"
00952
"NETRootInfo::setDesktopName: total property length = %d",
00953 desktop, desktopName, proplen);
00954
#endif
00955
00956 XChangeProperty(p->
display, p->
root, net_desktop_names, UTF8_STRING, 8,
00957 PropModeReplace, (
unsigned char *) prop, proplen);
00958
00959
delete [] prop;
00960 }
00961
00962
00963
void NETRootInfo::setDesktopGeometry(
int ,
const NETSize &geometry) {
00964
00965
#ifdef NETWMDEBUG
00966
fprintf(stderr,
"NETRootInfo::setDesktopGeometry( -- , { %d, %d }) (%s)\n",
00967 geometry.
width, geometry.
height, (role == WindowManager) ?
"WM" :
"Client");
00968
#endif
00969
00970
if (role == WindowManager) {
00971 p->geometry = geometry;
00972
00973
long data[2];
00974 data[0] = p->geometry.width;
00975 data[1] = p->geometry.height;
00976
00977 XChangeProperty(p->
display, p->
root, net_desktop_geometry, XA_CARDINAL, 32,
00978 PropModeReplace, (
unsigned char *) data, 2);
00979 }
else {
00980 XEvent e;
00981
00982 e.xclient.type = ClientMessage;
00983 e.xclient.message_type = net_desktop_geometry;
00984 e.xclient.display = p->
display;
00985 e.xclient.window = p->
root;
00986 e.xclient.format = 32;
00987 e.xclient.data.l[0] = geometry.
width;
00988 e.xclient.data.l[1] = geometry.
height;
00989 e.xclient.data.l[2] = 0l;
00990 e.xclient.data.l[3] = 0l;
00991 e.xclient.data.l[4] = 0l;
00992
00993 XSendEvent(p->
display, p->
root, False, netwm_sendevent_mask, &e);
00994 }
00995 }
00996
00997
00998
void NETRootInfo::setDesktopViewport(
int desktop,
const NETPoint &viewport) {
00999
01000
#ifdef NETWMDEBUG
01001
fprintf(stderr,
"NETRootInfo::setDesktopViewport(%d, { %d, %d }) (%s)\n",
01002 desktop, viewport.
x, viewport.
y, (role == WindowManager) ?
"WM" :
"Client");
01003
#endif
01004
01005
if (desktop < 1)
return;
01006
01007
if (role == WindowManager) {
01008 p->viewport[desktop - 1] = viewport;
01009
01010
int d, i, l;
01011 l = p->number_of_desktops * 2;
01012
long *data =
new long[l];
01013
for (d = 0, i = 0; d < p->number_of_desktops; d++) {
01014 data[i++] = p->viewport[d].x;
01015 data[i++] = p->viewport[d].y;
01016 }
01017
01018 XChangeProperty(p->
display, p->
root, net_desktop_viewport, XA_CARDINAL, 32,
01019 PropModeReplace, (
unsigned char *) data, l);
01020
01021
delete [] data;
01022 }
else {
01023 XEvent e;
01024
01025 e.xclient.type = ClientMessage;
01026 e.xclient.message_type = net_desktop_viewport;
01027 e.xclient.display = p->
display;
01028 e.xclient.window = p->
root;
01029 e.xclient.format = 32;
01030 e.xclient.data.l[0] = viewport.
x;
01031 e.xclient.data.l[1] = viewport.
y;
01032 e.xclient.data.l[2] = 0l;
01033 e.xclient.data.l[3] = 0l;
01034 e.xclient.data.l[4] = 0l;
01035
01036 XSendEvent(p->
display, p->
root, False, netwm_sendevent_mask, &e);
01037 }
01038 }
01039
01040
01041
void NETRootInfo::setSupported() {
01042
if (role != WindowManager) {
01043
#ifdef NETWMDEBUG
01044
fprintf(stderr,
"NETRootInfo::setSupported - role != WindowManager\n");
01045
#endif
01046
01047
return;
01048 }
01049
01050 Atom atoms[netAtomCount];
01051
int pnum = 2;
01052
01053
01054 atoms[0] = net_supported;
01055 atoms[1] = net_supporting_wm_check;
01056
01057
if (p->
properties[ PROTOCOLS ] & ClientList)
01058 atoms[pnum++] = net_client_list;
01059
01060
if (p->
properties[ PROTOCOLS ] & ClientListStacking)
01061 atoms[pnum++] = net_client_list_stacking;
01062
01063
if (p->
properties[ PROTOCOLS ] & NumberOfDesktops)
01064 atoms[pnum++] = net_number_of_desktops;
01065
01066
if (p->
properties[ PROTOCOLS ] & DesktopGeometry)
01067 atoms[pnum++] = net_desktop_geometry;
01068
01069
if (p->
properties[ PROTOCOLS ] & DesktopViewport)
01070 atoms[pnum++] = net_desktop_viewport;
01071
01072
if (p->
properties[ PROTOCOLS ] & CurrentDesktop)
01073 atoms[pnum++] = net_current_desktop;
01074
01075
if (p->
properties[ PROTOCOLS ] & DesktopNames)
01076 atoms[pnum++] = net_desktop_names;
01077
01078
if (p->
properties[ PROTOCOLS ] & ActiveWindow)
01079 atoms[pnum++] = net_active_window;
01080
01081
if (p->
properties[ PROTOCOLS ] & WorkArea)
01082 atoms[pnum++] = net_workarea;
01083
01084
if (p->
properties[ PROTOCOLS ] & VirtualRoots)
01085 atoms[pnum++] = net_virtual_roots;
01086
01087
if (p->
properties[ PROTOCOLS ] & CloseWindow)
01088 atoms[pnum++] = net_close_window;
01089
01090
if (p->
properties[ PROTOCOLS2 ] & WM2RestackWindow)
01091 atoms[pnum++] = net_restack_window;
01092
01093
01094
if (p->
properties[ PROTOCOLS ] & WMMoveResize)
01095 atoms[pnum++] = net_wm_moveresize;
01096
01097
if (p->
properties[ PROTOCOLS2 ] & WM2MoveResizeWindow)
01098 atoms[pnum++] = net_moveresize_window;
01099
01100
if (p->
properties[ PROTOCOLS ] & WMName)
01101 atoms[pnum++] = net_wm_name;
01102
01103
if (p->
properties[ PROTOCOLS ] & WMVisibleName)
01104 atoms[pnum++] = net_wm_visible_name;
01105
01106
if (p->
properties[ PROTOCOLS ] & WMIconName)
01107 atoms[pnum++] = net_wm_icon_name;
01108
01109
if (p->
properties[ PROTOCOLS ] & WMVisibleIconName)
01110 atoms[pnum++] = net_wm_visible_icon_name;
01111
01112
if (p->
properties[ PROTOCOLS ] & WMDesktop)
01113 atoms[pnum++] = net_wm_desktop;
01114
01115
if (p->
properties[ PROTOCOLS ] & WMWindowType) {
01116 atoms[pnum++] = net_wm_window_type;
01117
01118
01119
if (p->
properties[ WINDOW_TYPES ] & NormalMask)
01120 atoms[pnum++] = net_wm_window_type_normal;
01121
if (p->
properties[ WINDOW_TYPES ] & DesktopMask)
01122 atoms[pnum++] = net_wm_window_type_desktop;
01123
if (p->
properties[ WINDOW_TYPES ] & DockMask)
01124 atoms[pnum++] = net_wm_window_type_dock;
01125
if (p->
properties[ WINDOW_TYPES ] & ToolbarMask)
01126 atoms[pnum++] = net_wm_window_type_toolbar;
01127
if (p->
properties[ WINDOW_TYPES ] & MenuMask)
01128 atoms[pnum++] = net_wm_window_type_menu;
01129
if (p->
properties[ WINDOW_TYPES ] & DialogMask)
01130 atoms[pnum++] = net_wm_window_type_dialog;
01131
if (p->
properties[ WINDOW_TYPES ] & UtilityMask)
01132 atoms[pnum++] = net_wm_window_type_utility;
01133
if (p->
properties[ WINDOW_TYPES ] & SplashMask)
01134 atoms[pnum++] = net_wm_window_type_splash;
01135
01136
if (p->
properties[ WINDOW_TYPES ] & OverrideMask)
01137 atoms[pnum++] = kde_net_wm_window_type_override;
01138
if (p->
properties[ WINDOW_TYPES ] & TopMenuMask)
01139 atoms[pnum++] = kde_net_wm_window_type_topmenu;
01140 }
01141
01142
if (p->
properties[ PROTOCOLS ] & WMState) {
01143 atoms[pnum++] = net_wm_state;
01144
01145
01146
if (p->
properties[ STATES ] & Modal)
01147 atoms[pnum++] = net_wm_state_modal;
01148
if (p->
properties[ STATES ] & Sticky)
01149 atoms[pnum++] = net_wm_state_sticky;
01150
if (p->
properties[ STATES ] & MaxVert)
01151 atoms[pnum++] = net_wm_state_max_vert;
01152
if (p->
properties[ STATES ] & MaxHoriz)
01153 atoms[pnum++] = net_wm_state_max_horiz;
01154
if (p->
properties[ STATES ] & Shaded)
01155 atoms[pnum++] = net_wm_state_shaded;
01156
if (p->
properties[ STATES ] & SkipTaskbar)
01157 atoms[pnum++] = net_wm_state_skip_taskbar;
01158
if (p->
properties[ STATES ] & SkipPager)
01159 atoms[pnum++] = net_wm_state_skip_pager;
01160
if (p->
properties[ STATES ] & Hidden)
01161 atoms[pnum++] = net_wm_state_hidden;
01162
if (p->
properties[ STATES ] &
FullScreen)
01163 atoms[pnum++] = net_wm_state_fullscreen;
01164
if (p->
properties[ STATES ] & KeepAbove)
01165 atoms[pnum++] = net_wm_state_above;
01166
if (p->
properties[ STATES ] & KeepBelow)
01167 atoms[pnum++] = net_wm_state_below;
01168
if (p->
properties[ STATES ] & DemandsAttention)
01169 atoms[pnum++] = net_wm_state_demands_attention;
01170
01171
if (p->
properties[ STATES ] & StaysOnTop)
01172 atoms[pnum++] = net_wm_state_stays_on_top;
01173 }
01174
01175
if (p->
properties[ PROTOCOLS ] & WMStrut)
01176 atoms[pnum++] = net_wm_strut;
01177
01178
if (p->
properties[ PROTOCOLS ] & WMIconGeometry)
01179 atoms[pnum++] = net_wm_icon_geometry;
01180
01181
if (p->
properties[ PROTOCOLS ] & WMIcon)
01182 atoms[pnum++] = net_wm_icon;
01183
01184
if (p->
properties[ PROTOCOLS ] & WMPid)
01185 atoms[pnum++] = net_wm_pid;
01186
01187
if (p->
properties[ PROTOCOLS ] & WMHandledIcons)
01188 atoms[pnum++] = net_wm_handled_icons;
01189
01190
if (p->
properties[ PROTOCOLS ] & WMPing)
01191 atoms[pnum++] = net_wm_ping;
01192
01193
if (p->
properties[ PROTOCOLS2 ] & WM2UserTime)
01194 atoms[pnum++] = net_wm_user_time;
01195
01196
if (p->
properties[ PROTOCOLS2 ] & WM2StartupId)
01197 atoms[pnum++] = net_startup_id;
01198
01199
if (p->
properties[ PROTOCOLS2 ] & WM2AllowedActions) {
01200 atoms[pnum++] = net_wm_allowed_actions;
01201
01202
01203
if (p->
properties[ ACTIONS ] & ActionMove)
01204 atoms[pnum++] = net_wm_action_move;
01205
if (p->
properties[ ACTIONS ] & ActionResize)
01206 atoms[pnum++] = net_wm_action_resize;
01207
if (p->
properties[ ACTIONS ] & ActionMinimize)
01208 atoms[pnum++] = net_wm_action_minimize;
01209
if (p->
properties[ ACTIONS ] & ActionShade)
01210 atoms[pnum++] = net_wm_action_shade;
01211
if (p->
properties[ ACTIONS ] & ActionStick)
01212 atoms[pnum++] = net_wm_action_stick;
01213
if (p->
properties[ ACTIONS ] & ActionMaxVert)
01214 atoms[pnum++] = net_wm_action_max_vert;
01215
if (p->
properties[ ACTIONS ] & ActionMaxHoriz)
01216 atoms[pnum++] = net_wm_action_max_horiz;
01217
if (p->
properties[ ACTIONS ] & ActionFullScreen)
01218 atoms[pnum++] = net_wm_action_fullscreen;
01219
if (p->
properties[ ACTIONS ] & ActionChangeDesktop)
01220 atoms[pnum++] = net_wm_action_change_desk;
01221
if (p->
properties[ ACTIONS ] & ActionClose)
01222 atoms[pnum++] = net_wm_action_close;
01223 }
01224
01225
01226
if (p->
properties[ PROTOCOLS ] & KDESystemTrayWindows)
01227 atoms[pnum++] = kde_net_system_tray_windows;
01228
01229
if (p->
properties[ PROTOCOLS ] & WMKDESystemTrayWinFor)
01230 atoms[pnum++] = kde_net_wm_system_tray_window_for;
01231
01232
if (p->
properties[ PROTOCOLS ] & WMKDEFrameStrut)
01233 atoms[pnum++] = kde_net_wm_frame_strut;
01234
01235 XChangeProperty(p->
display, p->
root, net_supported, XA_ATOM, 32,
01236 PropModeReplace, (
unsigned char *) atoms, pnum);
01237 XChangeProperty(p->
display, p->
root, net_supporting_wm_check, XA_WINDOW, 32,
01238 PropModeReplace, (
unsigned char *) &(p->supportwindow), 1);
01239
01240
#ifdef NETWMDEBUG
01241
fprintf(stderr,
01242
"NETRootInfo::setSupported: _NET_SUPPORTING_WM_CHECK = 0x%lx on 0x%lx\n"
01243
" : _NET_WM_NAME = '%s' on 0x%lx\n",
01244 p->supportwindow, p->supportwindow, p->
name, p->supportwindow);
01245
#endif
01246
01247 XChangeProperty(p->
display, p->supportwindow, net_supporting_wm_check,
01248 XA_WINDOW, 32, PropModeReplace,
01249 (
unsigned char *) &(p->supportwindow), 1);
01250 XChangeProperty(p->
display, p->supportwindow, net_wm_name, UTF8_STRING, 8,
01251 PropModeReplace, (
unsigned char *) p->
name,
01252 strlen(p->
name));
01253 }
01254
01255
void NETRootInfo::updateSupportedProperties( Atom atom )
01256 {
01257
if( atom == net_supported )
01258 p->
properties[ PROTOCOLS ] |= Supported;
01259
01260
else if( atom == net_supporting_wm_check )
01261 p->
properties[ PROTOCOLS ] |= SupportingWMCheck;
01262
01263
else if( atom == net_client_list )
01264 p->
properties[ PROTOCOLS ] |= ClientList;
01265
01266
else if( atom == net_client_list_stacking )
01267 p->
properties[ PROTOCOLS ] |= ClientListStacking;
01268
01269
else if( atom == net_number_of_desktops )
01270 p->
properties[ PROTOCOLS ] |= NumberOfDesktops;
01271
01272
else if( atom == net_desktop_geometry )
01273 p->
properties[ PROTOCOLS ] |= DesktopGeometry;
01274
01275
else if( atom == net_desktop_viewport )
01276 p->
properties[ PROTOCOLS ] |= DesktopViewport;
01277
01278
else if( atom == net_current_desktop )
01279 p->
properties[ PROTOCOLS ] |= CurrentDesktop;
01280
01281
else if( atom == net_desktop_names )
01282 p->
properties[ PROTOCOLS ] |= DesktopNames;
01283
01284
else if( atom == net_active_window )
01285 p->
properties[ PROTOCOLS ] |= ActiveWindow;
01286
01287
else if( atom == net_workarea )
01288 p->
properties[ PROTOCOLS ] |= WorkArea;
01289
01290
else if( atom == net_virtual_roots )
01291 p->
properties[ PROTOCOLS ] |= VirtualRoots;
01292
01293
else if( atom == net_close_window )
01294 p->
properties[ PROTOCOLS ] |= CloseWindow;
01295
01296
else if( atom == net_restack_window )
01297 p->
properties[ PROTOCOLS2 ] |= WM2RestackWindow;
01298
01299
01300
01301
else if( atom == net_wm_moveresize )
01302 p->
properties[ PROTOCOLS ] |= WMMoveResize;
01303
01304
else if( atom == net_moveresize_window )
01305 p->
properties[ PROTOCOLS2 ] |= WM2MoveResizeWindow;
01306
01307
else if( atom == net_wm_name )
01308 p->
properties[ PROTOCOLS ] |= WMName;
01309
01310
else if( atom == net_wm_visible_name )
01311 p->
properties[ PROTOCOLS ] |= WMVisibleName;
01312
01313
else if( atom == net_wm_icon_name )
01314 p->
properties[ PROTOCOLS ] |= WMIconName;
01315
01316
else if( atom == net_wm_visible_icon_name )
01317 p->
properties[ PROTOCOLS ] |= WMVisibleIconName;
01318
01319
else if( atom == net_wm_desktop )
01320 p->
properties[ PROTOCOLS ] |= WMDesktop;
01321
01322
else if( atom == net_wm_window_type )
01323 p->
properties[ PROTOCOLS ] |= WMWindowType;
01324
01325
01326
else if( atom == net_wm_window_type_normal )
01327 p->
properties[ WINDOW_TYPES ] |= NormalMask;
01328
else if( atom == net_wm_window_type_desktop )
01329 p->
properties[ WINDOW_TYPES ] |= DesktopMask;
01330
else if( atom == net_wm_window_type_dock )
01331 p->
properties[ WINDOW_TYPES ] |= DockMask;
01332
else if( atom == net_wm_window_type_toolbar )
01333 p->
properties[ WINDOW_TYPES ] |= ToolbarMask;
01334
else if( atom == net_wm_window_type_menu )
01335 p->
properties[ WINDOW_TYPES ] |= MenuMask;
01336
else if( atom == net_wm_window_type_dialog )
01337 p->
properties[ WINDOW_TYPES ] |= DialogMask;
01338
else if( atom == net_wm_window_type_utility )
01339 p->
properties[ WINDOW_TYPES ] |= UtilityMask;
01340
else if( atom == net_wm_window_type_splash )
01341 p->
properties[ WINDOW_TYPES ] |= SplashMask;
01342
01343
else if( atom == kde_net_wm_window_type_override )
01344 p->
properties[ WINDOW_TYPES ] |= OverrideMask;
01345
else if( atom == kde_net_wm_window_type_topmenu )
01346 p->
properties[ WINDOW_TYPES ] |= TopMenuMask;
01347
01348
else if( atom == net_wm_state )
01349 p->
properties[ PROTOCOLS ] |= WMState;
01350
01351
01352
else if( atom == net_wm_state_modal )
01353 p->
properties[ STATES ] |= Modal;
01354
else if( atom == net_wm_state_sticky )
01355 p->
properties[ STATES ] |= Sticky;
01356
else if( atom == net_wm_state_max_vert )
01357 p->
properties[ STATES ] |= MaxVert;
01358
else if( atom == net_wm_state_max_horiz )
01359 p->
properties[ STATES ] |= MaxHoriz;
01360
else if( atom == net_wm_state_shaded )
01361 p->
properties[ STATES ] |= Shaded;
01362
else if( atom == net_wm_state_skip_taskbar )
01363 p->
properties[ STATES ] |= SkipTaskbar;
01364
else if( atom == net_wm_state_skip_pager )
01365 p->
properties[ STATES ] |= SkipPager;
01366
else if( atom == net_wm_state_hidden )
01367 p->
properties[ STATES ] |= Hidden;
01368
else if( atom == net_wm_state_fullscreen )
01369 p->
properties[ STATES ] |=
FullScreen;
01370
else if( atom == net_wm_state_above )
01371 p->
properties[ STATES ] |= KeepAbove;
01372
else if( atom == net_wm_state_below )
01373 p->
properties[ STATES ] |= KeepBelow;
01374
else if( atom == net_wm_state_demands_attention )
01375 p->
properties[ STATES ] |= DemandsAttention;
01376
01377
else if( atom == net_wm_state_stays_on_top )
01378 p->
properties[ STATES ] |= StaysOnTop;
01379
01380
else if( atom == net_wm_strut )
01381 p->
properties[ PROTOCOLS ] |= WMStrut;
01382
01383
else if( atom == net_wm_icon_geometry )
01384 p->
properties[ PROTOCOLS ] |= WMIconGeometry;
01385
01386
else if( atom == net_wm_icon )
01387 p->
properties[ PROTOCOLS ] |= WMIcon;
01388
01389
else if( atom == net_wm_pid )
01390 p->
properties[ PROTOCOLS ] |= WMPid;
01391
01392
else if( atom == net_wm_handled_icons )
01393 p->
properties[ PROTOCOLS ] |= WMHandledIcons;
01394
01395
else if( atom == net_wm_ping )
01396 p->
properties[ PROTOCOLS ] |= WMPing;
01397
01398
else if( atom == net_wm_user_time )
01399 p->
properties[ PROTOCOLS2 ] |= WM2UserTime;
01400
01401
else if( atom == net_startup_id )
01402 p->
properties[ PROTOCOLS2 ] |= WM2StartupId;
01403
01404
else if( atom == net_wm_allowed_actions )
01405 p->
properties[ PROTOCOLS2 ] |= WM2AllowedActions;
01406
01407
01408
else if( atom == net_wm_action_move )
01409 p->
properties[ ACTIONS ] |= ActionMove;
01410
else if( atom == net_wm_action_resize )
01411 p->
properties[ ACTIONS ] |= ActionResize;
01412
else if( atom == net_wm_action_minimize )
01413 p->
properties[ ACTIONS ] |= ActionMinimize;
01414
else if( atom == net_wm_action_shade )
01415 p->
properties[ ACTIONS ] |= ActionShade;
01416
else if( atom == net_wm_action_stick )
01417 p->
properties[ ACTIONS ] |= ActionStick;
01418
else if( atom == net_wm_action_max_vert )
01419 p->
properties[ ACTIONS ] |= ActionMaxVert;
01420
else if( atom == net_wm_action_max_horiz )
01421 p->
properties[ ACTIONS ] |= ActionMaxHoriz;
01422
else if( atom == net_wm_action_fullscreen )
01423 p->
properties[ ACTIONS ] |= ActionFullScreen;
01424
else if( atom == net_wm_action_change_desk )
01425 p->
properties[ ACTIONS ] |= ActionChangeDesktop;
01426
else if( atom == net_wm_action_close )
01427 p->
properties[ ACTIONS ] |= ActionClose;
01428
01429
01430
else if( atom == kde_net_system_tray_windows )
01431 p->
properties[ PROTOCOLS ] |= KDESystemTrayWindows;
01432
01433
else if( atom == kde_net_wm_system_tray_window_for )
01434 p->
properties[ PROTOCOLS ] |= WMKDESystemTrayWinFor;
01435
01436
else if( atom == kde_net_wm_frame_strut )
01437 p->
properties[ PROTOCOLS ] |= WMKDEFrameStrut;
01438 }
01439
01440
extern Time qt_x_user_time;
01441
void NETRootInfo::setActiveWindow(Window window) {
01442 setActiveWindow( window, FromUnknown, qt_x_user_time, None );
01443 }
01444
01445
void NETRootInfo::setActiveWindow(Window window, NET::RequestSource src,
01446 Time timestamp, Window active_window ) {
01447
01448
#ifdef NETWMDEBUG
01449
fprintf(stderr,
"NETRootInfo::setActiveWindow(0x%lx) (%s)\n",
01450 window, (role == WindowManager) ?
"WM" :
"Client");
01451
#endif
01452
01453
if (role == WindowManager) {
01454 p->active = window;
01455 XChangeProperty(p->
display, p->
root, net_active_window, XA_WINDOW, 32,
01456 PropModeReplace, (
unsigned char *) &(p->active), 1);
01457 }
else {
01458 XEvent e;
01459
01460 e.xclient.type = ClientMessage;
01461 e.xclient.message_type = net_active_window;
01462 e.xclient.display = p->
display;
01463 e.xclient.window = window;
01464 e.xclient.format = 32;
01465 e.xclient.data.l[0] = src;
01466 e.xclient.data.l[1] = timestamp;
01467 e.xclient.data.l[2] = active_window;
01468 e.xclient.data.l[3] = 0l;
01469 e.xclient.data.l[4] = 0l;
01470
01471 XSendEvent(p->
display, p->
root, False, netwm_sendevent_mask, &e);
01472 }
01473 }
01474
01475
01476
void NETRootInfo::setWorkArea(
int desktop,
const NETRect &workarea) {
01477
01478
#ifdef NETWMDEBUG
01479
fprintf(stderr,
"NETRootInfo::setWorkArea(%d, { %d, %d, %d, %d }) (%s)\n",
01480 desktop, workarea.
pos.
x, workarea.
pos.
y, workarea.
size.
width, workarea.
size.
height,
01481 (role == WindowManager) ?
"WM" :
"Client");
01482
#endif
01483
01484
if (role != WindowManager || desktop < 1)
return;
01485
01486 p->workarea[desktop - 1] = workarea;
01487
01488
long *wa =
new long[p->number_of_desktops * 4];
01489
int i, o;
01490
for (i = 0, o = 0; i < p->number_of_desktops; i++) {
01491 wa[o++] = p->workarea[i].pos.x;
01492 wa[o++] = p->workarea[i].pos.y;
01493 wa[o++] = p->workarea[i].size.width;
01494 wa[o++] = p->workarea[i].size.height;
01495 }
01496
01497 XChangeProperty(p->
display, p->
root, net_workarea, XA_CARDINAL, 32,
01498 PropModeReplace, (
unsigned char *) wa,
01499 p->number_of_desktops * 4);
01500
01501
delete [] wa;
01502 }
01503
01504
01505
void NETRootInfo::setVirtualRoots(Window *windows,
unsigned int count) {
01506
if (role != WindowManager)
return;
01507
01508 p->virtual_roots_count = count;
01509 p->virtual_roots = windows;
01510
01511
#ifdef NETWMDEBUG
01512
fprintf(stderr,
"NETRootInfo::setVirtualRoots: setting list with %ld windows\n",
01513 p->virtual_roots_count);
01514
#endif
01515
01516 XChangeProperty(p->
display, p->
root, net_virtual_roots, XA_WINDOW, 32,
01517 PropModeReplace, (
unsigned char *) p->virtual_roots,
01518 p->virtual_roots_count);
01519 }
01520
01521
01522
void NETRootInfo::closeWindowRequest(Window window) {
01523
01524
#ifdef NETWMDEBUG
01525
fprintf(stderr,
"NETRootInfo::closeWindowRequest: requesting close for 0x%lx\n",
01526 window);
01527
#endif
01528
01529 XEvent e;
01530
01531 e.xclient.type = ClientMessage;
01532 e.xclient.message_type = net_close_window;
01533 e.xclient.display = p->
display;
01534 e.xclient.window = window;
01535 e.xclient.format = 32;
01536 e.xclient.data.l[0] = 0l;
01537 e.xclient.data.l[1] = 0l;
01538 e.xclient.data.l[2] = 0l;
01539 e.xclient.data.l[3] = 0l;
01540 e.xclient.data.l[4] = 0l;
01541
01542 XSendEvent(p->
display, p->
root, False, netwm_sendevent_mask, &e);
01543 }
01544
01545
01546
void NETRootInfo::moveResizeRequest(Window window,
int x_root,
int y_root,
01547 Direction direction)
01548 {
01549
01550
#ifdef NETWMDEBUG
01551
fprintf(stderr,
01552
"NETRootInfo::moveResizeRequest: requesting resize/move for 0x%lx (%d, %d, %d)\n",
01553 window, x_root, y_root, direction);
01554
#endif
01555
01556 XEvent e;
01557
01558 e.xclient.type = ClientMessage;
01559 e.xclient.message_type = net_wm_moveresize;
01560 e.xclient.display = p->
display;
01561 e.xclient.window = window,
01562 e.xclient.format = 32;
01563 e.xclient.data.l[0] = x_root;
01564 e.xclient.data.l[1] = y_root;
01565 e.xclient.data.l[2] = direction;
01566 e.xclient.data.l[3] = 0l;
01567 e.xclient.data.l[4] = 0l;
01568
01569 XSendEvent(p->
display, p->
root, False, netwm_sendevent_mask, &e);
01570 }
01571
01572
void NETRootInfo::moveResizeWindowRequest(Window window,
int flags,
int x,
int y,
int width,
int height )
01573 {
01574
01575
#ifdef NETWMDEBUG
01576
fprintf(stderr,
01577
"NETRootInfo::moveResizeWindowRequest: resizing/moving 0x%lx (%d, %d, %d, %d, %d)\n",
01578 window, flags, x, y, width, height);
01579
#endif
01580
01581 XEvent e;
01582
01583 e.xclient.type = ClientMessage;
01584 e.xclient.message_type = net_moveresize_window;
01585 e.xclient.display = p->
display;
01586 e.xclient.window = window,
01587 e.xclient.format = 32;
01588 e.xclient.data.l[0] = flags;
01589 e.xclient.data.l[1] = x;
01590 e.xclient.data.l[2] = y;
01591 e.xclient.data.l[3] = width;
01592 e.xclient.data.l[4] = height;
01593
01594 XSendEvent(p->
display, p->
root, False, netwm_sendevent_mask, &e);
01595 }
01596
01597
void NETRootInfo::restackRequest(Window window, Window above,
int detail)
01598 {
01599
#ifdef NETWMDEBUG
01600
fprintf(stderr,
01601
"NETRootInfo::restackRequest: requesting restack for 0x%lx (%lx, %d)\n",
01602 window, above, detail);
01603
#endif
01604
01605 XEvent e;
01606
01607 e.xclient.type = ClientMessage;
01608 e.xclient.message_type = net_restack_window;
01609 e.xclient.display = p->
display;
01610 e.xclient.window = window,
01611 e.xclient.format = 32;
01612 e.xclient.data.l[0] = FromTool;
01613 e.xclient.data.l[1] = above;
01614 e.xclient.data.l[2] = detail;
01615 e.xclient.data.l[3] = 0l;
01616 e.xclient.data.l[4] = 0l;
01617
01618 XSendEvent(p->
display, p->
root, False, netwm_sendevent_mask, &e);
01619 }
01620
01621
void NETRootInfo2::sendPing( Window window, Time timestamp )
01622 {
01623
if (role != WindowManager)
return;
01624
#ifdef NETWMDEBUG
01625
fprintf(stderr,
"NETRootInfo2::setPing: window 0x%lx, timestamp %lu\n",
01626 window, timestamp );
01627
#endif
01628
XEvent e;
01629 e.xclient.type = ClientMessage;
01630 e.xclient.message_type = wm_protocols;
01631 e.xclient.display = p->
display;
01632 e.xclient.window = window,
01633 e.xclient.format = 32;
01634 e.xclient.data.l[0] = net_wm_ping;
01635 e.xclient.data.l[1] = timestamp;
01636 e.xclient.data.l[2] = window;
01637 e.xclient.data.l[3] = 0;
01638 e.xclient.data.l[4] = 0;
01639
01640 XSendEvent(p->
display, window, False, 0, &e);
01641 }
01642
01643
01644
01645
01646
01647
const NETRootInfo &NETRootInfo::operator=(
const NETRootInfo &rootinfo) {
01648
01649
#ifdef NETWMDEBUG
01650
fprintf(stderr,
"NETRootInfo::operator=()\n");
01651
#endif
01652
01653
if (p != rootinfo.p) {
01654 refdec_nri(p);
01655
01656
if (! p->
ref)
delete p;
01657 }
01658
01659 p = rootinfo.p;
01660 role = rootinfo.role;
01661 p->
ref++;
01662
01663
return *
this;
01664 }
01665
01666
unsigned long NETRootInfo::event(XEvent *ev )
01667 {
01668
unsigned long props[ 1 ];
01669
event( ev, props, 1 );
01670
return props[ 0 ];
01671 }
01672
01673
void NETRootInfo::event(XEvent *event,
unsigned long* properties,
int properties_size )
01674 {
01675
unsigned long props[ PROPERTIES_SIZE ] = { 0, 0, 0, 0, 0 };
01676 assert( PROPERTIES_SIZE == 5 );
01677
unsigned long& dirty = props[ PROTOCOLS ];
01678
unsigned long& dirty2 = props[ PROTOCOLS2 ];
01679
bool do_update =
false;
01680
01681 Q_UNUSED( dirty2 );
01682
01683
01684
01685
if (role == WindowManager &&
event->type == ClientMessage &&
01686
event->xclient.format == 32) {
01687
#ifdef NETWMDEBUG
01688
fprintf(stderr,
"NETRootInfo::event: handling ClientMessage event\n");
01689
#endif
01690
01691
if (
event->xclient.message_type == net_number_of_desktops) {
01692 dirty = NumberOfDesktops;
01693
01694
#ifdef NETWMDEBUG
01695
fprintf(stderr,
"NETRootInfo::event: changeNumberOfDesktops(%ld)\n",
01696
event->xclient.data.l[0]);
01697
#endif
01698
01699 changeNumberOfDesktops(
event->xclient.data.l[0]);
01700 }
else if (
event->xclient.message_type == net_desktop_geometry) {
01701 dirty = DesktopGeometry;
01702
01703
NETSize sz;
01704 sz.
width =
event->xclient.data.l[0];
01705 sz.
height =
event->xclient.data.l[1];
01706
01707
#ifdef NETWMDEBUG
01708
fprintf(stderr,
"NETRootInfo::event: changeDesktopGeometry( -- , { %d, %d })\n",
01709 sz.
width, sz.
height);
01710
#endif
01711
01712 changeDesktopGeometry(~0, sz);
01713 }
else if (
event->xclient.message_type == net_desktop_viewport) {
01714 dirty = DesktopViewport;
01715
01716
NETPoint pt;
01717 pt.
x =
event->xclient.data.l[0];
01718 pt.
y =
event->xclient.data.l[1];
01719
01720
#ifdef NETWMDEBUG
01721
fprintf(stderr,
"NETRootInfo::event: changeDesktopViewport(%d, { %d, %d })\n",
01722 p->current_desktop, pt.
x, pt.
y);
01723
#endif
01724
01725 changeDesktopViewport(p->current_desktop, pt);
01726 }
else if (
event->xclient.message_type == net_current_desktop) {
01727 dirty = CurrentDesktop;
01728
01729
#ifdef NETWMDEBUG
01730
fprintf(stderr,
"NETRootInfo::event: changeCurrentDesktop(%ld)\n",
01731
event->xclient.data.l[0] + 1);
01732
#endif
01733
01734 changeCurrentDesktop(
event->xclient.data.l[0] + 1);
01735 }
else if (
event->xclient.message_type == net_active_window) {
01736 dirty = ActiveWindow;
01737
01738
#ifdef NETWMDEBUG
01739
fprintf(stderr,
"NETRootInfo::event: changeActiveWindow(0x%lx)\n",
01740
event->xclient.window);
01741
#endif
01742
01743 changeActiveWindow(
event->xclient.window);
01744
if( NETRootInfo2* this2 = dynamic_cast< NETRootInfo2* >(
this ))
01745 {
01746 RequestSource src = FromUnknown;
01747 Time timestamp = CurrentTime;
01748 Window active_window = None;
01749
01750
if(
event->xclient.data.l[0] >= FromUnknown
01751 &&
event->xclient.data.l[0] <= FromTool )
01752 {
01753 src = static_cast< RequestSource >(
event->xclient.data.l[0] );
01754 timestamp =
event->xclient.data.l[1];
01755 active_window =
event->xclient.data.l[2];
01756 }
01757 this2->changeActiveWindow(
event->xclient.window, src, timestamp, active_window );
01758 }
01759 }
else if (
event->xclient.message_type == net_wm_moveresize) {
01760
01761
#ifdef NETWMDEBUG
01762
fprintf(stderr,
"NETRootInfo::event: moveResize(%ld, %ld, %ld, %ld)\n",
01763
event->xclient.window,
01764
event->xclient.data.l[0],
01765
event->xclient.data.l[1],
01766
event->xclient.data.l[2]
01767 );
01768
#endif
01769
01770 moveResize(
event->xclient.window,
01771
event->xclient.data.l[0],
01772
event->xclient.data.l[1],
01773
event->xclient.data.l[2]);
01774 }
else if (
event->xclient.message_type == net_moveresize_window) {
01775
01776
#ifdef NETWMDEBUG
01777
fprintf(stderr,
"NETRootInfo::event: moveResizeWindow(%ld, %ld, %ld, %ld, %ld, %ld)\n",
01778
event->xclient.window,
01779
event->xclient.data.l[0],
01780
event->xclient.data.l[1],
01781
event->xclient.data.l[2],
01782
event->xclient.data.l[3],
01783
event->xclient.data.l[4]
01784 );
01785
#endif
01786
01787
if( NETRootInfo2* this2 = dynamic_cast< NETRootInfo2* >(
this ))
01788 this2->moveResizeWindow(
event->xclient.window,
01789
event->xclient.data.l[0],
01790
event->xclient.data.l[1],
01791
event->xclient.data.l[2],
01792
event->xclient.data.l[3],
01793
event->xclient.data.l[4]);
01794 }
else if (
event->xclient.message_type == net_close_window) {
01795
01796
#ifdef NETWMDEBUG
01797
fprintf(stderr,
"NETRootInfo::event: closeWindow(0x%lx)\n",
01798
event->xclient.window);
01799
#endif
01800
01801 closeWindow(
event->xclient.window);
01802 }
else if (
event->xclient.message_type == net_restack_window) {
01803
01804
#ifdef NETWMDEBUG
01805
fprintf(stderr,
"NETRootInfo::event: restackWindow(0x%lx)\n",
01806
event->xclient.window);
01807
#endif
01808
01809
if( NETRootInfo2* this2 = dynamic_cast< NETRootInfo2* >(
this ))
01810 this2->restackWindow(
event->xclient.window,
01811
event->xclient.data.l[1],
event->xclient.data.l[2]);
01812 }
else if (
event->xclient.message_type == wm_protocols
01813 && (Atom)
event->xclient.data.l[ 0 ] == net_wm_ping) {
01814 dirty = WMPing;
01815
01816
#ifdef NETWMDEBUG
01817
fprintf(stderr,
"NETRootInfo2::event: gotPing(0x%lx,%lu)\n",
01818
event->xclient.window,
event->xclient.data.l[1]);
01819
#endif
01820
if( NETRootInfo2* this2 = dynamic_cast< NETRootInfo2* >(
this ))
01821 this2->gotPing(
event->xclient.data.l[2],
event->xclient.data.l[1]);
01822 }
01823 }
01824
01825
if (
event->type == PropertyNotify) {
01826
01827
#ifdef NETWMDEBUG
01828
fprintf(stderr,
"NETRootInfo::event: handling PropertyNotify event\n");
01829
#endif
01830
01831 XEvent pe = *
event;
01832
01833 Bool done = False;
01834 Bool compaction = False;
01835
while (! done) {
01836
01837
#ifdef NETWMDEBUG
01838
fprintf(stderr,
"NETRootInfo::event: loop fire\n");
01839
#endif
01840
01841
if (pe.xproperty.atom == net_client_list)
01842 dirty |= ClientList;
01843
else if (pe.xproperty.atom == net_client_list_stacking)
01844 dirty |= ClientListStacking;
01845
else if (pe.xproperty.atom == kde_net_system_tray_windows)
01846 dirty |= KDESystemTrayWindows;
01847
else if (pe.xproperty.atom == net_desktop_names)
01848 dirty |= DesktopNames;
01849
else if (pe.xproperty.atom == net_workarea)
01850 dirty |= WorkArea;
01851
else if (pe.xproperty.atom == net_number_of_desktops)
01852 dirty |= NumberOfDesktops;
01853
else if (pe.xproperty.atom == net_desktop_geometry)
01854 dirty |= DesktopGeometry;
01855
else if (pe.xproperty.atom == net_desktop_viewport)
01856 dirty |= DesktopViewport;
01857
else if (pe.xproperty.atom == net_current_desktop)
01858 dirty |= CurrentDesktop;
01859
else if (pe.xproperty.atom == net_active_window)
01860 dirty |= ActiveWindow;
01861
else {
01862
01863
#ifdef NETWMDEBUG
01864
fprintf(stderr,
"NETRootInfo::event: putting back event and breaking\n");
01865
#endif
01866
01867
if ( compaction )
01868 XPutBackEvent(p->
display, &pe);
01869
break;
01870 }
01871
01872
if (XCheckTypedWindowEvent(p->
display, p->
root, PropertyNotify, &pe) )
01873 compaction = True;
01874
else
01875
break;
01876 }
01877
01878 do_update =
true;
01879 }
01880
01881
if( do_update )
01882 update( props );
01883
01884
#ifdef NETWMDEBUG
01885
fprintf(stderr,
"NETRootInfo::event: handled events, returning dirty = 0x%lx, 0x%lx\n",
01886 dirty, dirty2);
01887
#endif
01888
01889
if( properties_size > PROPERTIES_SIZE )
01890 properties_size = PROPERTIES_SIZE;
01891
for(
int i = 0;
01892 i < properties_size;
01893 ++i )
01894 properties[ i ] = props[ i ];
01895 }
01896
01897
01898
01899
01900
void NETRootInfo::update(
const unsigned long dirty_props[] )
01901 {
01902 Atom type_ret;
01903
int format_ret;
01904
unsigned char *data_ret;
01905
unsigned long nitems_ret, unused;
01906
unsigned long props[ PROPERTIES_SIZE ];
01907
for(
int i = 0;
01908 i < PROPERTIES_SIZE;
01909 ++i )
01910 props[ i ] = dirty_props[ i ] & p->client_properties[ i ];
01911
const unsigned long& dirty = props[ PROTOCOLS ];
01912
const unsigned long& dirty2 = props[ PROTOCOLS2 ];
01913
01914 Q_UNUSED( dirty2 );
01915
01916
if (dirty & Supported ) {
01917
01918
for(
int i = 0; i < PROPERTIES_SIZE; ++i )
01919 p->
properties[ i ] = 0;
01920
if( XGetWindowProperty(p->
display, p->
root, net_supported,
01921 0l, MAX_PROP_SIZE, False, XA_ATOM, &type_ret,
01922 &format_ret, &nitems_ret, &unused, &data_ret)
01923 == Success ) {
01924
if( type_ret == XA_ATOM && format_ret == 32 ) {
01925 Atom* atoms = (Atom*) data_ret;
01926
for(
unsigned int i = 0;
01927 i < nitems_ret;
01928 ++i )
01929 updateSupportedProperties( atoms[ i ] );
01930 }
01931
if ( data_ret )
01932 XFree(data_ret);
01933 }
01934 }
01935
01936
if (dirty & ClientList) {
01937
bool read_ok =
false;
01938
if (XGetWindowProperty(p->
display, p->
root, net_client_list,
01939 0l, MAX_PROP_SIZE, False, XA_WINDOW, &type_ret,
01940 &format_ret, &nitems_ret, &unused, &data_ret)
01941 == Success) {
01942
if (type_ret == XA_WINDOW && format_ret == 32) {
01943 Window *wins = (Window *) data_ret;
01944
01945 qsort(wins, nitems_ret,
sizeof(Window), wcmp);
01946
01947
if (p->clients) {
01948
if (role == Client) {
01949
unsigned long new_index = 0, old_index = 0;
01950
unsigned long new_count = nitems_ret,
01951 old_count = p->clients_count;
01952
01953
while (old_index < old_count || new_index < new_count) {
01954
if (old_index == old_count) {
01955 addClient(wins[new_index++]);
01956 }
else if (new_index == new_count) {
01957 removeClient(p->clients[old_index++]);
01958 }
else {
01959
if (p->clients[old_index] <
01960 wins[new_index]) {
01961 removeClient(p->clients[old_index++]);
01962 }
else if (wins[new_index] <
01963 p->clients[old_index]) {
01964 addClient(wins[new_index++]);
01965 }
else {
01966 new_index++;
01967 old_index++;
01968 }
01969 }
01970 }
01971 }
01972
01973
delete [] p->clients;
01974 }
else {
01975
#ifdef NETWMDEBUG
01976
fprintf(stderr,
"NETRootInfo::update: client list null, creating\n");
01977
#endif
01978
01979
unsigned long n;
01980
for (n = 0; n < nitems_ret; n++) {
01981 addClient(wins[n]);
01982 }
01983 }
01984
01985 p->clients_count = nitems_ret;
01986 p->clients = nwindup(wins, p->clients_count);
01987 read_ok =
true;
01988 }
01989
01990
if ( data_ret )
01991 XFree(data_ret);
01992 }
01993
if( !read_ok ) {
01994
for(
unsigned int i = 0; i < p->clients_count; ++ i )
01995 removeClient(p->clients[i]);
01996 p->clients_count = 0;
01997
delete[] p->clients;
01998 p->clients = NULL;
01999 }
02000
02001
#ifdef NETWMDEBUG
02002
fprintf(stderr,
"NETRootInfo::update: client list updated (%ld clients)\n",
02003 p->clients_count);
02004
#endif
02005
}
02006
02007
if (dirty & KDESystemTrayWindows) {
02008
bool read_ok =
false;
02009
if (XGetWindowProperty(p->
display, p->
root, kde_net_system_tray_windows,
02010 0l, MAX_PROP_SIZE, False, XA_WINDOW, &type_ret,
02011 &format_ret, &nitems_ret, &unused, &data_ret)
02012 == Success) {
02013
if (type_ret == XA_WINDOW && format_ret == 32) {
02014 Window *wins = (Window *) data_ret;
02015
02016 qsort(wins, nitems_ret,
sizeof(Window), wcmp);
02017
02018
if (p->kde_system_tray_windows) {
02019
if (role == Client) {
02020
unsigned long new_index = 0, new_count = nitems_ret;
02021
unsigned long old_index = 0,
02022 old_count = p->kde_system_tray_windows_count;
02023
02024
while(old_index < old_count || new_index < new_count) {
02025
if (old_index == old_count) {
02026 addSystemTrayWin(wins[new_index++]);
02027 }
else if (new_index == new_count) {
02028 removeSystemTrayWin(p->kde_system_tray_windows[old_index++]);
02029 }
else {
02030
if (p->kde_system_tray_windows[old_index] <
02031 wins[new_index]) {
02032 removeSystemTrayWin(p->kde_system_tray_windows[old_index++]);
02033 }
else if (wins[new_index] <
02034 p->kde_system_tray_windows[old_index]) {
02035 addSystemTrayWin(wins[new_index++]);
02036 }
else {
02037 new_index++;
02038 old_index++;
02039 }
02040 }
02041 }
02042 }
02043
02044 }
else {
02045
unsigned long n;
02046
for (n = 0; n < nitems_ret; n++) {
02047 addSystemTrayWin(wins[n]);
02048 }
02049 }
02050
02051 p->kde_system_tray_windows_count = nitems_ret;
02052
delete [] p->kde_system_tray_windows;
02053 p->kde_system_tray_windows =
02054 nwindup(wins, p->kde_system_tray_windows_count);
02055 read_ok =
true;
02056 }
02057
02058
if ( data_ret )
02059 XFree(data_ret);
02060 }
02061
if( !read_ok ) {
02062
for(
unsigned int i = 0; i < p->kde_system_tray_windows_count; ++i )
02063 removeSystemTrayWin(p->kde_system_tray_windows[i]);
02064 p->kde_system_tray_windows_count = 0;
02065
delete [] p->kde_system_tray_windows;
02066 p->kde_system_tray_windows = NULL;
02067 }
02068 }
02069
02070
if (dirty & ClientListStacking) {
02071 p->stacking_count = 0;
02072
delete[] p->stacking;
02073 p->stacking = NULL;
02074
if (XGetWindowProperty(p->
display, p->
root, net_client_list_stacking,
02075 0, MAX_PROP_SIZE, False, XA_WINDOW, &type_ret,
02076 &format_ret, &nitems_ret, &unused, &data_ret)
02077 == Success) {
02078
if (type_ret == XA_WINDOW && format_ret == 32) {
02079 Window *wins = (Window *) data_ret;
02080
02081 p->stacking_count = nitems_ret;
02082 p->stacking = nwindup(wins, p->stacking_count);
02083 }
02084
02085
#ifdef NETWMDEBUG
02086
fprintf(stderr,
"NETRootInfo::update: client stacking updated (%ld clients)\n",
02087 p->stacking_count);
02088
#endif
02089
02090
if ( data_ret )
02091 XFree(data_ret);
02092 }
02093 }
02094
02095
if (dirty & NumberOfDesktops) {
02096 p->number_of_desktops = 0;
02097
02098
if (XGetWindowProperty(p->
display, p->
root, net_number_of_desktops,
02099 0l, 1l, False, XA_CARDINAL, &type_ret, &format_ret,
02100 &nitems_ret, &unused, &data_ret)
02101 == Success) {
02102
if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 1) {
02103 p->number_of_desktops = *((
long *) data_ret);
02104 }
02105
02106
#ifdef NETWMDEBUG
02107
fprintf(stderr,
"NETRootInfo::update: number of desktops = %d\n",
02108 p->number_of_desktops);
02109
#endif
02110
if ( data_ret )
02111 XFree(data_ret);
02112 }
02113 }
02114
02115
if (dirty & DesktopGeometry) {
02116 p->geometry = p->rootSize;
02117
if (XGetWindowProperty(p->
display, p->
root, net_desktop_geometry,
02118 0l, 2l, False, XA_CARDINAL, &type_ret, &format_ret,
02119 &nitems_ret, &unused, &data_ret)
02120 == Success) {
02121
if (type_ret == XA_CARDINAL && format_ret == 32 &&
02122 nitems_ret == 2) {
02123
long *data = (
long *) data_ret;
02124
02125 p->geometry.width = data[0];
02126 p->geometry.height = data[1];
02127
02128
#ifdef NETWMDEBUG
02129
fprintf(stderr,
"NETRootInfo::update: desktop geometry updated\n");
02130
#endif
02131
}
02132
if ( data_ret )
02133 XFree(data_ret);
02134 }
02135 }
02136
02137
if (dirty & DesktopViewport) {
02138
for (
int i = 0; i < p->viewport.size(); i++)
02139 p->viewport[i].x = p->viewport[i].y = 0;
02140
if (XGetWindowProperty(p->
display, p->
root, net_desktop_viewport,
02141 0l, 2l, False, XA_CARDINAL, &type_ret, &format_ret,
02142 &nitems_ret, &unused, &data_ret)
02143 == Success) {
02144
if (type_ret == XA_CARDINAL && format_ret == 32 &&
02145 nitems_ret == 2) {
02146
long *data = (
long *) data_ret;
02147
02148
int d, i, n;
02149 n = nitems_ret / 2;
02150
for (d = 0, i = 0; d < n; d++) {
02151 p->viewport[d].x = data[i++];
02152 p->viewport[d].y = data[i++];
02153 }
02154
02155
#ifdef NETWMDEBUG
02156
fprintf(stderr,
02157
"NETRootInfo::update: desktop viewport array updated (%d entries)\n",
02158 p->viewport.size());
02159
02160
if (nitems_ret % 2 != 0) {
02161 fprintf(stderr,
02162
"NETRootInfo::update(): desktop viewport array "
02163
"size not a multiple of 2\n");
02164 }
02165
#endif
02166
}
02167
if ( data_ret )
02168 XFree(data_ret);
02169 }
02170 }
02171
02172
if (dirty & CurrentDesktop) {
02173 p->current_desktop = 0;
02174
if (XGetWindowProperty(p->
display, p->
root, net_current_desktop,
02175 0l, 1l, False, XA_CARDINAL, &type_ret, &format_ret,
02176 &nitems_ret, &unused, &data_ret)
02177 == Success) {
02178
if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 1) {
02179 p->current_desktop = *((
long *) data_ret) + 1;
02180 }
02181
02182
#ifdef NETWMDEBUG
02183
fprintf(stderr,
"NETRootInfo::update: current desktop = %d\n",
02184 p->current_desktop);
02185
#endif
02186
if ( data_ret )
02187 XFree(data_ret);
02188 }
02189 }
02190
02191
if (dirty & DesktopNames) {
02192
for(
int i = 0; i < p->desktop_names.size(); ++i )
02193
delete[] p->desktop_names[ i ];
02194 p->desktop_names.reset();
02195
if (XGetWindowProperty(p->
display, p->
root, net_desktop_names,
02196 0l, MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
02197 &format_ret, &nitems_ret, &unused, &data_ret)
02198 == Success) {
02199
if (type_ret == UTF8_STRING && format_ret == 8) {
02200
const char *d = (
const char *) data_ret;
02201
unsigned int s, n, index;
02202
02203
for (s = 0, n = 0, index = 0; n < nitems_ret; n++) {
02204
if (d[n] ==
'\0') {
02205
delete [] p->desktop_names[index];
02206 p->desktop_names[index++] = nstrndup((d + s), n - s + 1);
02207 s = n + 1;
02208 }
02209 }
02210 }
02211
02212
#ifdef NETWMDEBUG
02213
fprintf(stderr,
"NETRootInfo::update: desktop names array updated (%d entries)\n",
02214 p->desktop_names.size());
02215
#endif
02216
if ( data_ret )
02217 XFree(data_ret);
02218 }
02219 }
02220
02221
if (dirty & ActiveWindow) {
02222 p->active = None;
02223
if (XGetWindowProperty(p->
display, p->
root, net_active_window, 0l, 1l,
02224 False, XA_WINDOW, &type_ret, &format_ret,
02225 &nitems_ret, &unused, &data_ret)
02226 == Success) {
02227
if (type_ret == XA_WINDOW && format_ret == 32 && nitems_ret == 1) {
02228 p->active = *((Window *) data_ret);
02229 }
02230
02231
#ifdef NETWMDEBUG
02232
fprintf(stderr,
"NETRootInfo::update: active window = 0x%lx\n",
02233 p->active);
02234
#endif
02235
if ( data_ret )
02236 XFree(data_ret);
02237 }
02238 }
02239
02240
if (dirty & WorkArea) {
02241 p->workarea.reset();
02242
if (XGetWindowProperty(p->
display, p->
root, net_workarea, 0l,
02243 (p->number_of_desktops * 4), False, XA_CARDINAL,
02244 &type_ret, &format_ret, &nitems_ret, &unused,
02245 &data_ret)
02246 == Success) {
02247
if (type_ret == XA_CARDINAL && format_ret == 32 &&
02248 nitems_ret == (
unsigned) (p->number_of_desktops * 4)) {
02249
long *d = (
long *) data_ret;
02250
int i, j;
02251
for (i = 0, j = 0; i < p->number_of_desktops; i++) {
02252 p->workarea[i].pos.x = d[j++];
02253 p->workarea[i].pos.y = d[j++];
02254 p->workarea[i].size.width = d[j++];
02255 p->workarea[i].size.height = d[j++];
02256 }
02257 }
02258
02259
#ifdef NETWMDEBUG
02260
fprintf(stderr,
"NETRootInfo::update: work area array updated (%d entries)\n",
02261 p->workarea.size());
02262
#endif
02263
if ( data_ret )
02264 XFree(data_ret);
02265 }
02266 }
02267
02268
02269
if (dirty & SupportingWMCheck) {
02270 p->supportwindow = None;
02271
delete[] p->
name;
02272 p->
name = NULL;
02273
if (XGetWindowProperty(p->
display, p->
root, net_supporting_wm_check,
02274 0l, 1l, False, XA_WINDOW, &type_ret, &format_ret,
02275 &nitems_ret, &unused, &data_ret)
02276 == Success) {
02277
if (type_ret == XA_WINDOW && format_ret == 32 && nitems_ret == 1) {
02278 p->supportwindow = *((Window *) data_ret);
02279
02280
unsigned char *name_ret;
02281
if (XGetWindowProperty(p->
display, p->supportwindow,
02282 net_wm_name, 0l, MAX_PROP_SIZE, False,
02283 UTF8_STRING, &type_ret, &format_ret,
02284 &nitems_ret, &unused, &name_ret)
02285 == Success) {
02286
if (type_ret == UTF8_STRING && format_ret == 8)
02287 p->
name = nstrndup((
const char *) name_ret, nitems_ret);
02288
02289
if ( name_ret )
02290 XFree(name_ret);
02291 }
02292 }
02293
02294
#ifdef NETWMDEBUG
02295
fprintf(stderr,
02296
"NETRootInfo::update: supporting window manager = '%s'\n",
02297 p->
name);
02298
#endif
02299
if ( data_ret )
02300 XFree(data_ret);
02301 }
02302 }
02303
02304
if (dirty & VirtualRoots) {
02305 p->virtual_roots_count = 0;
02306
delete[] p->virtual_roots;
02307 p->virtual_roots = NULL;
02308
if (XGetWindowProperty(p->
display, p->
root, net_virtual_roots,
02309 0, MAX_PROP_SIZE, False, XA_WINDOW, &type_ret,
02310 &format_ret, &nitems_ret, &unused, &data_ret)
02311 == Success) {
02312
if (type_ret == XA_WINDOW && format_ret == 32) {
02313 Window *wins = (Window *) data_ret;
02314
02315 p->virtual_roots_count = nitems_ret;
02316 p->virtual_roots = nwindup(wins, p->virtual_roots_count);
02317 }
02318
02319
#ifdef NETWMDEBUG
02320
fprintf(stderr,
"NETRootInfo::updated: virtual roots updated (%ld windows)\n",
02321 p->virtual_roots_count);
02322
#endif
02323
if ( data_ret )
02324 XFree(data_ret);
02325 }
02326 }
02327 }
02328
02329
02330 Display *NETRootInfo::x11Display()
const {
02331
return p->
display;
02332 }
02333
02334
02335 Window NETRootInfo::rootWindow()
const {
02336
return p->
root;
02337 }
02338
02339
02340 Window NETRootInfo::supportWindow()
const {
02341
return p->supportwindow;
02342 }
02343
02344
02345
const char *NETRootInfo::wmName()
const {
02346
return p->
name; }
02347
02348
02349
int NETRootInfo::screenNumber()
const {
02350
return p->screen;
02351 }
02352
02353
02354
unsigned long NETRootInfo::supported()
const {
02355
return role == WindowManager
02356 ? p->
properties[ PROTOCOLS ]
02357 : p->client_properties[ PROTOCOLS ];
02358 }
02359
02360
const unsigned long* NETRootInfo::supportedProperties()
const {
02361
return p->
properties;
02362 }
02363
02364
const unsigned long* NETRootInfo::passedProperties()
const {
02365
return role == WindowManager
02366 ? p->
properties
02367 : p->client_properties;
02368 }
02369
02370
bool NETRootInfo::isSupported( NET::Property property )
const {
02371
return p->
properties[ PROTOCOLS ] & property;
02372 }
02373
02374
bool NETRootInfo::isSupported( NET::Property2 property )
const {
02375
return p->
properties[ PROTOCOLS2 ] & property;
02376 }
02377
02378
bool NETRootInfo::isSupported( NET::WindowType type )
const {
02379
return p->
properties[ WINDOW_TYPES ] & type;
02380 }
02381
02382
bool NETRootInfo::isSupported( NET::State state )
const {
02383
return p->
properties[ STATES ] & state;
02384 }
02385
02386
bool NETRootInfo::isSupported( NET::Action action )
const {
02387
return p->
properties[ ACTIONS ] &
action;
02388 }
02389
02390
const Window *NETRootInfo::clientList()
const {
02391
return p->clients;
02392 }
02393
02394
02395
int NETRootInfo::clientListCount()
const {
02396
return p->clients_count;
02397 }
02398
02399
02400
const Window *NETRootInfo::clientListStacking()
const {
02401
return p->stacking;
02402 }
02403
02404
02405
int NETRootInfo::clientListStackingCount()
const {
02406
return p->stacking_count;
02407 }
02408
02409
02410
const Window *NETRootInfo::kdeSystemTrayWindows()
const {
02411
return p->kde_system_tray_windows;
02412 }
02413
02414
02415
int NETRootInfo::kdeSystemTrayWindowsCount()
const {
02416
return p->kde_system_tray_windows_count;
02417 }
02418
02419
02420
NETSize NETRootInfo::desktopGeometry(
int)
const {
02421
return p->geometry.width != 0 ? p->geometry : p->rootSize;
02422 }
02423
02424
02425
NETPoint NETRootInfo::desktopViewport(
int desktop)
const {
02426
if (desktop < 1) {
02427
NETPoint pt;
02428
return pt;
02429 }
02430
02431
return p->viewport[desktop - 1];
02432 }
02433
02434
02435
NETRect NETRootInfo::workArea(
int desktop)
const {
02436
if (desktop < 1) {
02437
NETRect rt;
02438
return rt;
02439 }
02440
02441
return p->workarea[desktop - 1];
02442 }
02443
02444
02445
const char *NETRootInfo::desktopName(
int desktop)
const {
02446
if (desktop < 1) {
02447
return 0;
02448 }
02449
02450
return p->desktop_names[desktop - 1];
02451 }
02452
02453
02454
const Window *NETRootInfo::virtualRoots( )
const {
02455
return p->virtual_roots;
02456 }
02457
02458
02459
int NETRootInfo::virtualRootsCount()
const {
02460
return p->virtual_roots_count;
02461 }
02462
02463
02464
int NETRootInfo::numberOfDesktops()
const {
02465
return p->number_of_desktops == 0 ? 1 : p->number_of_desktops;
02466 }
02467
02468
02469
int NETRootInfo::currentDesktop()
const {
02470
return p->current_desktop == 0 ? 1 : p->current_desktop;
02471 }
02472
02473
02474 Window NETRootInfo::activeWindow()
const {
02475
return p->active;
02476 }
02477
02478
02479
02480
02481
const int NETWinInfo::OnAllDesktops = NET::OnAllDesktops;
02482
02483 NETWinInfo::NETWinInfo(Display *display, Window window, Window rootWindow,
02484
const unsigned long properties[],
int properties_size,
02485 Role role)
02486 {
02487
02488
#ifdef NETWMDEBUG
02489
fprintf(stderr,
"NETWinInfo::NETWinInfo: constructing object with role '%s'\n",
02490 (role == WindowManager) ?
"WindowManager" :
"Client");
02491
#endif
02492
02493 p =
new NETWinInfoPrivate;
02494 p->
ref = 1;
02495
02496 p->
display = display;
02497 p->
window = window;
02498 p->
root = rootWindow;
02499 p->
mapping_state = Withdrawn;
02500 p->
mapping_state_dirty = True;
02501 p->
state = 0;
02502 p->
types[ 0 ] = Unknown;
02503 p->
name = (
char *) 0;
02504 p->
visible_name = (
char *) 0;
02505 p->
icon_name = (
char *) 0;
02506 p->
visible_icon_name = (
char *) 0;
02507 p->
desktop = p->
pid = p->
handled_icons = 0;
02508 p->
user_time = -1U;
02509 p->
startup_id = NULL;
02510 p->
transient_for = None;
02511 p->
window_group = None;
02512 p->
allowed_actions = 0;
02513 p->
has_net_support =
false;
02514
02515
02516
02517
02518
02519 p->
kde_system_tray_win_for = 0;
02520
02521
for(
int i = 0;
02522 i < PROPERTIES_SIZE;
02523 ++i )
02524 p->
properties[ i ] = 0;
02525
if( properties_size > PROPERTIES_SIZE )
02526 properties_size = PROPERTIES_SIZE;
02527
for(
int i = 0;
02528 i < properties_size;
02529 ++i )
02530 p->
properties[ i ] = properties[ i ];
02531
02532 p->
icon_count = 0;
02533
02534 this->role = role;
02535
02536
if (! netwm_atoms_created) create_atoms(p->
display);
02537
02538 update(p->
properties);
02539 }
02540
02541
02542 NETWinInfo::NETWinInfo(Display *display, Window window, Window rootWindow,
02543
unsigned long properties, Role role)
02544 {
02545
02546
#ifdef NETWMDEBUG
02547
fprintf(stderr,
"NETWinInfo::NETWinInfo: constructing object with role '%s'\n",
02548 (role == WindowManager) ?
"WindowManager" :
"Client");
02549
#endif
02550
02551 p =
new NETWinInfoPrivate;
02552 p->
ref = 1;
02553
02554 p->
display = display;
02555 p->
window = window;
02556 p->
root = rootWindow;
02557 p->
mapping_state = Withdrawn;
02558 p->
mapping_state_dirty = True;
02559 p->
state = 0;
02560 p->
types[ 0 ] = Unknown;
02561 p->
name = (
char *) 0;
02562 p->
visible_name = (
char *) 0;
02563 p->
icon_name = (
char *) 0;
02564 p->
visible_icon_name = (
char *) 0;
02565 p->
desktop = p->
pid = p->
handled_icons = 0;
02566 p->
user_time = -1U;
02567 p->
startup_id = NULL;
02568 p->
transient_for = None;
02569 p->
window_group = None;
02570 p->
allowed_actions = 0;
02571 p->
has_net_support =
false;
02572
02573
02574
02575
02576
02577 p->
kde_system_tray_win_for = 0;
02578
02579
for(
int i = 0;
02580 i < PROPERTIES_SIZE;
02581 ++i )
02582 p->
properties[ i ] = 0;
02583 p->
properties[ PROTOCOLS ] = properties;
02584
02585 p->
icon_count = 0;
02586
02587 this->role = role;
02588
02589
if (! netwm_atoms_created) create_atoms(p->
display);
02590
02591 update(p->
properties);
02592 }
02593
02594
02595 NETWinInfo::NETWinInfo(
const NETWinInfo &wininfo) {
02596 p = wininfo.p;
02597 p->
ref++;
02598 }
02599
02600
02601 NETWinInfo::~NETWinInfo() {
02602 refdec_nwi(p);
02603
02604
if (! p->
ref)
delete p;
02605 }
02606
02607
02608
02609
02610
const NETWinInfo &NETWinInfo::operator=(
const NETWinInfo &wininfo) {
02611
02612
#ifdef NETWMDEBUG
02613
fprintf(stderr,
"NETWinInfo::operator=()\n");
02614
#endif
02615
02616
if (p != wininfo.p) {
02617 refdec_nwi(p);
02618
02619
if (! p->
ref)
delete p;
02620 }
02621
02622 p = wininfo.p;
02623 role = wininfo.role;
02624 p->
ref++;
02625
02626
return *
this;
02627 }
02628
02629
02630
void NETWinInfo::setIcon(
NETIcon icon, Bool replace) {
02631
if (role != Client)
return;
02632
02633
int proplen, i, sz, j;
02634
02635
if (
replace) {
02636
02637
for (i = 0; i < p->
icons.
size(); i++) {
02638
delete [] p->
icons[i].data;
02639 p->
icons[i].data = 0;
02640 p->
icons[i].
size.width = 0;
02641 p->
icons[i].
size.height = 0;
02642 }
02643
02644 p->
icon_count = 0;
02645 }
02646
02647
02648 p->
icons[p->
icon_count] = icon;
02649 p->
icon_count++;
02650
02651
02652
NETIcon &ni = p->
icons[p->
icon_count - 1];
02653 sz = ni.
size.
width * ni.
size.
height;
02654 CARD32 *d =
new CARD32[sz];
02655 ni.
data = (
unsigned char *) d;
02656 memcpy(d, icon.
data, sz *
sizeof(CARD32));
02657
02658
02659
for (i = 0, proplen = 0; i < p->
icon_count; i++) {
02660 proplen += 2 + (p->
icons[i].
size.width *
02661 p->
icons[i].
size.height);
02662 }
02663
02664 CARD32 *d32;
02665
long *prop =
new long[proplen], *pprop = prop;
02666
for (i = 0; i < p->
icon_count; i++) {
02667
02668 *pprop++ = p->
icons[i].
size.width;
02669 *pprop++ = p->
icons[i].
size.height;
02670
02671
02672 sz = (p->
icons[i].
size.width * p->
icons[i].
size.height);
02673 d32 = (CARD32 *) p->
icons[i].data;
02674
for (j = 0; j < sz; j++) *pprop++ = *d32++;
02675 }
02676
02677 XChangeProperty(p->
display, p->
window, net_wm_icon, XA_CARDINAL, 32,
02678 PropModeReplace, (
unsigned char *) prop, proplen);
02679
02680
delete [] prop;
02681 }
02682
02683
02684
void NETWinInfo::setIconGeometry(
NETRect geometry) {
02685
if (role != Client)
return;
02686
02687 p->
icon_geom = geometry;
02688
02689
long data[4];
02690 data[0] = geometry.
pos.
x;
02691 data[1] = geometry.
pos.
y;
02692 data[2] = geometry.
size.
width;
02693 data[3] = geometry.
size.
height;
02694
02695 XChangeProperty(p->
display, p->
window, net_wm_icon_geometry, XA_CARDINAL,
02696 32, PropModeReplace, (
unsigned char *) data, 4);
02697 }
02698
02699
02700
void NETWinInfo::setStrut(
NETStrut strut) {
02701
if (role != Client)
return;
02702
02703 p->
strut = strut;
02704
02705
long data[4];
02706 data[0] = strut.
left;
02707 data[1] = strut.
right;
02708 data[2] = strut.
top;
02709 data[3] = strut.
bottom;
02710
02711 XChangeProperty(p->
display, p->
window, net_wm_strut, XA_CARDINAL, 32,
02712 PropModeReplace, (
unsigned char *) data, 4);
02713 }
02714
02715
02716
void NETWinInfo::setState(
unsigned long state,
unsigned long mask) {
02717
if (p->
mapping_state_dirty)
02718 updateWMState();
02719
02720
02721
if( ( p->
properties[ PROTOCOLS ] & WMState ) == 0 ) {
02722 p->
properties[ PROTOCOLS ] |= WMState;
02723
unsigned long props[ PROPERTIES_SIZE ] = { WMState, 0 };
02724 assert( PROPERTIES_SIZE == 2 );
02725 update( props );
02726 p->
properties[ PROTOCOLS ] &= ~WMState;
02727 }
02728
02729
if (role == Client && p->
mapping_state != Withdrawn) {
02730
02731
#ifdef NETWMDEBUG
02732
fprintf(stderr,
"NETWinInfo::setState (0x%lx, 0x%lx) (Client)\n",
02733 state, mask);
02734
#endif // NETWMDEBUG
02735
02736 XEvent e;
02737 e.xclient.type = ClientMessage;
02738 e.xclient.message_type = net_wm_state;
02739 e.xclient.display = p->
display;
02740 e.xclient.window = p->
window;
02741 e.xclient.format = 32;
02742 e.xclient.data.l[3] = 0l;
02743 e.xclient.data.l[4] = 0l;
02744
02745
if ((mask & Modal) && ((p->
state & Modal) != (state & Modal))) {
02746 e.xclient.data.l[0] = (state & Modal) ? 1 : 0;
02747 e.xclient.data.l[1] = net_wm_state_modal;
02748 e.xclient.data.l[2] = 0l;
02749
02750 XSendEvent(p->
display, p->
root, False, netwm_sendevent_mask, &e);
02751 }
02752
02753
if ((mask & Sticky) && ((p->
state & Sticky) != (state & Sticky))) {
02754 e.xclient.data.l[0] = (state & Sticky) ? 1 : 0;
02755 e.xclient.data.l[1] = net_wm_state_sticky;
02756 e.xclient.data.l[2] = 0l;
02757
02758 XSendEvent(p->
display, p->
root, False, netwm_sendevent_mask, &e);
02759 }
02760
02761
if ((mask & Max) && (( (p->
state&mask) & Max) != (state & Max))) {
02762
02763
unsigned long wishstate = (p->
state & ~mask) | (state & mask);
02764
if ( ( (wishstate & MaxHoriz) != (p->
state & MaxHoriz) )
02765 && ( (wishstate & MaxVert) != (p->
state & MaxVert) ) ) {
02766
if ( (wishstate & Max) == Max ) {
02767 e.xclient.data.l[0] = 1;
02768 e.xclient.data.l[1] = net_wm_state_max_horiz;
02769 e.xclient.data.l[2] = net_wm_state_max_vert;
02770 XSendEvent(p->
display, p->
root, False, netwm_sendevent_mask, &e);
02771 }
else if ( (wishstate & Max) == 0 ) {
02772 e.xclient.data.l[0] = 0;
02773 e.xclient.data.l[1] = net_wm_state_max_horiz;
02774 e.xclient.data.l[2] = net_wm_state_max_vert;
02775 XSendEvent(p->
display, p->
root, False, netwm_sendevent_mask, &e);
02776 }
else {
02777 e.xclient.data.l[0] = ( wishstate & MaxHoriz ) ? 1 : 0;
02778 e.xclient.data.l[1] = net_wm_state_max_horiz;
02779 e.xclient.data.l[2] = 0;
02780 XSendEvent(p->
display, p->
root, False, netwm_sendevent_mask, &e);
02781 e.xclient.data.l[0] = ( wishstate & MaxVert ) ? 1 : 0;
02782 e.xclient.data.l[1] = net_wm_state_max_vert;
02783 e.xclient.data.l[2] = 0;
02784 XSendEvent(p->
display, p->
root, False, netwm_sendevent_mask, &e);
02785 }
02786 }
else if ( (wishstate & MaxVert) != (p->
state & MaxVert) ) {
02787 e.xclient.data.l[0] = ( wishstate & MaxVert ) ? 1 : 0;
02788 e.xclient.data.l[1] = net_wm_state_max_vert;
02789 e.xclient.data.l[2] = 0;
02790 XSendEvent(p->
display, p->
root, False, netwm_sendevent_mask, &e);
02791 }
else if ( (wishstate & MaxHoriz) != (p->
state & MaxHoriz) ) {
02792 e.xclient.data.l[0] = ( wishstate & MaxHoriz ) ? 1 : 0;
02793 e.xclient.data.l[1] = net_wm_state_max_horiz;
02794 e.xclient.data.l[2] = 0;
02795 XSendEvent(p->
display, p->
root, False, netwm_sendevent_mask, &e);
02796 }
02797 }
02798
02799
if ((mask & Shaded) && ((p->
state & Shaded) != (state & Shaded))) {
02800 e.xclient.data.l[0] = (state & Shaded) ? 1 : 0;
02801 e.xclient.data.l[1] = net_wm_state_shaded;
02802 e.xclient.data.l[2] = 0l;
02803
02804 XSendEvent(p->
display, p->
root, False, netwm_sendevent_mask, &e);
02805 }
02806
02807
if ((mask & SkipTaskbar) &&
02808 ((p->
state & SkipTaskbar) != (state & SkipTaskbar))) {
02809 e.xclient.data.l[0] = (state & SkipTaskbar) ? 1 : 0;
02810 e.xclient.data.l[1] = net_wm_state_skip_taskbar;
02811 e.xclient.data.l[2] = 0l;
02812
02813 XSendEvent(p->
display, p->
root, False, netwm_sendevent_mask, &e);
02814 }
02815
02816
if ((mask & SkipPager) &&
02817 ((p->
state & SkipPager) != (state & SkipPager))) {
02818 e.xclient.data.l[0] = (state & SkipPager) ? 1 : 0;
02819 e.xclient.data.l[1] = net_wm_state_skip_pager;
02820 e.xclient.data.l[2] = 0l;
02821
02822 XSendEvent(p->
display, p->
root, False, netwm_sendevent_mask, &e);
02823 }
02824
02825
if ((mask & Hidden) &&
02826 ((p->
state & Hidden) != (state & Hidden))) {
02827 e.xclient.data.l[0] = (state & Hidden) ? 1 : 0;
02828 e.xclient.data.l[1] = net_wm_state_hidden;
02829 e.xclient.data.l[2] = 0l;
02830
02831 XSendEvent(p->
display, p->
root, False, netwm_sendevent_mask, &e);
02832 }
02833
02834
if ((mask &
FullScreen) &&
02835 ((p->
state &
FullScreen) != (state &
FullScreen))) {
02836 e.xclient.data.l[0] = (state &
FullScreen) ? 1 : 0;
02837 e.xclient.data.l[1] = net_wm_state_fullscreen;
02838 e.xclient.data.l[2] = 0l;
02839
02840 XSendEvent(p->
display, p->
root, False, netwm_sendevent_mask, &e);
02841 }
02842
02843
if ((mask & KeepAbove) &&
02844 ((p->
state & KeepAbove) != (state & KeepAbove))) {
02845 e.xclient.data.l[0] = (state & KeepAbove) ? 1 : 0;
02846 e.xclient.data.l[1] = net_wm_state_above;
02847 e.xclient.data.l[2] = 0l;
02848
02849 XSendEvent(p->
display, p->
root, False, netwm_sendevent_mask, &e);
02850 }
02851
02852
if ((mask & KeepBelow) &&
02853 ((p->
state & KeepBelow) != (state & KeepBelow))) {
02854 e.xclient.data.l[0] = (state & KeepBelow) ? 1 : 0;
02855 e.xclient.data.l[1] = net_wm_state_below;
02856 e.xclient.data.l[2] = 0l;
02857
02858 XSendEvent(p->
display, p->
root, False, netwm_sendevent_mask, &e);
02859 }
02860
02861
if ((mask & StaysOnTop) && ((p->
state & StaysOnTop) != (state & StaysOnTop))) {
02862 e.xclient.data.l[0] = (state & StaysOnTop) ? 1 : 0;
02863 e.xclient.data.l[1] = net_wm_state_stays_on_top;
02864 e.xclient.data.l[2] = 0l;
02865
02866 XSendEvent(p->
display, p->
root, False, netwm_sendevent_mask, &e);
02867 }
02868
02869
if ((mask & DemandsAttention) &&
02870 ((p->
state & DemandsAttention) != (state & DemandsAttention))) {
02871 e.xclient.data.l[0] = (state & DemandsAttention) ? 1 : 0;
02872 e.xclient.data.l[1] = net_wm_state_demands_attention;
02873 e.xclient.data.l[2] = 0l;
02874
02875 XSendEvent(p->
display, p->
root, False, netwm_sendevent_mask, &e);
02876 }
02877
02878 }
else {
02879 p->
state &= ~mask;
02880 p->
state |= state;
02881
02882
long data[50];
02883
int count = 0;
02884
02885
02886
if (p->
state & Modal) data[count++] = net_wm_state_modal;
02887
if (p->
state & MaxVert) data[count++] = net_wm_state_max_vert;
02888
if (p->
state & MaxHoriz) data[count++] = net_wm_state_max_horiz;
02889
if (p->
state & Shaded) data[count++] = net_wm_state_shaded;
02890
if (p->
state & Hidden) data[count++] = net_wm_state_hidden;
02891
if (p->
state &
FullScreen) data[count++] = net_wm_state_fullscreen;
02892
if (p->
state & DemandsAttention) data[count++] = net_wm_state_demands_attention;
02893
02894
02895
if (p->
state & KeepAbove) data[count++] = net_wm_state_above;
02896
if (p->
state & KeepBelow) data[count++] = net_wm_state_below;
02897
if (p->
state & StaysOnTop) data[count++] = net_wm_state_stays_on_top;
02898
if (p->
state & Sticky) data[count++] = net_wm_state_sticky;
02899
if (p->
state & SkipTaskbar) data[count++] = net_wm_state_skip_taskbar;
02900
if (p->
state & SkipPager) data[count++] = net_wm_state_skip_pager;
02901
02902
#ifdef NETWMDEBUG
02903
fprintf(stderr,
"NETWinInfo::setState: setting state property (%d)\n", count);
02904
for (
int i = 0; i < count; i++) {
02905
char* data_ret = XGetAtomName(p->
display, (Atom) data[i]);
02906 fprintf(stderr,
"NETWinInfo::setState: state %ld '%s'\n",
02907 data[i], data_ret);
02908
if ( data_ret )
02909 XFree( data_ret );
02910 }
02911
02912
#endif
02913
02914 XChangeProperty(p->
display, p->
window, net_wm_state, XA_ATOM, 32,
02915 PropModeReplace, (
unsigned char *) data, count);
02916 }
02917 }
02918
02919
02920
void NETWinInfo::setWindowType(WindowType type) {
02921
if (role != Client)
return;
02922
02923
int len;
02924
long data[2];
02925
02926
switch (type) {
02927
case Override:
02928
02929
02930 data[0] = kde_net_wm_window_type_override;
02931 data[1] = net_wm_window_type_normal;
02932 len = 2;
02933
break;
02934
02935
case Dialog:
02936 data[0] = net_wm_window_type_dialog;
02937 data[1] = None;
02938 len = 1;
02939
break;
02940
02941
case Menu:
02942 data[0] = net_wm_window_type_menu;
02943 data[1] = None;
02944 len = 1;
02945
break;
02946
02947
case TopMenu:
02948
02949
02950 data[0] = kde_net_wm_window_type_topmenu;
02951 data[1] = net_wm_window_type_dock;
02952 len = 2;
02953
break;
02954
02955
case Tool:
02956 data[0] = net_wm_window_type_toolbar;
02957 data[1] = None;
02958 len = 1;
02959
break;
02960
02961
case Dock:
02962 data[0] = net_wm_window_type_dock;
02963 data[1] = None;
02964 len = 1;
02965
break;
02966
02967
case Desktop:
02968 data[0] = net_wm_window_type_desktop;
02969 data[1] = None;
02970 len = 1;
02971
break;
02972
02973
case Utility:
02974 data[0] = net_wm_window_type_utility;
02975 data[1] = net_wm_window_type_dialog;
02976 len = 2;
02977
break;
02978
02979
case Splash:
02980 data[0] = net_wm_window_type_splash;
02981 data[1] = net_wm_window_type_dock;
02982 len = 2;
02983
break;
02984
02985
default:
02986
case Normal:
02987 data[0] = net_wm_window_type_normal;
02988 data[1] = None;
02989 len = 1;
02990
break;
02991 }
02992
02993 XChangeProperty(p->
display, p->
window, net_wm_window_type, XA_ATOM, 32,
02994 PropModeReplace, (
unsigned char *) &data, len);
02995 }
02996
02997
02998
void NETWinInfo::setName(
const char *name) {
02999
if (role != Client)
return;
03000
03001
delete [] p->
name;
03002 p->
name = nstrdup(name);
03003
if( p->
name[ 0 ] !=
'\0' )
03004 XChangeProperty(p->
display, p->
window, net_wm_name, UTF8_STRING, 8,
03005 PropModeReplace, (
unsigned char *) p->
name,
03006 strlen(p->
name));
03007
else
03008 XDeleteProperty(p->
display, p->
window, net_wm_name);
03009 }
03010
03011
03012
void NETWinInfo::setVisibleName(
const char *visibleName) {
03013
if (role != WindowManager)
return;
03014
03015
delete [] p->
visible_name;
03016 p->
visible_name = nstrdup(visibleName);
03017
if( p->
visible_name[ 0 ] !=
'\0' )
03018 XChangeProperty(p->
display, p->
window, net_wm_visible_name, UTF8_STRING, 8,
03019 PropModeReplace, (
unsigned char *) p->
visible_name,
03020 strlen(p->
visible_name));
03021
else
03022 XDeleteProperty(p->
display, p->
window, net_wm_visible_name);
03023 }
03024
03025
03026
void NETWinInfo::setIconName(
const char *iconName) {
03027
if (role != Client)
return;
03028
03029
delete [] p->
icon_name;
03030 p->
icon_name = nstrdup(iconName);
03031
if( p->
icon_name[ 0 ] !=
'\0' )
03032 XChangeProperty(p->
display, p->
window, net_wm_icon_name, UTF8_STRING, 8,
03033 PropModeReplace, (
unsigned char *) p->
icon_name,
03034 strlen(p->
icon_name));
03035
else
03036 XDeleteProperty(p->
display, p->
window, net_wm_icon_name);
03037 }
03038
03039
03040
void NETWinInfo::setVisibleIconName(
const char *visibleIconName) {
03041
if (role != WindowManager)
return;
03042
03043
delete [] p->
visible_icon_name;
03044 p->
visible_icon_name = nstrdup(visibleIconName);
03045
if( p->
visible_icon_name[ 0 ] !=
'\0' )
03046 XChangeProperty(p->
display, p->
window, net_wm_visible_icon_name, UTF8_STRING, 8,
03047 PropModeReplace, (
unsigned char *) p->
visible_icon_name,
03048 strlen(p->
visible_icon_name));
03049
else
03050 XDeleteProperty(p->
display, p->
window, net_wm_visible_icon_name);
03051 }
03052
03053
03054
void NETWinInfo::setDesktop(
int desktop) {
03055
if (p->
mapping_state_dirty)
03056 updateWMState();
03057
03058
if (role == Client && p->
mapping_state != Withdrawn) {
03059
03060
03061
if ( desktop == 0 )
03062
return;
03063
03064 XEvent e;
03065
03066 e.xclient.type = ClientMessage;
03067 e.xclient.message_type = net_wm_desktop;
03068 e.xclient.display = p->
display;
03069 e.xclient.window = p->
window;
03070 e.xclient.format = 32;
03071 e.xclient.data.l[0] = desktop == OnAllDesktops ? OnAllDesktops : desktop - 1;
03072 e.xclient.data.l[1] = 0l;
03073 e.xclient.data.l[2] = 0l;
03074 e.xclient.data.l[3] = 0l;
03075 e.xclient.data.l[4] = 0l;
03076
03077 XSendEvent(p->
display, p->
root, False, netwm_sendevent_mask, &e);
03078 }
else {
03079
03080 p->
desktop = desktop;
03081
long d = desktop;
03082
03083
if ( d != OnAllDesktops ) {
03084
if ( d == 0 ) {
03085 XDeleteProperty( p->
display, p->
window, net_wm_desktop );
03086
return;
03087 }
03088
03089 d -= 1;
03090 }
03091
03092 XChangeProperty(p->
display, p->
window, net_wm_desktop, XA_CARDINAL, 32,
03093 PropModeReplace, (
unsigned char *) &d, 1);
03094 }
03095 }
03096
03097
03098
void NETWinInfo::setPid(
int pid) {
03099
if (role != Client)
return;
03100
03101 p->
pid = pid;
03102
long d = pid;
03103 XChangeProperty(p->
display, p->
window, net_wm_pid, XA_CARDINAL, 32,
03104 PropModeReplace, (
unsigned char *) &d, 1);
03105 }
03106
03107
03108
void NETWinInfo::setHandledIcons(Bool handled) {
03109
if (role != Client)
return;
03110
03111 p->
handled_icons = handled;
03112
long d = handled;
03113 XChangeProperty(p->
display, p->
window, net_wm_handled_icons, XA_CARDINAL, 32,
03114 PropModeReplace, (
unsigned char *) &d, 1);
03115 }
03116
03117
void NETWinInfo::setStartupId(
const char*
id) {
03118
if (role != Client)
return;
03119
03120
delete[] p->
startup_id;
03121 p->
startup_id = nstrdup(
id);
03122 XChangeProperty(p->
display, p->
window, net_startup_id, UTF8_STRING, 8,
03123 PropModeReplace, reinterpret_cast< unsigned char* >( p->
startup_id ),
03124 strlen( p->
startup_id ));
03125 }
03126
03127
void NETWinInfo::setAllowedActions(
unsigned long actions ) {
03128
if( role != WindowManager )
03129
return;
03130
long data[50];
03131
int count = 0;
03132
03133 p->
allowed_actions = actions;
03134
if (p->
allowed_actions & ActionMove) data[count++] = net_wm_action_move;
03135
if (p->
allowed_actions & ActionResize) data[count++] = net_wm_action_resize;
03136
if (p->
allowed_actions & ActionMinimize) data[count++] = net_wm_action_minimize;
03137
if (p->
allowed_actions & ActionShade) data[count++] = net_wm_action_shade;
03138
if (p->
allowed_actions & ActionStick) data[count++] = net_wm_action_stick;
03139
if (p->
allowed_actions & ActionMaxVert) data[count++] = net_wm_action_max_vert;
03140
if (p->
allowed_actions & ActionMaxHoriz) data[count++] = net_wm_action_max_horiz;
03141
if (p->
allowed_actions & ActionFullScreen) data[count++] = net_wm_action_fullscreen;
03142
if (p->
allowed_actions & ActionChangeDesktop) data[count++] = net_wm_action_change_desk;
03143
if (p->
allowed_actions & ActionClose) data[count++] = net_wm_action_close;
03144
03145
#ifdef NETWMDEBUG
03146
fprintf(stderr,
"NETWinInfo::setAllowedActions: setting property (%d)\n", count);
03147
for (
int i = 0; i < count; i++) {
03148
char* data_ret = XGetAtomName(p->
display, (Atom) data[i]);
03149 fprintf(stderr,
"NETWinInfo::setAllowedActions: action %ld '%s'\n",
03150 data[i], data_ret);
03151
if ( data_ret )
03152 XFree(data_ret);
03153 }
03154
#endif
03155
03156 XChangeProperty(p->
display, p->
window, net_wm_allowed_actions, XA_ATOM, 32,
03157 PropModeReplace, (
unsigned char *) data, count);
03158 }
03159
03160
void NETWinInfo::setKDESystemTrayWinFor(Window window) {
03161
if (role != Client)
return;
03162
03163 p->
kde_system_tray_win_for = window;
03164 XChangeProperty(p->
display, p->
window, kde_net_wm_system_tray_window_for,
03165 XA_WINDOW, 32, PropModeReplace,
03166 (
unsigned char *) &(p->
kde_system_tray_win_for), 1);
03167 }
03168
03169
03170
void NETWinInfo::setKDEFrameStrut(
NETStrut strut) {
03171
if (role != WindowManager)
return;
03172
03173 p->
frame_strut = strut;
03174
03175
long d[4];
03176 d[0] = strut.
left;
03177 d[1] = strut.
right;
03178 d[2] = strut.
top;
03179 d[3] = strut.
bottom;
03180
03181 XChangeProperty(p->
display, p->
window, kde_net_wm_frame_strut, XA_CARDINAL, 32,
03182 PropModeReplace, (
unsigned char *) d, 4);
03183 }
03184
03185
03186
void NETWinInfo::kdeGeometry(
NETRect& frame,
NETRect& window) {
03187
if (p->
win_geom.
size.
width == 0 || p->
win_geom.
size.
height == 0) {
03188 Window unused;
03189
int x, y;
03190
unsigned int w, h, junk;
03191 XGetGeometry(p->
display, p->
window, &unused, &x, &y, &w, &h, &junk, &junk);
03192 XTranslateCoordinates(p->
display, p->
window, p->
root, 0, 0, &x, &y, &unused
03193 );
03194
03195 p->
win_geom.
pos.
x = x;
03196 p->
win_geom.
pos.
y = y;
03197
03198 p->
win_geom.
size.
width = w;
03199 p->
win_geom.
size.
height = h;
03200 }
03201
03202 window = p->
win_geom;
03203
03204 frame.
pos.
x = window.
pos.
x - p->
frame_strut.
left;
03205 frame.
pos.
y = window.
pos.
y - p->
frame_strut.
top;
03206 frame.
size.
width = window.
size.
width + p->
frame_strut.
left + p->
frame_strut.
right;
03207 frame.
size.
height = window.
size.
height + p->
frame_strut.
top + p->
frame_strut.
bottom;
03208 }
03209
03210
03211
NETIcon NETWinInfo::icon(
int width,
int height)
const {
03212
NETIcon result;
03213
03214
if ( !p->
icon_count ) {
03215 result.
size.
width = 0;
03216 result.
size.
height = 0;
03217 result.
data = 0;
03218
return result;
03219 }
03220
03221 result = p->
icons[0];
03222
03223
03224
03225
if (width == height && height == -1)
return result;
03226
03227
int i;
03228
for (i = 0; i < p->
icons.
size(); i++) {
03229
if ((p->
icons[i].
size.width >= width &&
03230 p->
icons[i].
size.width < result.
size.
width) &&
03231 (p->
icons[i].
size.height >= height &&
03232 p->
icons[i].
size.height < result.
size.
height))
03233 result = p->
icons[i];
03234 }
03235
03236
return result;
03237 }
03238
03239
void NETWinInfo::setUserTime( Time time ) {
03240
if (role != Client)
return;
03241
03242 p->
user_time = time;
03243
long d = time;
03244 XChangeProperty(p->
display, p->
window, net_wm_user_time, XA_CARDINAL, 32,
03245 PropModeReplace, (
unsigned char *) &d, 1);
03246 }
03247
03248
03249
unsigned long NETWinInfo::event(XEvent *ev )
03250 {
03251
unsigned long props[ 1 ];
03252
event( ev, props, 1 );
03253
return props[ 0 ];
03254 }
03255
03256
void NETWinInfo::event(XEvent *event,
unsigned long* properties,
int properties_size ) {
03257
unsigned long props[ PROPERTIES_SIZE ] = { 0, 0 };
03258 assert( PROPERTIES_SIZE == 2 );
03259
unsigned long& dirty = props[ PROTOCOLS ];
03260
unsigned long& dirty2 = props[ PROTOCOLS2 ];
03261
bool do_update =
false;
03262
03263
if (role == WindowManager &&
event->type == ClientMessage &&
03264
event->xclient.format == 32) {
03265
03266
#ifdef NETWMDEBUG
03267
fprintf(stderr,
"NETWinInfo::event: handling ClientMessage event\n");
03268
#endif // NETWMDEBUG
03269
03270
if (
event->xclient.message_type == net_wm_state) {
03271 dirty = WMState;
03272
03273
03274
03275
#ifdef NETWMDEBUG
03276
fprintf(stderr,
03277
"NETWinInfo::event: state client message, getting new state/mask\n");
03278
#endif
03279
03280
int i;
03281
long state = 0, mask = 0;
03282
03283
for (i = 1; i < 3; i++) {
03284
#ifdef NETWMDEBUG
03285
char* debug_txt = XGetAtomName(p->
display, (Atom)
event->xclient.data.l[i]);
03286 fprintf(stderr,
"NETWinInfo::event: message %ld '%s'\n",
03287
event->xclient.data.l[i], debug_txt );
03288
if ( debug_txt )
03289 XFree( debug_txt );
03290
#endif
03291
03292
if ((Atom)
event->xclient.data.l[i] == net_wm_state_modal)
03293 mask |= Modal;
03294
else if ((Atom)
event->xclient.data.l[i] == net_wm_state_sticky)
03295 mask |= Sticky;
03296
else if ((Atom)
event->xclient.data.l[i] == net_wm_state_max_vert)
03297 mask |= MaxVert;
03298
else if ((Atom)
event->xclient.data.l[i] == net_wm_state_max_horiz)
03299 mask |= MaxHoriz;
03300
else if ((Atom)
event->xclient.data.l[i] == net_wm_state_shaded)
03301 mask |= Shaded;
03302
else if ((Atom)
event->xclient.data.l[i] == net_wm_state_skip_taskbar)
03303 mask |= SkipTaskbar;
03304
else if ((Atom)
event->xclient.data.l[i] == net_wm_state_skip_pager)
03305 mask |= SkipPager;
03306
else if ((Atom)
event->xclient.data.l[i] == net_wm_state_hidden)
03307 mask |= Hidden;
03308
else if ((Atom)
event->xclient.data.l[i] == net_wm_state_fullscreen)
03309 mask |=
FullScreen;
03310
else if ((Atom)
event->xclient.data.l[i] == net_wm_state_above)
03311 mask |= KeepAbove;
03312
else if ((Atom)
event->xclient.data.l[i] == net_wm_state_below)
03313 mask |= KeepBelow;
03314
else if ((Atom)
event->xclient.data.l[i] == net_wm_state_demands_attention)
03315 mask |= DemandsAttention;
03316
else if ((Atom)
event->xclient.data.l[i] == net_wm_state_stays_on_top)
03317 mask |= StaysOnTop;
03318 }
03319
03320
03321
switch (
event->xclient.data.l[0]) {
03322
case 1:
03323
03324 state = mask;
03325
break;
03326
03327
case 2:
03328
03329 state = (p->
state & mask) ^ mask;
03330
break;
03331
03332
default:
03333
03334 ;
03335 }
03336
03337
#ifdef NETWMDEBUG
03338
fprintf(stderr,
"NETWinInfo::event: calling changeState(%lx, %lx)\n",
03339 state, mask);
03340
#endif
03341
03342 changeState(state, mask);
03343 }
else if (
event->xclient.message_type == net_wm_desktop) {
03344 dirty = WMDesktop;
03345
03346
if(
event->xclient.data.l[0] == OnAllDesktops )
03347 changeDesktop( OnAllDesktops );
03348
else
03349 changeDesktop(
event->xclient.data.l[0] + 1);
03350 }
03351 }
03352
03353
if (
event->type == PropertyNotify) {
03354
03355
#ifdef NETWMDEBUG
03356
fprintf(stderr,
"NETWinInfo::event: handling PropertyNotify event\n");
03357
#endif
03358
03359 XEvent pe = *
event;
03360
03361 Bool done = False;
03362 Bool compaction = False;
03363
while (! done) {
03364
03365
#ifdef NETWMDEBUG
03366
fprintf(stderr,
"NETWinInfo::event: loop fire\n");
03367
#endif
03368
03369
if (pe.xproperty.atom == net_wm_name)
03370 dirty |= WMName;
03371
else if (pe.xproperty.atom == net_wm_visible_name)
03372 dirty |= WMVisibleName;
03373
else if (pe.xproperty.atom == net_wm_desktop)
03374 dirty |= WMDesktop;
03375
else if (pe.xproperty.atom == net_wm_window_type)
03376 dirty |=WMWindowType;
03377
else if (pe.xproperty.atom == net_wm_state)
03378 dirty |= WMState;
03379
else if (pe.xproperty.atom == net_wm_strut)
03380 dirty |= WMStrut;
03381
else if (pe.xproperty.atom == net_wm_icon_geometry)
03382 dirty |= WMIconGeometry;
03383
else if (pe.xproperty.atom == net_wm_icon)
03384 dirty |= WMIcon;
03385
else if (pe.xproperty.atom == net_wm_pid)
03386 dirty |= WMPid;
03387
else if (pe.xproperty.atom == net_wm_handled_icons)
03388 dirty |= WMHandledIcons;
03389
else if (pe.xproperty.atom == net_startup_id)
03390 dirty2 |= WM2StartupId;
03391
else if (pe.xproperty.atom == net_wm_allowed_actions)
03392 dirty2 |= WM2AllowedActions;
03393
else if (pe.xproperty.atom == kde_net_wm_system_tray_window_for)
03394 dirty |= WMKDESystemTrayWinFor;
03395
else if (pe.xproperty.atom == xa_wm_state)
03396 dirty |= XAWMState;
03397
else if (pe.xproperty.atom == kde_net_wm_frame_strut)
03398 dirty |= WMKDEFrameStrut;
03399
else if (pe.xproperty.atom == net_wm_icon_name)
03400 dirty |= WMIconName;
03401
else if (pe.xproperty.atom == net_wm_visible_icon_name)
03402 dirty |= WMVisibleIconName;
03403
else if (pe.xproperty.atom == net_wm_user_time)
03404 dirty2 |= WM2UserTime;
03405
else if (pe.xproperty.atom == XA_WM_HINTS)
03406 dirty2 |= WM2GroupLeader;
03407
else if (pe.xproperty.atom == XA_WM_TRANSIENT_FOR)
03408 dirty2 |= WM2TransientFor;
03409
else {
03410
03411
#ifdef NETWMDEBUG
03412
fprintf(stderr,
"NETWinInfo::event: putting back event and breaking\n");
03413
#endif
03414
03415
if ( compaction )
03416 XPutBackEvent(p->
display, &pe);
03417
break;
03418 }
03419
03420
if (XCheckTypedWindowEvent(p->
display, p->
window, PropertyNotify, &pe) )
03421 compaction = True;
03422
else
03423
break;
03424 }
03425
03426 do_update =
true;
03427 }
else if (
event->type == ConfigureNotify) {
03428
03429
#ifdef NETWMDEBUG
03430
fprintf(stderr,
"NETWinInfo::event: handling ConfigureNotify event\n");
03431
#endif
03432
03433 dirty |= WMGeometry;
03434
03435
03436 p->
win_geom.
pos.
x =
event->xconfigure.x;
03437 p->
win_geom.
pos.
y =
event->xconfigure.y;
03438 p->
win_geom.
size.
width =
event->xconfigure.width;
03439 p->
win_geom.
size.
height =
event->xconfigure.height;
03440 }
03441
03442
if( do_update )
03443 update( props );
03444
03445
if( properties_size > PROPERTIES_SIZE )
03446 properties_size = PROPERTIES_SIZE;
03447
for(
int i = 0;
03448 i < properties_size;
03449 ++i )
03450 properties[ i ] = props[ i ];
03451 }
03452
03453
void NETWinInfo::updateWMState() {
03454
unsigned long props[ PROPERTIES_SIZE ] = { XAWMState, 0 };
03455 assert( PROPERTIES_SIZE == 2 );
03456 update( props );
03457 }
03458
03459
void NETWinInfo::update(
const unsigned long dirty_props[]) {
03460 Atom type_ret;
03461
int format_ret;
03462
unsigned long nitems_ret, unused;
03463
unsigned char *data_ret;
03464
unsigned long props[ PROPERTIES_SIZE ];
03465
for(
int i = 0;
03466 i < PROPERTIES_SIZE;
03467 ++i )
03468 props[ i ] = dirty_props[ i ] & p->
properties[ i ];
03469
const unsigned long& dirty = props[ PROTOCOLS ];
03470
const unsigned long& dirty2 = props[ PROTOCOLS2 ];
03471
03472
03473
if( dirty_props[ PROTOCOLS ] & XAWMState )
03474 props[ PROTOCOLS ] |= XAWMState;
03475
03476
if (dirty & XAWMState) {
03477 p->
mapping_state = Withdrawn;
03478
if (XGetWindowProperty(p->
display, p->
window, xa_wm_state, 0l, 1l,
03479 False, xa_wm_state, &type_ret, &format_ret,
03480 &nitems_ret, &unused, &data_ret)
03481 == Success) {
03482
if (type_ret == xa_wm_state && format_ret == 32 &&
03483 nitems_ret == 1) {
03484
long *state = (
long *) data_ret;
03485
03486
switch(*state) {
03487
case IconicState:
03488 p->
mapping_state = Iconic;
03489
break;
03490
case NormalState:
03491 p->
mapping_state = Visible;
03492
break;
03493
case WithdrawnState:
03494
default:
03495 p->
mapping_state = Withdrawn;
03496
break;
03497 }
03498
03499 p->
mapping_state_dirty = False;
03500 }
03501
if ( data_ret )
03502 XFree(data_ret);
03503 }
03504 }
03505
03506
if (dirty & WMState) {
03507 p->
state = 0;
03508
if (XGetWindowProperty(p->
display, p->
window, net_wm_state, 0l, 2048l,
03509 False, XA_ATOM, &type_ret, &format_ret,
03510 &nitems_ret, &unused, &data_ret)
03511 == Success) {
03512
if (type_ret == XA_ATOM && format_ret == 32 && nitems_ret > 0) {
03513
03514
#ifdef NETWMDEBUG
03515
fprintf(stderr,
"NETWinInfo::update: updating window state (%ld)\n",
03516 nitems_ret);
03517
#endif
03518
03519
long *states = (
long *) data_ret;
03520
unsigned long count;
03521
03522
for (count = 0; count < nitems_ret; count++) {
03523
#ifdef NETWMDEBUG
03524
char* data_ret = XGetAtomName(p->
display, (Atom) states[count]);
03525 fprintf(stderr,
03526
"NETWinInfo::update: adding window state %ld '%s'\n",
03527 states[count], data_ret );
03528
if ( data_ret )
03529 XFree( data_ret );
03530
#endif
03531
03532
if ((Atom) states[count] == net_wm_state_modal)
03533 p->
state |= Modal;
03534
else if ((Atom) states[count] == net_wm_state_sticky)
03535 p->
state |= Sticky;
03536
else if ((Atom) states[count] == net_wm_state_max_vert)
03537 p->
state |= MaxVert;
03538
else if ((Atom) states[count] == net_wm_state_max_horiz)
03539 p->
state |= MaxHoriz;
03540
else if ((Atom) states[count] == net_wm_state_shaded)
03541 p->
state |= Shaded;
03542
else if ((Atom) states[count] == net_wm_state_skip_taskbar)
03543 p->
state |= SkipTaskbar;
03544
else if ((Atom) states[count] == net_wm_state_skip_pager)
03545 p->
state |= SkipPager;
03546
else if ((Atom) states[count] == net_wm_state_hidden)
03547 p->
state |= Hidden;
03548
else if ((Atom) states[count] == net_wm_state_fullscreen)
03549 p->
state |=
FullScreen;
03550
else if ((Atom) states[count] == net_wm_state_above)
03551 p->
state |= KeepAbove;
03552
else if ((Atom) states[count] == net_wm_state_below)
03553 p->
state |= KeepBelow;
03554
else if ((Atom) states[count] == net_wm_state_demands_attention)
03555 p->
state |= DemandsAttention;
03556
else if ((Atom) states[count] == net_wm_state_stays_on_top)
03557 p->
state |= StaysOnTop;
03558 }
03559 }
03560
if ( data_ret )
03561 XFree(data_ret);
03562 }
03563 }
03564
03565
if (dirty & WMDesktop) {
03566 p->
desktop = 0;
03567
if (XGetWindowProperty(p->
display, p->
window, net_wm_desktop, 0l, 1l,
03568 False, XA_CARDINAL, &type_ret,
03569 &format_ret, &nitems_ret,
03570 &unused, &data_ret)
03571 == Success) {
03572
if (type_ret == XA_CARDINAL && format_ret == 32 &&
03573 nitems_ret == 1) {
03574 p->
desktop = *((
long *) data_ret);
03575
if ((
signed) p->
desktop != OnAllDesktops)
03576 p->
desktop++;
03577
03578
if ( p->
desktop == 0 )
03579 p->
desktop = OnAllDesktops;
03580 }
03581
if ( data_ret )
03582 XFree(data_ret);
03583 }
03584 }
03585
03586
if (dirty & WMName) {
03587
delete[] p->
name;
03588 p->
name = NULL;
03589
if (XGetWindowProperty(p->
display, p->
window, net_wm_name, 0l,
03590 MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
03591 &format_ret, &nitems_ret, &unused, &data_ret)
03592 == Success) {
03593
if (type_ret == UTF8_STRING && format_ret == 8 && nitems_ret > 0) {
03594 p->
name = nstrndup((
const char *) data_ret, nitems_ret);
03595 }
03596
03597
if( data_ret )
03598 XFree(data_ret);
03599 }
03600 }
03601
03602
if (dirty & WMVisibleName) {
03603
delete[] p->
visible_name;
03604 p->
visible_name = NULL;
03605
if (XGetWindowProperty(p->
display, p->
window, net_wm_visible_name, 0l,
03606 MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
03607 &format_ret, &nitems_ret, &unused, &data_ret)
03608 == Success) {
03609
if (type_ret == UTF8_STRING && format_ret == 8 && nitems_ret > 0) {
03610 p->
visible_name = nstrndup((
const char *) data_ret, nitems_ret);
03611 }
03612
03613
if( data_ret )
03614 XFree(data_ret);
03615 }
03616 }
03617
03618
if (dirty & WMIconName) {
03619
delete[] p->
icon_name;
03620 p->
icon_name = NULL;
03621
if (XGetWindowProperty(p->
display, p->
window, net_wm_icon_name, 0l,
03622 MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
03623 &format_ret, &nitems_ret, &unused, &data_ret)
03624 == Success) {
03625
if (type_ret == UTF8_STRING && format_ret == 8 && nitems_ret > 0) {
03626 p->
icon_name = nstrndup((
const char *) data_ret, nitems_ret);
03627 }
03628
03629
if( data_ret )
03630 XFree(data_ret);
03631 }
03632 }
03633
03634
if (dirty & WMVisibleIconName)
03635 {
03636
delete[] p->
visible_icon_name;
03637 p->
visible_icon_name = NULL;
03638
if (XGetWindowProperty(p->
display, p->
window, net_wm_visible_icon_name, 0l,
03639 MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
03640 &format_ret, &nitems_ret, &unused, &data_ret)
03641 == Success) {
03642
if (type_ret == UTF8_STRING && format_ret == 8 && nitems_ret > 0) {
03643 p->
visible_icon_name = nstrndup((
const char *) data_ret, nitems_ret);
03644 }
03645
03646
if( data_ret )
03647 XFree(data_ret);
03648 }
03649 }
03650
03651
if (dirty & WMWindowType) {
03652 p->
types.
reset();
03653 p->
types[ 0 ] = Unknown;
03654 p->
has_net_support =
false;
03655
if (XGetWindowProperty(p->
display, p->
window, net_wm_window_type, 0l, 2048l,
03656 False, XA_ATOM, &type_ret, &format_ret,
03657 &nitems_ret, &unused, &data_ret)
03658 == Success) {
03659
if (type_ret == XA_ATOM && format_ret == 32 && nitems_ret > 0) {
03660
03661
#ifdef NETWMDEBUG
03662
fprintf(stderr,
"NETWinInfo::update: getting window type (%ld)\n",
03663 nitems_ret);
03664
#endif
03665
03666 p->
has_net_support =
true;
03667
03668
unsigned long count = 0;
03669
long *types = (
long *) data_ret;
03670
int pos = 0;
03671
03672
while (count < nitems_ret) {
03673
03674
#ifdef NETWMDEBUG
03675
char* debug_type = XGetAtomName(p->
display, (Atom) types[count]);
03676 fprintf(stderr,
03677
"NETWinInfo::update: examining window type %ld %s\n",
03678 types[count], debug_type );
03679
if ( debug_type )
03680 XFree( debug_type );
03681
#endif
03682
03683
if ((Atom) types[count] == net_wm_window_type_normal)
03684 p->
types[ pos++ ] = Normal;
03685
else if ((Atom) types[count] == net_wm_window_type_desktop)
03686 p->
types[ pos++ ] = Desktop;
03687
else if ((Atom) types[count] == net_wm_window_type_dock)
03688 p->
types[ pos++ ] = Dock;
03689
else if ((Atom) types[count] == net_wm_window_type_toolbar)
03690 p->
types[ pos++ ] = Tool;
03691
else if ((Atom) types[count] == net_wm_window_type_menu)
03692 p->
types[ pos++ ] = Menu;
03693
else if ((Atom) types[count] == net_wm_window_type_dialog)
03694 p->
types[ pos++ ] = Dialog;
03695
else if ((Atom) types[count] == net_wm_window_type_utility)
03696 p->
types[ pos++ ] = Utility;
03697
else if ((Atom) types[count] == net_wm_window_type_splash)
03698 p->
types[ pos++ ] = Splash;
03699
else if ((Atom) types[count] == kde_net_wm_window_type_override)
03700 p->
types[ pos++ ] = Override;
03701
else if ((Atom) types[count] == kde_net_wm_window_type_topmenu)
03702 p->
types[ pos++ ] = TopMenu;
03703
03704 count++;
03705 }
03706 }
03707
03708
if ( data_ret )
03709 XFree(data_ret);
03710 }
03711 }
03712
03713
if (dirty & WMStrut) {
03714 p->
strut =
NETStrut();
03715
if (XGetWindowProperty(p->
display, p->
window, net_wm_strut, 0l, 4l,
03716 False, XA_CARDINAL, &type_ret, &format_ret,
03717 &nitems_ret, &unused, &data_ret)
03718 == Success) {
03719
if (type_ret == XA_CARDINAL && format_ret == 32 &&
03720 nitems_ret == 4) {
03721
long *d = (
long *) data_ret;
03722 p->
strut.
left = d[0];
03723 p->
strut.
right = d[1];
03724 p->
strut.
top = d[2];
03725 p->
strut.
bottom = d[3];
03726 }
03727
if ( data_ret )
03728 XFree(data_ret);
03729 }
03730 }
03731
03732
if (dirty & WMIconGeometry) {
03733 p->
icon_geom =
NETRect();
03734
if (XGetWindowProperty(p->
display, p->
window, net_wm_icon_geometry, 0l, 4l,
03735 False, XA_CARDINAL, &type_ret, &format_ret,
03736 &nitems_ret, &unused, &data_ret)
03737 == Success) {
03738
if (type_ret == XA_CARDINAL && format_ret == 32 &&
03739 nitems_ret == 4) {
03740
long *d = (
long *) data_ret;
03741 p->
icon_geom.
pos.
x = d[0];
03742 p->
icon_geom.
pos.
y = d[1];
03743 p->
icon_geom.
size.
width = d[2];
03744 p->
icon_geom.
size.
height = d[3];
03745 }
03746
if ( data_ret )
03747 XFree(data_ret);
03748 }
03749 }
03750
03751
if (dirty & WMIcon) {
03752 readIcon(p);
03753 }
03754
03755
if (dirty & WMKDESystemTrayWinFor) {
03756 p->
kde_system_tray_win_for = 0;
03757
if (XGetWindowProperty(p->
display, p->
window, kde_net_wm_system_tray_window_for,
03758 0l, 1l, False, XA_WINDOW, &type_ret, &format_ret,
03759 &nitems_ret, &unused, &data_ret)
03760 == Success) {
03761
if (type_ret == XA_WINDOW && format_ret == 32 &&
03762 nitems_ret == 1) {
03763 p->
kde_system_tray_win_for = *((Window *) data_ret);
03764
if ( p->
kde_system_tray_win_for == 0 )
03765 p->
kde_system_tray_win_for = p->
root;
03766 }
03767
if ( data_ret )
03768 XFree(data_ret);
03769 }
03770 }
03771
03772
if (dirty & WMKDEFrameStrut) {
03773 p->
frame_strut =
NETStrut();
03774
if (XGetWindowProperty(p->
display, p->
window, kde_net_wm_frame_strut,
03775 0l, 4l, False, XA_CARDINAL, &type_ret, &format_ret,
03776 &nitems_ret, &unused, &data_ret) == Success) {
03777
if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 4) {
03778
long *d = (
long *) data_ret;
03779
03780 p->
frame_strut.
left = d[0];
03781 p->
frame_strut.
right = d[1];
03782 p->
frame_strut.
top = d[2];
03783 p->
frame_strut.
bottom = d[3];
03784 }
03785
if ( data_ret )
03786 XFree(data_ret);
03787 }
03788 }
03789
03790
if (dirty & WMPid) {
03791 p->
pid = 0;
03792
if (XGetWindowProperty(p->
display, p->
window, net_wm_pid, 0l, 1l,
03793 False, XA_CARDINAL, &type_ret, &format_ret,
03794 &nitems_ret, &unused, &data_ret) == Success) {
03795
if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 1) {
03796 p->
pid = *((
long *) data_ret);
03797 }
03798
if ( data_ret )
03799 XFree(data_ret);
03800 }
03801 }
03802
03803
if (dirty2 & WM2StartupId)
03804 {
03805
delete[] p->
startup_id;
03806 p->
startup_id = NULL;
03807
if (XGetWindowProperty(p->
display, p->
window, net_startup_id, 0l,
03808 MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
03809 &format_ret, &nitems_ret, &unused, &data_ret)
03810 == Success) {
03811
if (type_ret == XA_STRING && format_ret == 8 && nitems_ret > 0) {
03812 p->
startup_id = nstrndup((
const char *) data_ret, nitems_ret);
03813 }
03814
03815
if( data_ret )
03816 XFree(data_ret);
03817 }
03818 }
03819
03820
if( dirty2 & WM2AllowedActions ) {
03821 p->
allowed_actions = 0;
03822
if (XGetWindowProperty(p->
display, p->
window, net_wm_allowed_actions, 0l, 2048l,
03823 False, XA_ATOM, &type_ret, &format_ret,
03824 &nitems_ret, &unused, &data_ret)
03825 == Success) {
03826
if (type_ret == XA_ATOM && format_ret == 32 && nitems_ret > 0) {
03827
03828
#ifdef NETWMDEBUG
03829
fprintf(stderr,
"NETWinInfo::update: updating allowed actions (%ld)\n",
03830 nitems_ret);
03831
#endif
03832
03833
long *actions = (
long *) data_ret;
03834
unsigned long count;
03835
03836
for (count = 0; count < nitems_ret; count++) {
03837
#ifdef NETWMDEBUG
03838
fprintf(stderr,
03839
"NETWinInfo::update: adding allowed action %ld '%s'\n",
03840 actions[count],
03841 XGetAtomName(p->
display, (Atom) actions[count]));
03842
#endif
03843
03844
if ((Atom) actions[count] == net_wm_action_move)
03845 p->
allowed_actions |= ActionMove;
03846
if ((Atom) actions[count] == net_wm_action_resize)
03847 p->
allowed_actions |= ActionResize;
03848
if ((Atom) actions[count] == net_wm_action_minimize)
03849 p->
allowed_actions |= ActionMinimize;
03850
if ((Atom) actions[count] == net_wm_action_shade)
03851 p->
allowed_actions |= ActionShade;
03852
if ((Atom) actions[count] == net_wm_action_stick)
03853 p->
allowed_actions |= ActionStick;
03854
if ((Atom) actions[count] == net_wm_action_max_vert)
03855 p->
allowed_actions |= ActionMaxVert;
03856
if ((Atom) actions[count] == net_wm_action_max_horiz)
03857 p->
allowed_actions |= ActionMaxHoriz;
03858
if ((Atom) actions[count] == net_wm_action_fullscreen)
03859 p->
allowed_actions |= ActionFullScreen;
03860
if ((Atom) actions[count] == net_wm_action_change_desk)
03861 p->
allowed_actions |= ActionChangeDesktop;
03862
if ((Atom) actions[count] == net_wm_action_close)
03863 p->
allowed_actions |= ActionClose;
03864 }
03865 }
03866
if ( data_ret )
03867 XFree(data_ret);
03868 }
03869 }
03870
03871
if (dirty2 & WM2UserTime) {
03872 p->
user_time = -1U;
03873
if (XGetWindowProperty(p->
display, p->
window, net_wm_user_time, 0l, 1l,
03874 False, XA_CARDINAL, &type_ret, &format_ret,
03875 &nitems_ret, &unused, &data_ret) == Success) {
03876
03877
if (type_ret == XA_CARDINAL && format_ret == 32 ) {
03878 p->
user_time = *((
long *) data_ret);
03879 }
03880
if ( data_ret )
03881 XFree(data_ret);
03882 }
03883 }
03884
03885
if (dirty2 & WM2TransientFor) {
03886 p->
transient_for = None;
03887 XGetTransientForHint(p->
display, p->
window, &p->
transient_for);
03888 }
03889
03890
if (dirty2 & WM2GroupLeader) {
03891 XWMHints *hints = XGetWMHints(p->
display, p->
window);
03892 p->
window_group = None;
03893
if ( hints )
03894 {
03895
if( hints->flags & WindowGroupHint )
03896 p->
window_group = hints->window_group;
03897 XFree( reinterpret_cast< char* >( hints ));
03898 }
03899 }
03900
03901 }
03902
03903
03904
NETRect NETWinInfo::iconGeometry()
const {
03905
return p->
icon_geom;
03906 }
03907
03908
03909
unsigned long NETWinInfo::state()
const {
03910
return p->
state;
03911 }
03912
03913
03914
NETStrut NETWinInfo::strut()
const {
03915
return p->
strut;
03916 }
03917
03918
NET::WindowType NETWinInfo::windowType(
unsigned long supported_types )
const {
03919
for(
int i = 0;
03920 i < p->
types.
size();
03921 ++i ) {
03922
switch( p->
types[ i ] ) {
03923
03924
#define CHECK_TYPE_MASK( type ) \
03925
case type: \
03926
if( supported_types & type##Mask ) \
03927
return type; \
03928
break;
03929
CHECK_TYPE_MASK( Normal )
03930 CHECK_TYPE_MASK( Desktop )
03931 CHECK_TYPE_MASK( Dock )
03932 CHECK_TYPE_MASK( Toolbar )
03933 CHECK_TYPE_MASK( Menu )
03934 CHECK_TYPE_MASK( Dialog )
03935 CHECK_TYPE_MASK( Override )
03936 CHECK_TYPE_MASK( TopMenu )
03937 CHECK_TYPE_MASK( Utility )
03938 CHECK_TYPE_MASK( Splash )
03939 #undef CHECK_TYPE_MASK
03940 default:
03941 break;
03942 }
03943 }
03944 return Unknown;
03945 }
03946
03947
NET::WindowType NETWinInfo::windowType()
const {
03948
return p->
types[ 0 ];
03949 }
03950
03951
03952
const char *NETWinInfo::name()
const {
03953
return p->
name;
03954 }
03955
03956
03957
const char *NETWinInfo::visibleName()
const {
03958
return p->
visible_name;
03959 }
03960
03961
03962
const char *NETWinInfo::iconName()
const {
03963
return p->
icon_name;
03964 }
03965
03966
03967
const char *NETWinInfo::visibleIconName()
const {
03968
return p->
visible_icon_name;
03969 }
03970
03971
03972
int NETWinInfo::desktop()
const {
03973
return p->
desktop;
03974 }
03975
03976
int NETWinInfo::pid()
const {
03977
return p->
pid;
03978 }
03979
03980 Time NETWinInfo::userTime()
const {
03981
return p->
user_time;
03982 }
03983
03984
const char* NETWinInfo::startupId()
const {
03985
return p->
startup_id;
03986 }
03987
03988
unsigned long NETWinInfo::allowedActions()
const {
03989
return p->
allowed_actions;
03990 }
03991
03992
bool NETWinInfo::hasNETSupport()
const {
03993
return p->
has_net_support;
03994 }
03995
03996 Window NETWinInfo::transientFor()
const {
03997
return p->
transient_for;
03998 }
03999
04000 Window NETWinInfo::groupLeader()
const {
04001
return p->
window_group;
04002 }
04003
04004 Bool NETWinInfo::handledIcons()
const {
04005
return p->
handled_icons;
04006 }
04007
04008
04009 Window NETWinInfo::kdeSystemTrayWinFor()
const {
04010
return p->
kde_system_tray_win_for;
04011 }
04012
04013
const unsigned long* NETWinInfo::passedProperties()
const {
04014
return p->
properties;
04015 }
04016
04017
unsigned long NETWinInfo::properties()
const {
04018
return p->
properties[ PROTOCOLS ];
04019 }
04020
04021
04022
NET::MappingState NETWinInfo::mappingState()
const {
04023
return p->
mapping_state;
04024 }
04025
04026
void NETRootInfo::virtual_hook(
int,
void* )
04027 { }
04028
04029
void NETWinInfo::virtual_hook(
int,
void* )
04030 { }
04031
04032
#endif