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