00001
00002
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #define _GNU_SOURCE
00037 #define _SVID_SOURCE
00038
00039 #include <config.h>
00040 #include "window-props.h"
00041 #include "errors.h"
00042 #include "xprops.h"
00043 #include "frame-private.h"
00044 #include "group.h"
00045 #include <X11/Xatom.h>
00046 #include <unistd.h>
00047 #include <string.h>
00048 #ifndef HOST_NAME_MAX
00049
00050 #define HOST_NAME_MAX 255
00051 #endif
00052
00053 typedef void (* InitValueFunc) (MetaDisplay *display,
00054 Atom property,
00055 MetaPropValue *value);
00056 typedef void (* ReloadValueFunc) (MetaWindow *window,
00057 MetaPropValue *value);
00058
00059 struct _MetaWindowPropHooks
00060 {
00061 Atom property;
00062 InitValueFunc init_func;
00063 ReloadValueFunc reload_func;
00064 };
00065
00066 static void init_prop_value (MetaDisplay *display,
00067 Atom property,
00068 MetaPropValue *value);
00069 static void reload_prop_value (MetaWindow *window,
00070 MetaPropValue *value);
00071 static MetaWindowPropHooks* find_hooks (MetaDisplay *display,
00072 Atom property);
00073
00074
00075 void
00076 meta_window_reload_property (MetaWindow *window,
00077 Atom property)
00078 {
00079 meta_window_reload_properties (window, &property, 1);
00080 }
00081
00082 void
00083 meta_window_reload_properties (MetaWindow *window,
00084 const Atom *properties,
00085 int n_properties)
00086 {
00087 meta_window_reload_properties_from_xwindow (window,
00088 window->xwindow,
00089 properties,
00090 n_properties);
00091 }
00092
00093 void
00094 meta_window_reload_property_from_xwindow (MetaWindow *window,
00095 Window xwindow,
00096 Atom property)
00097 {
00098 meta_window_reload_properties_from_xwindow (window, xwindow, &property, 1);
00099 }
00100
00101 void
00102 meta_window_reload_properties_from_xwindow (MetaWindow *window,
00103 Window xwindow,
00104 const Atom *properties,
00105 int n_properties)
00106 {
00107 int i;
00108 MetaPropValue *values;
00109
00110 g_return_if_fail (properties != NULL);
00111 g_return_if_fail (n_properties > 0);
00112
00113 values = g_new0 (MetaPropValue, n_properties);
00114
00115 i = 0;
00116 while (i < n_properties)
00117 {
00118 init_prop_value (window->display, properties[i], &values[i]);
00119 ++i;
00120 }
00121
00122 meta_prop_get_values (window->display, xwindow,
00123 values, n_properties);
00124
00125 i = 0;
00126 while (i < n_properties)
00127 {
00128 reload_prop_value (window, &values[i]);
00129
00130 ++i;
00131 }
00132
00133 meta_prop_free_values (values, n_properties);
00134
00135 g_free (values);
00136 }
00137
00138
00139 static void
00140 init_prop_value (MetaDisplay *display,
00141 Atom property,
00142 MetaPropValue *value)
00143 {
00144 MetaWindowPropHooks *hooks;
00145
00146 value->type = META_PROP_VALUE_INVALID;
00147 value->atom = None;
00148
00149 hooks = find_hooks (display, property);
00150 if (hooks && hooks->init_func != NULL)
00151 (* hooks->init_func) (display, property, value);
00152 }
00153
00154 static void
00155 reload_prop_value (MetaWindow *window,
00156 MetaPropValue *value)
00157 {
00158 MetaWindowPropHooks *hooks;
00159
00160 hooks = find_hooks (window->display, value->atom);
00161 if (hooks && hooks->reload_func != NULL)
00162 (* hooks->reload_func) (window, value);
00163 }
00164
00165 static void
00166 init_wm_client_machine (MetaDisplay *display,
00167 Atom property,
00168 MetaPropValue *value)
00169 {
00170 value->type = META_PROP_VALUE_STRING;
00171 value->atom = display->atom_WM_CLIENT_MACHINE;
00172 }
00173
00174 static void
00175 reload_wm_client_machine (MetaWindow *window,
00176 MetaPropValue *value)
00177 {
00178 g_free (window->wm_client_machine);
00179 window->wm_client_machine = NULL;
00180
00181 if (value->type != META_PROP_VALUE_INVALID)
00182 window->wm_client_machine = g_strdup (value->v.str);
00183
00184 meta_verbose ("Window has client machine \"%s\"\n",
00185 window->wm_client_machine ? window->wm_client_machine : "unset");
00186 }
00187
00188 static void
00189 init_net_wm_pid (MetaDisplay *display,
00190 Atom property,
00191 MetaPropValue *value)
00192 {
00193 value->type = META_PROP_VALUE_CARDINAL;
00194 value->atom = display->atom__NET_WM_PID;
00195 }
00196
00197 static void
00198 reload_net_wm_pid (MetaWindow *window,
00199 MetaPropValue *value)
00200 {
00201 if (value->type != META_PROP_VALUE_INVALID)
00202 {
00203 gulong cardinal = (int) value->v.cardinal;
00204
00205 if (cardinal <= 0)
00206 meta_warning (_("Application set a bogus _NET_WM_PID %lu\n"),
00207 cardinal);
00208 else
00209 {
00210 window->net_wm_pid = cardinal;
00211 meta_verbose ("Window has _NET_WM_PID %d\n",
00212 window->net_wm_pid);
00213 }
00214 }
00215 }
00216
00217 static void
00218 init_net_wm_user_time (MetaDisplay *display,
00219 Atom property,
00220 MetaPropValue *value)
00221 {
00222 value->type = META_PROP_VALUE_CARDINAL;
00223 value->atom = display->atom__NET_WM_USER_TIME;
00224 }
00225
00226 static void
00227 reload_net_wm_user_time (MetaWindow *window,
00228 MetaPropValue *value)
00229 {
00230 if (value->type != META_PROP_VALUE_INVALID)
00231 {
00232 gulong cardinal = value->v.cardinal;
00233 meta_window_set_user_time (window, cardinal);
00234 }
00235 }
00236
00237 static void
00238 init_net_wm_user_time_window (MetaDisplay *display,
00239 Atom property,
00240 MetaPropValue *value)
00241 {
00242 value->type = META_PROP_VALUE_WINDOW;
00243 value->atom = display->atom__NET_WM_USER_TIME_WINDOW;
00244 }
00245
00246 static void
00247 reload_net_wm_user_time_window (MetaWindow *window,
00248 MetaPropValue *value)
00249 {
00250 if (value->type != META_PROP_VALUE_INVALID)
00251 {
00252
00253 if (window->user_time_window != None)
00254 {
00255
00256 meta_display_unregister_x_window (window->display,
00257 window->user_time_window);
00258
00259 XSelectInput (window->display->xdisplay,
00260 window->user_time_window,
00261 NoEventMask);
00262 }
00263
00264
00265
00266 window->user_time_window = value->v.xwindow;
00267 if (window->user_time_window != None)
00268 {
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 meta_display_register_x_window (window->display,
00282 &window->user_time_window,
00283 window);
00284
00285 XSelectInput (window->display->xdisplay,
00286 window->user_time_window,
00287 PropertyChangeMask);
00288
00289
00290
00291
00292
00293 meta_window_reload_property_from_xwindow (
00294 window,
00295 window->user_time_window,
00296 window->display->atom__NET_WM_USER_TIME);
00297 }
00298 }
00299 }
00300
00301 #define MAX_TITLE_LENGTH 512
00302
00310 static gboolean
00311 set_title_text (MetaWindow *window,
00312 gboolean previous_was_modified,
00313 const char *title,
00314 Atom atom,
00315 char **target)
00316 {
00317 char hostname[HOST_NAME_MAX + 1];
00318 gboolean modified = FALSE;
00319
00320 if (!target)
00321 return FALSE;
00322
00323 g_free (*target);
00324
00325 if (!title)
00326 *target = g_strdup ("");
00327 else if (g_utf8_strlen (title, MAX_TITLE_LENGTH + 1) > MAX_TITLE_LENGTH)
00328 {
00329 *target = meta_g_utf8_strndup (title, MAX_TITLE_LENGTH);
00330 modified = TRUE;
00331 }
00332
00333
00334 else if (window->wm_client_machine &&
00335 !gethostname (hostname, HOST_NAME_MAX + 1) &&
00336 strcmp (hostname, window->wm_client_machine))
00337 {
00338 *target = g_strdup_printf (_("%s (on %s)"),
00339 title, window->wm_client_machine);
00340 modified = TRUE;
00341 }
00342 else
00343 *target = g_strdup (title);
00344
00345 if (modified && atom != None)
00346 meta_prop_set_utf8_string_hint (window->display,
00347 window->xwindow,
00348 atom, *target);
00349
00350
00351 if (!modified && previous_was_modified)
00352 {
00353 meta_error_trap_push (window->display);
00354 XDeleteProperty (window->display->xdisplay,
00355 window->xwindow,
00356 atom);
00357 meta_error_trap_pop (window->display, FALSE);
00358 }
00359
00360 return modified;
00361 }
00362
00363 static void
00364 set_window_title (MetaWindow *window,
00365 const char *title)
00366 {
00367 char *str;
00368
00369 gboolean modified =
00370 set_title_text (window,
00371 window->using_net_wm_visible_name,
00372 title,
00373 window->display->atom__NET_WM_VISIBLE_NAME,
00374 &window->title);
00375 window->using_net_wm_visible_name = modified;
00376
00377
00378 str = g_strndup (window->title, 10);
00379 g_free (window->desc);
00380 window->desc = g_strdup_printf ("0x%lx (%s)", window->xwindow, str);
00381 g_free (str);
00382
00383 if (window->frame)
00384 meta_ui_set_frame_title (window->screen->ui,
00385 window->frame->xwindow,
00386 window->title);
00387 }
00388
00389 static void
00390 init_net_wm_name (MetaDisplay *display,
00391 Atom property,
00392 MetaPropValue *value)
00393 {
00394 value->type = META_PROP_VALUE_UTF8;
00395 value->atom = display->atom__NET_WM_NAME;
00396 }
00397
00398 static void
00399 reload_net_wm_name (MetaWindow *window,
00400 MetaPropValue *value)
00401 {
00402 if (value->type != META_PROP_VALUE_INVALID)
00403 {
00404 set_window_title (window, value->v.str);
00405 window->using_net_wm_name = TRUE;
00406
00407 meta_verbose ("Using _NET_WM_NAME for new title of %s: \"%s\"\n",
00408 window->desc, window->title);
00409 }
00410 else
00411 {
00412 set_window_title (window, NULL);
00413 window->using_net_wm_name = FALSE;
00414 }
00415 }
00416
00417
00418 static void
00419 init_wm_name (MetaDisplay *display,
00420 Atom property,
00421 MetaPropValue *value)
00422 {
00423 value->type = META_PROP_VALUE_TEXT_PROPERTY;
00424 value->atom = XA_WM_NAME;
00425 }
00426
00427 static void
00428 reload_wm_name (MetaWindow *window,
00429 MetaPropValue *value)
00430 {
00431 if (window->using_net_wm_name)
00432 {
00433 meta_verbose ("Ignoring WM_NAME \"%s\" as _NET_WM_NAME is set\n",
00434 value->v.str);
00435 return;
00436 }
00437
00438 if (value->type != META_PROP_VALUE_INVALID)
00439 {
00440 set_window_title (window, value->v.str);
00441
00442 meta_verbose ("Using WM_NAME for new title of %s: \"%s\"\n",
00443 window->desc, window->title);
00444 }
00445 else
00446 {
00447 set_window_title (window, NULL);
00448 }
00449 }
00450
00451 static void
00452 set_icon_title (MetaWindow *window,
00453 const char *title)
00454 {
00455 gboolean modified =
00456 set_title_text (window,
00457 window->using_net_wm_visible_icon_name,
00458 title,
00459 window->display->atom__NET_WM_VISIBLE_ICON_NAME,
00460 &window->icon_name);
00461 window->using_net_wm_visible_icon_name = modified;
00462 }
00463
00464 static void
00465 init_net_wm_icon_name (MetaDisplay *display,
00466 Atom property,
00467 MetaPropValue *value)
00468 {
00469 value->type = META_PROP_VALUE_UTF8;
00470 value->atom = display->atom__NET_WM_ICON_NAME;
00471 }
00472
00473 static void
00474 reload_net_wm_icon_name (MetaWindow *window,
00475 MetaPropValue *value)
00476 {
00477 if (value->type != META_PROP_VALUE_INVALID)
00478 {
00479 set_icon_title (window, value->v.str);
00480 window->using_net_wm_icon_name = TRUE;
00481
00482 meta_verbose ("Using _NET_WM_ICON_NAME for new title of %s: \"%s\"\n",
00483 window->desc, window->title);
00484 }
00485 else
00486 {
00487 set_icon_title (window, NULL);
00488 window->using_net_wm_icon_name = FALSE;
00489 }
00490 }
00491
00492
00493 static void
00494 init_wm_icon_name (MetaDisplay *display,
00495 Atom property,
00496 MetaPropValue *value)
00497 {
00498 value->type = META_PROP_VALUE_TEXT_PROPERTY;
00499 value->atom = XA_WM_ICON_NAME;
00500 }
00501
00502 static void
00503 reload_wm_icon_name (MetaWindow *window,
00504 MetaPropValue *value)
00505 {
00506 if (window->using_net_wm_icon_name)
00507 {
00508 meta_verbose ("Ignoring WM_ICON_NAME \"%s\" as _NET_WM_ICON_NAME is set\n",
00509 value->v.str);
00510 return;
00511 }
00512
00513 if (value->type != META_PROP_VALUE_INVALID)
00514 {
00515 set_icon_title (window, value->v.str);
00516
00517 meta_verbose ("Using WM_ICON_NAME for new title of %s: \"%s\"\n",
00518 window->desc, window->title);
00519 }
00520 else
00521 {
00522 set_icon_title (window, NULL);
00523 }
00524 }
00525
00526 static void
00527 init_net_wm_state (MetaDisplay *display,
00528 Atom property,
00529 MetaPropValue *value)
00530 {
00531 value->type = META_PROP_VALUE_ATOM_LIST;
00532 value->atom = display->atom__NET_WM_STATE;
00533 }
00534
00535 static void
00536 reload_net_wm_state (MetaWindow *window,
00537 MetaPropValue *value)
00538 {
00539 int i;
00540
00541
00542
00543
00544
00545 window->shaded = FALSE;
00546 window->maximized_horizontally = FALSE;
00547 window->maximized_vertically = FALSE;
00548 window->wm_state_modal = FALSE;
00549 window->wm_state_skip_taskbar = FALSE;
00550 window->wm_state_skip_pager = FALSE;
00551 window->wm_state_above = FALSE;
00552 window->wm_state_below = FALSE;
00553 window->wm_state_demands_attention = FALSE;
00554
00555 if (value->type == META_PROP_VALUE_INVALID)
00556 return;
00557
00558 i = 0;
00559 while (i < value->v.atom_list.n_atoms)
00560 {
00561 if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_SHADED)
00562 window->shaded = TRUE;
00563 else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_MAXIMIZED_HORZ)
00564 window->maximize_horizontally_after_placement = TRUE;
00565 else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_MAXIMIZED_VERT)
00566 window->maximize_vertically_after_placement = TRUE;
00567 else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_HIDDEN)
00568 window->minimize_after_placement = TRUE;
00569 else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_MODAL)
00570 window->wm_state_modal = TRUE;
00571 else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_SKIP_TASKBAR)
00572 window->wm_state_skip_taskbar = TRUE;
00573 else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_SKIP_PAGER)
00574 window->wm_state_skip_pager = TRUE;
00575 else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_FULLSCREEN)
00576 window->fullscreen = TRUE;
00577 else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_ABOVE)
00578 window->wm_state_above = TRUE;
00579 else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_BELOW)
00580 window->wm_state_below = TRUE;
00581 else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_DEMANDS_ATTENTION)
00582 window->wm_state_demands_attention = TRUE;
00583
00584 ++i;
00585 }
00586
00587 meta_verbose ("Reloaded _NET_WM_STATE for %s\n",
00588 window->desc);
00589
00590 meta_window_recalc_window_type (window);
00591 }
00592
00593 static void
00594 init_mwm_hints (MetaDisplay *display,
00595 Atom property,
00596 MetaPropValue *value)
00597 {
00598 value->type = META_PROP_VALUE_MOTIF_HINTS;
00599 value->atom = display->atom__MOTIF_WM_HINTS;
00600 }
00601
00602 static void
00603 reload_mwm_hints (MetaWindow *window,
00604 MetaPropValue *value)
00605 {
00606 MotifWmHints *hints;
00607
00608 window->mwm_decorated = TRUE;
00609 window->mwm_border_only = FALSE;
00610 window->mwm_has_close_func = TRUE;
00611 window->mwm_has_minimize_func = TRUE;
00612 window->mwm_has_maximize_func = TRUE;
00613 window->mwm_has_move_func = TRUE;
00614 window->mwm_has_resize_func = TRUE;
00615
00616 if (value->type == META_PROP_VALUE_INVALID)
00617 {
00618 meta_verbose ("Window %s has no MWM hints\n", window->desc);
00619 meta_window_recalc_features (window);
00620 return;
00621 }
00622
00623 hints = value->v.motif_hints;
00624
00625
00626
00627 meta_verbose ("Window %s has MWM hints\n",
00628 window->desc);
00629
00630 if (hints->flags & MWM_HINTS_DECORATIONS)
00631 {
00632 meta_verbose ("Window %s sets MWM_HINTS_DECORATIONS 0x%lx\n",
00633 window->desc, hints->decorations);
00634
00635 if (hints->decorations == 0)
00636 window->mwm_decorated = FALSE;
00637
00638 else if (hints->decorations == MWM_DECOR_BORDER)
00639 window->mwm_border_only = TRUE;
00640 }
00641 else
00642 meta_verbose ("Decorations flag unset\n");
00643
00644 if (hints->flags & MWM_HINTS_FUNCTIONS)
00645 {
00646 gboolean toggle_value;
00647
00648 meta_verbose ("Window %s sets MWM_HINTS_FUNCTIONS 0x%lx\n",
00649 window->desc, hints->functions);
00650
00651
00652
00653
00654
00655
00656 if ((hints->functions & MWM_FUNC_ALL) == 0)
00657 {
00658 toggle_value = TRUE;
00659
00660 meta_verbose ("Window %s disables all funcs then reenables some\n",
00661 window->desc);
00662 window->mwm_has_close_func = FALSE;
00663 window->mwm_has_minimize_func = FALSE;
00664 window->mwm_has_maximize_func = FALSE;
00665 window->mwm_has_move_func = FALSE;
00666 window->mwm_has_resize_func = FALSE;
00667 }
00668 else
00669 {
00670 meta_verbose ("Window %s enables all funcs then disables some\n",
00671 window->desc);
00672 toggle_value = FALSE;
00673 }
00674
00675 if ((hints->functions & MWM_FUNC_CLOSE) != 0)
00676 {
00677 meta_verbose ("Window %s toggles close via MWM hints\n",
00678 window->desc);
00679 window->mwm_has_close_func = toggle_value;
00680 }
00681 if ((hints->functions & MWM_FUNC_MINIMIZE) != 0)
00682 {
00683 meta_verbose ("Window %s toggles minimize via MWM hints\n",
00684 window->desc);
00685 window->mwm_has_minimize_func = toggle_value;
00686 }
00687 if ((hints->functions & MWM_FUNC_MAXIMIZE) != 0)
00688 {
00689 meta_verbose ("Window %s toggles maximize via MWM hints\n",
00690 window->desc);
00691 window->mwm_has_maximize_func = toggle_value;
00692 }
00693 if ((hints->functions & MWM_FUNC_MOVE) != 0)
00694 {
00695 meta_verbose ("Window %s toggles move via MWM hints\n",
00696 window->desc);
00697 window->mwm_has_move_func = toggle_value;
00698 }
00699 if ((hints->functions & MWM_FUNC_RESIZE) != 0)
00700 {
00701 meta_verbose ("Window %s toggles resize via MWM hints\n",
00702 window->desc);
00703 window->mwm_has_resize_func = toggle_value;
00704 }
00705 }
00706 else
00707 meta_verbose ("Functions flag unset\n");
00708
00709 meta_window_recalc_features (window);
00710
00711
00712 if (!window->constructing)
00713 {
00714 if (window->decorated)
00715 meta_window_ensure_frame (window);
00716 else
00717 meta_window_destroy_frame (window);
00718
00719 meta_window_queue (window,
00720 META_QUEUE_MOVE_RESIZE |
00721
00722 META_QUEUE_CALC_SHOWING);
00723 }
00724 }
00725
00726 static void
00727 init_wm_class (MetaDisplay *display,
00728 Atom property,
00729 MetaPropValue *value)
00730 {
00731 value->type = META_PROP_VALUE_CLASS_HINT;
00732 value->atom = XA_WM_CLASS;
00733 }
00734
00735 static void
00736 reload_wm_class (MetaWindow *window,
00737 MetaPropValue *value)
00738 {
00739 if (window->res_class)
00740 g_free (window->res_class);
00741 if (window->res_name)
00742 g_free (window->res_name);
00743
00744 window->res_class = NULL;
00745 window->res_name = NULL;
00746
00747 if (value->type != META_PROP_VALUE_INVALID)
00748 {
00749 if (value->v.class_hint.res_name)
00750 window->res_name = g_strdup (value->v.class_hint.res_name);
00751
00752 if (value->v.class_hint.res_class)
00753 window->res_class = g_strdup (value->v.class_hint.res_class);
00754 }
00755
00756 meta_verbose ("Window %s class: '%s' name: '%s'\n",
00757 window->desc,
00758 window->res_class ? window->res_class : "none",
00759 window->res_name ? window->res_name : "none");
00760 }
00761
00762 static void
00763 init_net_wm_desktop (MetaDisplay *display,
00764 Atom property,
00765 MetaPropValue *value)
00766 {
00767 value->type = META_PROP_VALUE_CARDINAL;
00768 value->atom = display->atom__NET_WM_DESKTOP;
00769 }
00770
00771 static void
00772 reload_net_wm_desktop (MetaWindow *window,
00773 MetaPropValue *value)
00774 {
00775 if (value->type != META_PROP_VALUE_INVALID)
00776 {
00777 window->initial_workspace_set = TRUE;
00778 window->initial_workspace = value->v.cardinal;
00779 meta_topic (META_DEBUG_PLACEMENT,
00780 "Read initial workspace prop %d for %s\n",
00781 window->initial_workspace, window->desc);
00782 }
00783 }
00784
00785 static void
00786 init_net_startup_id (MetaDisplay *display,
00787 Atom property,
00788 MetaPropValue *value)
00789 {
00790 value->type = META_PROP_VALUE_UTF8;
00791 value->atom = display->atom__NET_STARTUP_ID;
00792 }
00793
00794 static void
00795 reload_net_startup_id (MetaWindow *window,
00796 MetaPropValue *value)
00797 {
00798 guint32 timestamp = window->net_wm_user_time;
00799 MetaWorkspace *workspace = NULL;
00800
00801 g_free (window->startup_id);
00802
00803 if (value->type != META_PROP_VALUE_INVALID)
00804 window->startup_id = g_strdup (value->v.str);
00805 else
00806 window->startup_id = NULL;
00807
00808
00809 if (!window->constructing)
00810 {
00811 window->initial_timestamp_set = 0;
00812 window->initial_workspace_set = 0;
00813
00814 if (meta_screen_apply_startup_properties (window->screen, window))
00815 {
00816
00817 if (window->initial_timestamp_set)
00818 timestamp = window->initial_timestamp;
00819 if (window->initial_workspace_set)
00820 workspace = meta_screen_get_workspace_by_index (window->screen, window->initial_workspace);
00821
00822 meta_window_activate_with_workspace (window, timestamp, workspace);
00823 }
00824 }
00825
00826 meta_verbose ("New _NET_STARTUP_ID \"%s\" for %s\n",
00827 window->startup_id ? window->startup_id : "unset",
00828 window->desc);
00829 }
00830
00831 static void
00832 init_update_counter (MetaDisplay *display,
00833 Atom property,
00834 MetaPropValue *value)
00835 {
00836 value->type = META_PROP_VALUE_SYNC_COUNTER;
00837 value->atom = display->atom__NET_WM_SYNC_REQUEST_COUNTER;
00838 }
00839
00840 static void
00841 reload_update_counter (MetaWindow *window,
00842 MetaPropValue *value)
00843 {
00844 if (value->type != META_PROP_VALUE_INVALID)
00845 {
00846 #ifdef HAVE_XSYNC
00847 XSyncCounter counter = value->v.xcounter;
00848
00849 window->sync_request_counter = counter;
00850 meta_verbose ("Window has _NET_WM_SYNC_REQUEST_COUNTER 0x%lx\n",
00851 window->sync_request_counter);
00852 #endif
00853 }
00854 }
00855
00856
00857 static void
00858 init_normal_hints (MetaDisplay *display,
00859 Atom property,
00860 MetaPropValue *value)
00861 {
00862 value->type = META_PROP_VALUE_SIZE_HINTS;
00863 value->atom = XA_WM_NORMAL_HINTS;
00864 }
00865
00866
00867 #define FLAG_TOGGLED_ON(old,new,flag) \
00868 (((old)->flags & (flag)) == 0 && \
00869 ((new)->flags & (flag)) != 0)
00870
00871 #define FLAG_TOGGLED_OFF(old,new,flag) \
00872 (((old)->flags & (flag)) != 0 && \
00873 ((new)->flags & (flag)) == 0)
00874
00875 #define FLAG_CHANGED(old,new,flag) \
00876 (FLAG_TOGGLED_ON(old,new,flag) || FLAG_TOGGLED_OFF(old,new,flag))
00877
00878 static void
00879 spew_size_hints_differences (const XSizeHints *old,
00880 const XSizeHints *new)
00881 {
00882 if (FLAG_CHANGED (old, new, USPosition))
00883 meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: USPosition now %s\n",
00884 FLAG_TOGGLED_ON (old, new, USPosition) ? "set" : "unset");
00885 if (FLAG_CHANGED (old, new, USSize))
00886 meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: USSize now %s\n",
00887 FLAG_TOGGLED_ON (old, new, USSize) ? "set" : "unset");
00888 if (FLAG_CHANGED (old, new, PPosition))
00889 meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PPosition now %s\n",
00890 FLAG_TOGGLED_ON (old, new, PPosition) ? "set" : "unset");
00891 if (FLAG_CHANGED (old, new, PSize))
00892 meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PSize now %s\n",
00893 FLAG_TOGGLED_ON (old, new, PSize) ? "set" : "unset");
00894 if (FLAG_CHANGED (old, new, PMinSize))
00895 meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PMinSize now %s (%d x %d -> %d x %d)\n",
00896 FLAG_TOGGLED_ON (old, new, PMinSize) ? "set" : "unset",
00897 old->min_width, old->min_height,
00898 new->min_width, new->min_height);
00899 if (FLAG_CHANGED (old, new, PMaxSize))
00900 meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PMaxSize now %s (%d x %d -> %d x %d)\n",
00901 FLAG_TOGGLED_ON (old, new, PMaxSize) ? "set" : "unset",
00902 old->max_width, old->max_height,
00903 new->max_width, new->max_height);
00904 if (FLAG_CHANGED (old, new, PResizeInc))
00905 meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PResizeInc now %s (width_inc %d -> %d height_inc %d -> %d)\n",
00906 FLAG_TOGGLED_ON (old, new, PResizeInc) ? "set" : "unset",
00907 old->width_inc, new->width_inc,
00908 old->height_inc, new->height_inc);
00909 if (FLAG_CHANGED (old, new, PAspect))
00910 meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PAspect now %s (min %d/%d -> %d/%d max %d/%d -> %d/%d)\n",
00911 FLAG_TOGGLED_ON (old, new, PAspect) ? "set" : "unset",
00912 old->min_aspect.x, old->min_aspect.y,
00913 new->min_aspect.x, new->min_aspect.y,
00914 old->max_aspect.x, old->max_aspect.y,
00915 new->max_aspect.x, new->max_aspect.y);
00916 if (FLAG_CHANGED (old, new, PBaseSize))
00917 meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PBaseSize now %s (%d x %d -> %d x %d)\n",
00918 FLAG_TOGGLED_ON (old, new, PBaseSize) ? "set" : "unset",
00919 old->base_width, old->base_height,
00920 new->base_width, new->base_height);
00921 if (FLAG_CHANGED (old, new, PWinGravity))
00922 meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PWinGravity now %s (%d -> %d)\n",
00923 FLAG_TOGGLED_ON (old, new, PWinGravity) ? "set" : "unset",
00924 old->win_gravity, new->win_gravity);
00925 }
00926
00927 void
00928 meta_set_normal_hints (MetaWindow *window,
00929 XSizeHints *hints)
00930 {
00931 int x, y, w, h;
00932 double minr, maxr;
00933
00934 int minw, minh, maxw, maxh;
00935 int basew, baseh, winc, hinc;
00936
00937
00938
00939
00940
00941 x = window->size_hints.x;
00942 y = window->size_hints.y;
00943 w = window->size_hints.width;
00944 h = window->size_hints.height;
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958 if (hints)
00959 window->size_hints = *hints;
00960 else
00961 window->size_hints.flags = 0;
00962
00963
00964 window->size_hints.x = x;
00965 window->size_hints.y = y;
00966 window->size_hints.width = w;
00967 window->size_hints.height = h;
00968
00969
00970 if (window->size_hints.flags & PBaseSize)
00971 {
00972 meta_topic (META_DEBUG_GEOMETRY, "Window %s sets base size %d x %d\n",
00973 window->desc,
00974 window->size_hints.base_width,
00975 window->size_hints.base_height);
00976 }
00977 else if (window->size_hints.flags & PMinSize)
00978 {
00979 window->size_hints.base_width = window->size_hints.min_width;
00980 window->size_hints.base_height = window->size_hints.min_height;
00981 }
00982 else
00983 {
00984 window->size_hints.base_width = 0;
00985 window->size_hints.base_height = 0;
00986 }
00987 window->size_hints.flags |= PBaseSize;
00988
00989
00990 if (window->size_hints.flags & PMinSize)
00991 {
00992 meta_topic (META_DEBUG_GEOMETRY, "Window %s sets min size %d x %d\n",
00993 window->desc,
00994 window->size_hints.min_width,
00995 window->size_hints.min_height);
00996 }
00997 else if (window->size_hints.flags & PBaseSize)
00998 {
00999 window->size_hints.min_width = window->size_hints.base_width;
01000 window->size_hints.min_height = window->size_hints.base_height;
01001 }
01002 else
01003 {
01004 window->size_hints.min_width = 0;
01005 window->size_hints.min_height = 0;
01006 }
01007 window->size_hints.flags |= PMinSize;
01008
01009
01010 if (window->size_hints.flags & PMaxSize)
01011 {
01012 meta_topic (META_DEBUG_GEOMETRY, "Window %s sets max size %d x %d\n",
01013 window->desc,
01014 window->size_hints.max_width,
01015 window->size_hints.max_height);
01016 }
01017 else
01018 {
01019 window->size_hints.max_width = G_MAXINT;
01020 window->size_hints.max_height = G_MAXINT;
01021 window->size_hints.flags |= PMaxSize;
01022 }
01023
01024
01025 if (window->size_hints.flags & PResizeInc)
01026 {
01027 meta_topic (META_DEBUG_GEOMETRY,
01028 "Window %s sets resize width inc: %d height inc: %d\n",
01029 window->desc,
01030 window->size_hints.width_inc,
01031 window->size_hints.height_inc);
01032 }
01033 else
01034 {
01035 window->size_hints.width_inc = 1;
01036 window->size_hints.height_inc = 1;
01037 window->size_hints.flags |= PResizeInc;
01038 }
01039
01040
01041 if (window->size_hints.flags & PAspect)
01042 {
01043 meta_topic (META_DEBUG_GEOMETRY,
01044 "Window %s sets min_aspect: %d/%d max_aspect: %d/%d\n",
01045 window->desc,
01046 window->size_hints.min_aspect.x,
01047 window->size_hints.min_aspect.y,
01048 window->size_hints.max_aspect.x,
01049 window->size_hints.max_aspect.y);
01050 }
01051 else
01052 {
01053 window->size_hints.min_aspect.x = 1;
01054 window->size_hints.min_aspect.y = G_MAXINT;
01055 window->size_hints.max_aspect.x = G_MAXINT;
01056 window->size_hints.max_aspect.y = 1;
01057 window->size_hints.flags |= PAspect;
01058 }
01059
01060
01061 if (window->size_hints.flags & PWinGravity)
01062 {
01063 meta_topic (META_DEBUG_GEOMETRY, "Window %s sets gravity %d\n",
01064 window->desc,
01065 window->size_hints.win_gravity);
01066 }
01067 else
01068 {
01069 meta_topic (META_DEBUG_GEOMETRY,
01070 "Window %s doesn't set gravity, using NW\n",
01071 window->desc);
01072 window->size_hints.win_gravity = NorthWestGravity;
01073 window->size_hints.flags |= PWinGravity;
01074 }
01075
01076
01077
01078
01079 if (window->size_hints.min_width < 1)
01080 {
01081
01082 meta_topic (META_DEBUG_GEOMETRY,
01083 "Window %s sets min width to 0, which makes no sense\n",
01084 window->desc);
01085 window->size_hints.min_width = 1;
01086 }
01087 if (window->size_hints.max_width < 1)
01088 {
01089
01090 meta_topic (META_DEBUG_GEOMETRY,
01091 "Window %s sets max width to 0, which makes no sense\n",
01092 window->desc);
01093 window->size_hints.max_width = 1;
01094 }
01095 if (window->size_hints.min_height < 1)
01096 {
01097
01098 meta_topic (META_DEBUG_GEOMETRY,
01099 "Window %s sets min height to 0, which makes no sense\n",
01100 window->desc);
01101 window->size_hints.min_height = 1;
01102 }
01103 if (window->size_hints.max_height < 1)
01104 {
01105
01106 meta_topic (META_DEBUG_GEOMETRY,
01107 "Window %s sets max height to 0, which makes no sense\n",
01108 window->desc);
01109 window->size_hints.max_height = 1;
01110 }
01111
01112
01113 if (window->size_hints.width_inc < 1)
01114 {
01115
01116 window->size_hints.width_inc = 1;
01117 meta_topic (META_DEBUG_GEOMETRY, "Corrected 0 width_inc to 1\n");
01118 }
01119 if (window->size_hints.height_inc < 1)
01120 {
01121
01122 window->size_hints.height_inc = 1;
01123 meta_topic (META_DEBUG_GEOMETRY, "Corrected 0 height_inc to 1\n");
01124 }
01125
01126
01127
01128 if (window->size_hints.min_aspect.y < 1)
01129 window->size_hints.min_aspect.y = 1;
01130 if (window->size_hints.max_aspect.y < 1)
01131 window->size_hints.max_aspect.y = 1;
01132
01133 minw = window->size_hints.min_width; minh = window->size_hints.min_height;
01134 maxw = window->size_hints.max_width; maxh = window->size_hints.max_height;
01135 basew = window->size_hints.base_width; baseh = window->size_hints.base_height;
01136 winc = window->size_hints.width_inc; hinc = window->size_hints.height_inc;
01137
01138
01139
01140
01141
01142
01143 if ((minw - basew) % winc != 0)
01144 {
01145
01146 window->size_hints.min_width = basew + ((minw - basew)/winc + 1)*winc;
01147
01148 meta_topic (META_DEBUG_GEOMETRY,
01149 "Window %s has width_inc (%d) that does not evenly divide "
01150 "min_width - base_width (%d - %d); thus effective "
01151 "min_width is really %d\n",
01152 window->desc,
01153 winc, minw, basew, window->size_hints.min_width);
01154 minw = window->size_hints.min_width;
01155 }
01156 if (maxw != G_MAXINT && (maxw - basew) % winc != 0)
01157 {
01158
01159 window->size_hints.max_width = basew + ((maxw - basew)/winc)*winc;
01160
01161 meta_topic (META_DEBUG_GEOMETRY,
01162 "Window %s has width_inc (%d) that does not evenly divide "
01163 "max_width - base_width (%d - %d); thus effective "
01164 "max_width is really %d\n",
01165 window->desc,
01166 winc, maxw, basew, window->size_hints.max_width);
01167 maxw = window->size_hints.max_width;
01168 }
01169 if ((minh - baseh) % hinc != 0)
01170 {
01171
01172 window->size_hints.min_height = baseh + ((minh - baseh)/hinc + 1)*hinc;
01173
01174 meta_topic (META_DEBUG_GEOMETRY,
01175 "Window %s has height_inc (%d) that does not evenly divide "
01176 "min_height - base_height (%d - %d); thus effective "
01177 "min_height is really %d\n",
01178 window->desc,
01179 hinc, minh, baseh, window->size_hints.min_height);
01180 minh = window->size_hints.min_height;
01181 }
01182 if (maxh != G_MAXINT && (maxh - baseh) % hinc != 0)
01183 {
01184
01185 window->size_hints.max_height = baseh + ((maxh - baseh)/hinc)*hinc;
01186
01187 meta_topic (META_DEBUG_GEOMETRY,
01188 "Window %s has height_inc (%d) that does not evenly divide "
01189 "max_height - base_height (%d - %d); thus effective "
01190 "max_height is really %d\n",
01191 window->desc,
01192 hinc, maxh, baseh, window->size_hints.max_height);
01193 maxh = window->size_hints.max_height;
01194 }
01195
01196
01197
01198
01199 if (window->size_hints.max_width < window->size_hints.min_width)
01200 {
01201
01202 meta_topic (META_DEBUG_GEOMETRY,
01203 "Window %s sets max width %d less than min width %d, "
01204 "disabling resize\n",
01205 window->desc,
01206 window->size_hints.max_width,
01207 window->size_hints.min_width);
01208 maxw = window->size_hints.max_width = window->size_hints.min_width;
01209 }
01210 if (window->size_hints.max_height < window->size_hints.min_height)
01211 {
01212
01213 meta_topic (META_DEBUG_GEOMETRY,
01214 "Window %s sets max height %d less than min height %d, "
01215 "disabling resize\n",
01216 window->desc,
01217 window->size_hints.max_height,
01218 window->size_hints.min_height);
01219 maxh = window->size_hints.max_height = window->size_hints.min_height;
01220 }
01221
01222
01223 minr = window->size_hints.min_aspect.x /
01224 (double)window->size_hints.min_aspect.y;
01225 maxr = window->size_hints.max_aspect.x /
01226 (double)window->size_hints.max_aspect.y;
01227 if (minr > maxr)
01228 {
01229
01230 meta_topic (META_DEBUG_GEOMETRY,
01231 "Window %s sets min aspect ratio larger than max aspect "
01232 "ratio; disabling aspect ratio constraints.\n",
01233 window->desc);
01234 window->size_hints.min_aspect.x = 1;
01235 window->size_hints.min_aspect.y = G_MAXINT;
01236 window->size_hints.max_aspect.x = G_MAXINT;
01237 window->size_hints.max_aspect.y = 1;
01238 }
01239 else
01240 {
01241 if (minh > 0 && minr > (maxw / (double)minh))
01242 {
01243
01244 meta_topic (META_DEBUG_GEOMETRY,
01245 "Window %s sets min aspect ratio larger than largest "
01246 "aspect ratio possible given min/max size constraints; "
01247 "disabling min aspect ratio constraint.\n",
01248 window->desc);
01249 window->size_hints.min_aspect.x = 1;
01250 window->size_hints.min_aspect.y = G_MAXINT;
01251 }
01252 if (maxr < (minw / (double)maxh))
01253 {
01254
01255 meta_topic (META_DEBUG_GEOMETRY,
01256 "Window %s sets max aspect ratio smaller than smallest "
01257 "aspect ratio possible given min/max size constraints; "
01258 "disabling max aspect ratio constraint.\n",
01259 window->desc);
01260 window->size_hints.max_aspect.x = G_MAXINT;
01261 window->size_hints.max_aspect.y = 1;
01262 }
01263
01264
01265
01266 }
01267 }
01268
01269 static void
01270 reload_normal_hints (MetaWindow *window,
01271 MetaPropValue *value)
01272 {
01273 if (value->type != META_PROP_VALUE_INVALID)
01274 {
01275 XSizeHints old_hints;
01276
01277 meta_topic (META_DEBUG_GEOMETRY, "Updating WM_NORMAL_HINTS for %s\n", window->desc);
01278
01279 old_hints = window->size_hints;
01280
01281 meta_set_normal_hints (window, value->v.size_hints.hints);
01282
01283 spew_size_hints_differences (&old_hints, &window->size_hints);
01284
01285 meta_window_recalc_features (window);
01286 }
01287 }
01288
01289
01290 static void
01291 init_wm_protocols (MetaDisplay *display,
01292 Atom property,
01293 MetaPropValue *value)
01294 {
01295 value->type = META_PROP_VALUE_ATOM_LIST;
01296 value->atom = display->atom_WM_PROTOCOLS;
01297 }
01298
01299 static void
01300 reload_wm_protocols (MetaWindow *window,
01301 MetaPropValue *value)
01302 {
01303 int i;
01304
01305 window->take_focus = FALSE;
01306 window->delete_window = FALSE;
01307 window->net_wm_ping = FALSE;
01308
01309 if (value->type == META_PROP_VALUE_INVALID)
01310 return;
01311
01312 i = 0;
01313 while (i < value->v.atom_list.n_atoms)
01314 {
01315 if (value->v.atom_list.atoms[i] ==
01316 window->display->atom_WM_TAKE_FOCUS)
01317 window->take_focus = TRUE;
01318 else if (value->v.atom_list.atoms[i] ==
01319 window->display->atom_WM_DELETE_WINDOW)
01320 window->delete_window = TRUE;
01321 else if (value->v.atom_list.atoms[i] ==
01322 window->display->atom__NET_WM_PING)
01323 window->net_wm_ping = TRUE;
01324 ++i;
01325 }
01326
01327 meta_verbose ("New _NET_STARTUP_ID \"%s\" for %s\n",
01328 window->startup_id ? window->startup_id : "unset",
01329 window->desc);
01330 }
01331
01332 static void
01333 init_wm_hints (MetaDisplay *display,
01334 Atom property,
01335 MetaPropValue *value)
01336 {
01337 value->type = META_PROP_VALUE_WM_HINTS;
01338 value->atom = XA_WM_HINTS;
01339 }
01340
01341 static void
01342 reload_wm_hints (MetaWindow *window,
01343 MetaPropValue *value)
01344 {
01345 Window old_group_leader;
01346
01347 old_group_leader = window->xgroup_leader;
01348
01349
01350 window->input = TRUE;
01351 window->initially_iconic = FALSE;
01352 window->xgroup_leader = None;
01353 window->wm_hints_pixmap = None;
01354 window->wm_hints_mask = None;
01355
01356 if (value->type != META_PROP_VALUE_INVALID)
01357 {
01358 const XWMHints *hints = value->v.wm_hints;
01359
01360 if (hints->flags & InputHint)
01361 window->input = hints->input;
01362
01363 if (hints->flags & StateHint)
01364 window->initially_iconic = (hints->initial_state == IconicState);
01365
01366 if (hints->flags & WindowGroupHint)
01367 window->xgroup_leader = hints->window_group;
01368
01369 if (hints->flags & IconPixmapHint)
01370 window->wm_hints_pixmap = hints->icon_pixmap;
01371
01372 if (hints->flags & IconMaskHint)
01373 window->wm_hints_mask = hints->icon_mask;
01374
01375 meta_verbose ("Read WM_HINTS input: %d iconic: %d group leader: 0x%lx pixmap: 0x%lx mask: 0x%lx\n",
01376 window->input, window->initially_iconic,
01377 window->xgroup_leader,
01378 window->wm_hints_pixmap,
01379 window->wm_hints_mask);
01380 }
01381
01382 if (window->xgroup_leader != old_group_leader)
01383 {
01384 meta_verbose ("Window %s changed its group leader to 0x%lx\n",
01385 window->desc, window->xgroup_leader);
01386
01387 meta_window_group_leader_changed (window);
01388 }
01389
01390 meta_icon_cache_property_changed (&window->icon_cache,
01391 window->display,
01392 XA_WM_HINTS);
01393
01394 meta_window_queue (window, META_QUEUE_UPDATE_ICON | META_QUEUE_MOVE_RESIZE);
01395 }
01396
01397 static void
01398 init_transient_for (MetaDisplay *display,
01399 Atom property,
01400 MetaPropValue *value)
01401 {
01402 value->type = META_PROP_VALUE_WINDOW;
01403 value->atom = XA_WM_TRANSIENT_FOR;
01404 }
01405
01406 static void
01407 reload_transient_for (MetaWindow *window,
01408 MetaPropValue *value)
01409 {
01410 window->xtransient_for = None;
01411
01412 if (value->type != META_PROP_VALUE_INVALID)
01413 window->xtransient_for = value->v.xwindow;
01414
01415
01416 if (window->xtransient_for != None &&
01417 meta_display_lookup_x_window (window->display,
01418 window->xtransient_for) == NULL)
01419 {
01420 meta_warning (_("Invalid WM_TRANSIENT_FOR window 0x%lx specified "
01421 "for %s.\n"),
01422 window->xtransient_for, window->desc);
01423 window->xtransient_for = None;
01424 }
01425
01426 window->transient_parent_is_root_window =
01427 window->xtransient_for == window->screen->xroot;
01428
01429 if (window->xtransient_for != None)
01430 meta_verbose ("Window %s transient for 0x%lx (root = %d)\n", window->desc,
01431 window->xtransient_for, window->transient_parent_is_root_window);
01432 else
01433 meta_verbose ("Window %s is not transient\n", window->desc);
01434
01435
01436 meta_window_recalc_window_type (window);
01437
01438
01439 meta_stack_update_transient (window->screen->stack, window);
01440
01441
01442
01443
01444
01445 if (window->xtransient_for != None &&
01446 window->xgroup_leader != None &&
01447 window->xtransient_for != window->xgroup_leader)
01448 meta_window_group_leader_changed (window);
01449
01450 if (!window->constructing)
01451 meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
01452 }
01453
01454 #define N_HOOKS 26
01455
01456 void
01457 meta_display_init_window_prop_hooks (MetaDisplay *display)
01458 {
01459 int i;
01460 MetaWindowPropHooks *hooks;
01461
01462 g_assert (display->prop_hooks == NULL);
01463
01464 display->prop_hooks = g_new0 (MetaWindowPropHooks, N_HOOKS);
01465 hooks = display->prop_hooks;
01466
01467 i = 0;
01468
01469 hooks[i].property = display->atom_WM_STATE;
01470 hooks[i].init_func = NULL;
01471 hooks[i].reload_func = NULL;
01472 ++i;
01473
01474 hooks[i].property = display->atom_WM_CLIENT_MACHINE;
01475 hooks[i].init_func = init_wm_client_machine;
01476 hooks[i].reload_func = reload_wm_client_machine;
01477 ++i;
01478
01479 hooks[i].property = display->atom__NET_WM_PID;
01480 hooks[i].init_func = init_net_wm_pid;
01481 hooks[i].reload_func = reload_net_wm_pid;
01482 ++i;
01483
01484 hooks[i].property = display->atom__NET_WM_USER_TIME;
01485 hooks[i].init_func = init_net_wm_user_time;
01486 hooks[i].reload_func = reload_net_wm_user_time;
01487 ++i;
01488
01489 hooks[i].property = display->atom__NET_WM_NAME;
01490 hooks[i].init_func = init_net_wm_name;
01491 hooks[i].reload_func = reload_net_wm_name;
01492 ++i;
01493
01494 hooks[i].property = XA_WM_NAME;
01495 hooks[i].init_func = init_wm_name;
01496 hooks[i].reload_func = reload_wm_name;
01497 ++i;
01498
01499 hooks[i].property = display->atom__NET_WM_ICON_NAME;
01500 hooks[i].init_func = init_net_wm_icon_name;
01501 hooks[i].reload_func = reload_net_wm_icon_name;
01502 ++i;
01503
01504 hooks[i].property = XA_WM_ICON_NAME;
01505 hooks[i].init_func = init_wm_icon_name;
01506 hooks[i].reload_func = reload_wm_icon_name;
01507 ++i;
01508
01509 hooks[i].property = display->atom__NET_WM_STATE;
01510 hooks[i].init_func = init_net_wm_state;
01511 hooks[i].reload_func = reload_net_wm_state;
01512 ++i;
01513
01514 hooks[i].property = display->atom__MOTIF_WM_HINTS;
01515 hooks[i].init_func = init_mwm_hints;
01516 hooks[i].reload_func = reload_mwm_hints;
01517 ++i;
01518
01519 hooks[i].property = display->atom__NET_WM_ICON_GEOMETRY;
01520 hooks[i].init_func = NULL;
01521 hooks[i].reload_func = NULL;
01522 ++i;
01523
01524 hooks[i].property = XA_WM_CLASS;
01525 hooks[i].init_func = init_wm_class;
01526 hooks[i].reload_func = reload_wm_class;
01527 ++i;
01528
01529 hooks[i].property = display->atom_WM_CLIENT_LEADER;
01530 hooks[i].init_func = NULL;
01531 hooks[i].reload_func = NULL;
01532 ++i;
01533
01534 hooks[i].property = display->atom_SM_CLIENT_ID;
01535 hooks[i].init_func = NULL;
01536 hooks[i].reload_func = NULL;
01537 ++i;
01538
01539 hooks[i].property = display->atom_WM_WINDOW_ROLE;
01540 hooks[i].init_func = NULL;
01541 hooks[i].reload_func = NULL;
01542 ++i;
01543
01544 hooks[i].property = display->atom__NET_WM_WINDOW_TYPE;
01545 hooks[i].init_func = NULL;
01546 hooks[i].reload_func = NULL;
01547 ++i;
01548
01549 hooks[i].property = display->atom__NET_WM_DESKTOP;
01550 hooks[i].init_func = init_net_wm_desktop;
01551 hooks[i].reload_func = reload_net_wm_desktop;
01552 ++i;
01553
01554 hooks[i].property = display->atom__NET_WM_STRUT;
01555 hooks[i].init_func = NULL;
01556 hooks[i].reload_func = NULL;
01557 ++i;
01558
01559 hooks[i].property = display->atom__NET_WM_STRUT_PARTIAL;
01560 hooks[i].init_func = NULL;
01561 hooks[i].reload_func = NULL;
01562 ++i;
01563
01564 hooks[i].property = display->atom__NET_STARTUP_ID;
01565 hooks[i].init_func = init_net_startup_id;
01566 hooks[i].reload_func = reload_net_startup_id;
01567 ++i;
01568
01569 hooks[i].property = display->atom__NET_WM_SYNC_REQUEST_COUNTER;
01570 hooks[i].init_func = init_update_counter;
01571 hooks[i].reload_func = reload_update_counter;
01572 ++i;
01573
01574 hooks[i].property = XA_WM_NORMAL_HINTS;
01575 hooks[i].init_func = init_normal_hints;
01576 hooks[i].reload_func = reload_normal_hints;
01577 ++i;
01578
01579 hooks[i].property = display->atom_WM_PROTOCOLS;
01580 hooks[i].init_func = init_wm_protocols;
01581 hooks[i].reload_func = reload_wm_protocols;
01582 ++i;
01583
01584 hooks[i].property = XA_WM_HINTS;
01585 hooks[i].init_func = init_wm_hints;
01586 hooks[i].reload_func = reload_wm_hints;
01587 ++i;
01588
01589 hooks[i].property = XA_WM_TRANSIENT_FOR;
01590 hooks[i].init_func = init_transient_for;
01591 hooks[i].reload_func = reload_transient_for;
01592 ++i;
01593
01594 hooks[i].property = display->atom__NET_WM_USER_TIME_WINDOW;
01595 hooks[i].init_func = init_net_wm_user_time_window;
01596 hooks[i].reload_func = reload_net_wm_user_time_window;
01597 ++i;
01598
01599 if (i != N_HOOKS)
01600 {
01601 g_error ("Initialized %d hooks should have been %d\n", i, N_HOOKS);
01602 }
01603 }
01604
01605 void
01606 meta_display_free_window_prop_hooks (MetaDisplay *display)
01607 {
01608 g_assert (display->prop_hooks != NULL);
01609
01610 g_free (display->prop_hooks);
01611 display->prop_hooks = NULL;
01612 }
01613
01614 static MetaWindowPropHooks*
01615 find_hooks (MetaDisplay *display,
01616 Atom property)
01617 {
01618 int i;
01619
01620
01621
01622
01623
01624 i = 0;
01625 while (i < N_HOOKS)
01626 {
01627 if (display->prop_hooks[i].property == property)
01628 return &display->prop_hooks[i];
01629
01630 ++i;
01631 }
01632
01633 return NULL;
01634 }