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