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