diff options
author | Havoc Pennington <hp@pobox.com> | 2003-02-28 01:24:44 +0000 |
---|---|---|
committer | Havoc Pennington <hp@src.gnome.org> | 2003-02-28 01:24:44 +0000 |
commit | fa3de81741ece6b2c287edc88e75f7fb691048b1 (patch) | |
tree | c508d8eaafb200ce4bcfa04c7f5aeeebe26fc524 | |
parent | 6094763def1a3fda6553d349f55fd7080b696ead (diff) | |
download | metacity-fa3de81741ece6b2c287edc88e75f7fb691048b1.tar.gz |
add more debug spew about conditional build stuff (main): panic to
2003-02-27 Havoc Pennington <hp@pobox.com>
* src/main.c (main): add more debug spew about conditional
build stuff
(main): panic to "Simple" theme
* src/window.c, src/window-props.c: move WM_NORMAL_HINTS and
WM_PROTOCOLS to new property system; don't queue move resize on
updating WM_PROTOCOLS; move WM_HINTS to new property system;
reload icon in an idle handler.
Changes made on plane from FOSDEM, syncing from laptop.
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | rationales.txt | 2 | ||||
-rw-r--r-- | src/main.c | 19 | ||||
-rw-r--r-- | src/window-props.c | 393 | ||||
-rw-r--r-- | src/window.c | 514 | ||||
-rw-r--r-- | src/window.h | 14 |
6 files changed, 562 insertions, 393 deletions
@@ -1,3 +1,16 @@ +2003-02-27 Havoc Pennington <hp@pobox.com> + + * src/main.c (main): add more debug spew about conditional + build stuff + (main): panic to "Simple" theme + + * src/window.c, src/window-props.c: move WM_NORMAL_HINTS and + WM_PROTOCOLS to new property system; don't queue move resize on + updating WM_PROTOCOLS; move WM_HINTS to new property system; + reload icon in an idle handler. + + Changes made on plane from FOSDEM, syncing from laptop. + 2003-02-28 Mark McLoughlin <mark@skynet.ie> Give me back my keys. diff --git a/rationales.txt b/rationales.txt index f13b1dab..9f0de294 100644 --- a/rationales.txt +++ b/rationales.txt @@ -14,3 +14,5 @@ configure click actions, alt+click: http://bugzilla.gnome.org/show_bug.cgi?id=83210 system modal dialogs: http://bugzilla.gnome.org/show_bug.cgi?id=83357 + +workspace wrapping: http://bugzilla.gnome.org/show_bug.cgi?id=89315 @@ -271,6 +271,22 @@ main (int argc, char **argv) #else meta_topic (META_DEBUG_XINERAMA, " (not using Solaris Xinerama)\n"); #endif +#ifdef HAVE_XSYNC + meta_verbose ("Compiled with sync extension\n"); +#else + meta_verbose ("Compiled without sync extension\n"); +#endif +#ifdef HAVE_RANDR + meta_verbose ("Compiled with randr extension\n"); +#else + meta_verbose ("Compiled without randr extension\n"); +#endif +#ifdef HAVE_STARTUP_NOTIFICATION + meta_verbose ("Compiled with startup notification\n"); +#else + meta_verbose ("Compiled without startup notification\n"); +#endif + /* Load prefs */ meta_prefs_init (); @@ -317,6 +333,9 @@ main (int argc, char **argv) * don't want users to lose their WM :-/ */ if (!meta_ui_have_a_theme ()) + meta_ui_set_current_theme ("Simple", FALSE); + + if (!meta_ui_have_a_theme ()) meta_ui_set_current_theme ("Atlanta", FALSE); if (!meta_ui_have_a_theme ()) diff --git a/src/window-props.c b/src/window-props.c index c4b62552..1e334be1 100644 --- a/src/window-props.c +++ b/src/window-props.c @@ -1,7 +1,7 @@ /* MetaWindow property handling */ /* - * Copyright (C) 2001, 2002 Red Hat, Inc. + * Copyright (C) 2001, 2002, 2003 Red Hat, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -23,6 +23,7 @@ #include "window-props.h" #include "xprops.h" #include "frame.h" +#include "group.h" #include <X11/Xatom.h> typedef void (* InitValueFunc) (MetaDisplay *display, @@ -437,7 +438,370 @@ reload_update_counter (MetaWindow *window, } } -#define N_HOOKS 24 + +static void +init_normal_hints (MetaDisplay *display, + Atom property, + MetaPropValue *value) +{ + value->type = META_PROP_VALUE_SIZE_HINTS; + value->atom = XA_WM_NORMAL_HINTS; +} + + +#define FLAG_TOGGLED_ON(old,new,flag) \ + (((old)->flags & (flag)) == 0 && \ + ((new)->flags & (flag)) != 0) + +#define FLAG_TOGGLED_OFF(old,new,flag) \ + (((old)->flags & (flag)) != 0 && \ + ((new)->flags & (flag)) == 0) + +#define FLAG_CHANGED(old,new,flag) \ + (FLAG_TOGGLED_ON(old,new,flag) || FLAG_TOGGLED_OFF(old,new,flag)) + +static void +spew_size_hints_differences (const XSizeHints *old, + const XSizeHints *new) +{ + if (FLAG_CHANGED (old, new, USPosition)) + meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: USPosition now %s\n", + FLAG_TOGGLED_ON (old, new, USPosition) ? "set" : "unset"); + if (FLAG_CHANGED (old, new, USSize)) + meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: USSize now %s\n", + FLAG_TOGGLED_ON (old, new, USSize) ? "set" : "unset"); + if (FLAG_CHANGED (old, new, PPosition)) + meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PPosition now %s\n", + FLAG_TOGGLED_ON (old, new, PPosition) ? "set" : "unset"); + if (FLAG_CHANGED (old, new, PSize)) + meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PSize now %s\n", + FLAG_TOGGLED_ON (old, new, PSize) ? "set" : "unset"); + if (FLAG_CHANGED (old, new, PMinSize)) + meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PMinSize now %s (%d x %d -> %d x %d)\n", + FLAG_TOGGLED_ON (old, new, PMinSize) ? "set" : "unset", + old->min_width, old->min_height, + new->min_width, new->min_height); + if (FLAG_CHANGED (old, new, PMaxSize)) + meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PMaxSize now %s (%d x %d -> %d x %d)\n", + FLAG_TOGGLED_ON (old, new, PMaxSize) ? "set" : "unset", + old->max_width, old->max_height, + new->max_width, new->max_height); + if (FLAG_CHANGED (old, new, PResizeInc)) + meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PResizeInc now %s (width_inc %d -> %d height_inc %d -> %d)\n", + FLAG_TOGGLED_ON (old, new, PResizeInc) ? "set" : "unset", + old->width_inc, new->width_inc, + old->height_inc, new->height_inc); + if (FLAG_CHANGED (old, new, PAspect)) + meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PAspect now %s (min %d/%d -> %d/%d max %d/%d -> %d/%d)\n", + FLAG_TOGGLED_ON (old, new, PAspect) ? "set" : "unset", + old->min_aspect.x, old->min_aspect.y, + new->min_aspect.x, new->min_aspect.y, + old->max_aspect.x, old->max_aspect.y, + new->max_aspect.x, new->max_aspect.y); + if (FLAG_CHANGED (old, new, PBaseSize)) + meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PBaseSize now %s (%d x %d -> %d x %d)\n", + FLAG_TOGGLED_ON (old, new, PBaseSize) ? "set" : "unset", + old->base_width, old->base_height, + new->base_width, new->base_height); + if (FLAG_CHANGED (old, new, PWinGravity)) + meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PWinGravity now %s (%d -> %d)\n", + FLAG_TOGGLED_ON (old, new, PWinGravity) ? "set" : "unset", + old->win_gravity, new->win_gravity); +} + +static void +reload_normal_hints (MetaWindow *window, + MetaPropValue *value) +{ + if (value->type != META_PROP_VALUE_INVALID) + { + int x, y, w, h; + XSizeHints old_hints; + + meta_topic (META_DEBUG_GEOMETRY, "Updating WM_NORMAL_HINTS for %s\n", window->desc); + + old_hints = window->size_hints; + + /* Save the last ConfigureRequest, which we put here. + * Values here set in the hints are supposed to + * be ignored. + */ + x = window->size_hints.x; + y = window->size_hints.y; + w = window->size_hints.width; + h = window->size_hints.height; + + /* as far as I can tell, value->v.size_hints.flags is just to + * check whether we had old-style normal hints without gravity, + * base size as returned by XGetNormalHints(), so we don't + * really use it as we fixup window->size_hints to have those + * fields if they're missing. + */ + + window->size_hints.flags = 0; /* pointless right? why did I have this here */ + window->size_hints = * value->v.size_hints.hints; + + /* Put back saved ConfigureRequest. */ + window->size_hints.x = x; + window->size_hints.y = y; + window->size_hints.width = w; + window->size_hints.height = h; + + if (window->size_hints.flags & PBaseSize) + { + meta_topic (META_DEBUG_GEOMETRY, "Window %s sets base size %d x %d\n", + window->desc, + window->size_hints.base_width, + window->size_hints.base_height); + } + else if (window->size_hints.flags & PMinSize) + { + window->size_hints.base_width = window->size_hints.min_width; + window->size_hints.base_height = window->size_hints.min_height; + } + else + { + window->size_hints.base_width = 0; + window->size_hints.base_height = 0; + } + window->size_hints.flags |= PBaseSize; + + if (window->size_hints.flags & PMinSize) + { + meta_topic (META_DEBUG_GEOMETRY, "Window %s sets min size %d x %d\n", + window->desc, + window->size_hints.min_width, + window->size_hints.min_height); + } + else if (window->size_hints.flags & PBaseSize) + { + window->size_hints.min_width = window->size_hints.base_width; + window->size_hints.min_height = window->size_hints.base_height; + } + else + { + window->size_hints.min_width = 0; + window->size_hints.min_height = 0; + } + window->size_hints.flags |= PMinSize; + + if (window->size_hints.flags & PMaxSize) + { + meta_topic (META_DEBUG_GEOMETRY, "Window %s sets max size %d x %d\n", + window->desc, + window->size_hints.max_width, + window->size_hints.max_height); + } + else + { + window->size_hints.max_width = G_MAXINT; + window->size_hints.max_height = G_MAXINT; + window->size_hints.flags |= PMaxSize; + } + + if (window->size_hints.max_width < window->size_hints.min_width) + { + /* someone is on crack */ + meta_topic (META_DEBUG_GEOMETRY, + "Window %s sets max width %d less than min width %d, disabling resize\n", + window->desc, + window->size_hints.max_width, + window->size_hints.min_width); + window->size_hints.max_width = window->size_hints.min_width; + } + + if (window->size_hints.max_height < window->size_hints.min_height) + { + /* another cracksmoker */ + meta_topic (META_DEBUG_GEOMETRY, + "Window %s sets max height %d less than min height %d, disabling resize\n", + window->desc, + window->size_hints.max_height, + window->size_hints.min_height); + window->size_hints.max_height = window->size_hints.min_height; + } + + if (window->size_hints.flags & PResizeInc) + { + meta_topic (META_DEBUG_GEOMETRY, "Window %s sets resize width inc: %d height inc: %d\n", + window->desc, + window->size_hints.width_inc, + window->size_hints.height_inc); + if (window->size_hints.width_inc == 0) + { + window->size_hints.width_inc = 1; + meta_topic (META_DEBUG_GEOMETRY, "Corrected 0 width_inc to 1\n"); + } + if (window->size_hints.height_inc == 0) + { + window->size_hints.height_inc = 1; + meta_topic (META_DEBUG_GEOMETRY, "Corrected 0 height_inc to 1\n"); + } + } + else + { + window->size_hints.width_inc = 1; + window->size_hints.height_inc = 1; + window->size_hints.flags |= PResizeInc; + } + + if (window->size_hints.flags & PAspect) + { + meta_topic (META_DEBUG_GEOMETRY, "Window %s sets min_aspect: %d/%d max_aspect: %d/%d\n", + window->desc, + window->size_hints.min_aspect.x, + window->size_hints.min_aspect.y, + window->size_hints.max_aspect.x, + window->size_hints.max_aspect.y); + + /* don't divide by 0 */ + if (window->size_hints.min_aspect.y < 1) + window->size_hints.min_aspect.y = 1; + if (window->size_hints.max_aspect.y < 1) + window->size_hints.max_aspect.y = 1; + } + else + { + window->size_hints.min_aspect.x = 1; + window->size_hints.min_aspect.y = G_MAXINT; + window->size_hints.max_aspect.x = G_MAXINT; + window->size_hints.max_aspect.y = 1; + window->size_hints.flags |= PAspect; + } + + if (window->size_hints.flags & PWinGravity) + { + meta_topic (META_DEBUG_GEOMETRY, "Window %s sets gravity %d\n", + window->desc, + window->size_hints.win_gravity); + } + else + { + meta_topic (META_DEBUG_GEOMETRY, "Window %s doesn't set gravity, using NW\n", + window->desc); + window->size_hints.win_gravity = NorthWestGravity; + window->size_hints.flags |= PWinGravity; + } + + spew_size_hints_differences (&old_hints, &window->size_hints); + + meta_window_recalc_features (window); + } +} + + +static void +init_wm_protocols (MetaDisplay *display, + Atom property, + MetaPropValue *value) +{ + value->type = META_PROP_VALUE_ATOM_LIST; + value->atom = display->atom_wm_protocols; +} + +static void +reload_wm_protocols (MetaWindow *window, + MetaPropValue *value) +{ + int i; + + window->take_focus = FALSE; + window->delete_window = FALSE; + window->net_wm_ping = FALSE; + + if (value->type == META_PROP_VALUE_INVALID) + return; + + i = 0; + while (i < value->v.atom_list.n_atoms) + { + if (value->v.atom_list.atoms[i] == + window->display->atom_wm_take_focus) + window->take_focus = TRUE; + else if (value->v.atom_list.atoms[i] == + window->display->atom_wm_delete_window) + window->delete_window = TRUE; + else if (value->v.atom_list.atoms[i] == + window->display->atom_net_wm_ping) + window->net_wm_ping = TRUE; + ++i; + } + + meta_verbose ("New _NET_STARTUP_ID \"%s\" for %s\n", + window->startup_id ? window->startup_id : "unset", + window->desc); +} + +static void +init_wm_hints (MetaDisplay *display, + Atom property, + MetaPropValue *value) +{ + value->type = META_PROP_VALUE_WM_HINTS; + value->atom = XA_WM_HINTS; +} + +static void +reload_wm_hints (MetaWindow *window, + MetaPropValue *value) +{ + Window old_group_leader; + + old_group_leader = window->xgroup_leader; + + /* Fill in defaults */ + window->input = TRUE; + window->initially_iconic = FALSE; + window->xgroup_leader = None; + window->wm_hints_pixmap = None; + window->wm_hints_mask = None; + + if (value->type != META_PROP_VALUE_INVALID) + { + const XWMHints *hints = value->v.wm_hints; + + if (hints->flags & InputHint) + window->input = hints->input; + + if (hints->flags & StateHint) + window->initially_iconic = (hints->initial_state == IconicState); + + if (hints->flags & WindowGroupHint) + window->xgroup_leader = hints->window_group; + + if (hints->flags & IconPixmapHint) + window->wm_hints_pixmap = hints->icon_pixmap; + + if (hints->flags & IconMaskHint) + window->wm_hints_mask = hints->icon_mask; + + meta_verbose ("Read WM_HINTS input: %d iconic: %d group leader: 0x%lx pixmap: 0x%lx mask: 0x%lx\n", + window->input, window->initially_iconic, + window->xgroup_leader, + window->wm_hints_pixmap, + window->wm_hints_mask); + } + + if (window->xgroup_leader != old_group_leader) + { + meta_verbose ("Window %s changed its group leader to 0x%lx\n", + window->desc, window->xgroup_leader); + + meta_window_group_leader_changed (window); + } + + meta_icon_cache_property_changed (&window->icon_cache, + window->display, + XA_WM_HINTS); + + meta_window_queue_update_icon (window); + + meta_window_queue_move_resize (window); +} + + + +#define N_HOOKS 25 void meta_display_init_window_prop_hooks (MetaDisplay *display) @@ -467,11 +831,6 @@ meta_display_init_window_prop_hooks (MetaDisplay *display) hooks[i].reload_func = reload_net_wm_pid; ++i; - hooks[i].property = XA_WM_NORMAL_HINTS; - hooks[i].init_func = NULL; - hooks[i].reload_func = NULL; - ++i; - hooks[i].property = display->atom_net_wm_name; hooks[i].init_func = init_net_wm_name; hooks[i].reload_func = reload_net_wm_name; @@ -491,11 +850,6 @@ meta_display_init_window_prop_hooks (MetaDisplay *display) hooks[i].init_func = init_wm_icon_name; hooks[i].reload_func = reload_wm_icon_name; ++i; - - hooks[i].property = XA_WM_HINTS; - hooks[i].init_func = NULL; - hooks[i].reload_func = NULL; - ++i; hooks[i].property = display->atom_net_wm_state; hooks[i].init_func = NULL; @@ -571,6 +925,21 @@ meta_display_init_window_prop_hooks (MetaDisplay *display) hooks[i].init_func = init_update_counter; hooks[i].reload_func = reload_update_counter; ++i; + + hooks[i].property = XA_WM_NORMAL_HINTS; + hooks[i].init_func = init_normal_hints; + hooks[i].reload_func = reload_normal_hints; + ++i; + + hooks[i].property = display->atom_wm_protocols; + hooks[i].init_func = init_wm_protocols; + hooks[i].reload_func = reload_wm_protocols; + ++i; + + hooks[i].property = XA_WM_HINTS; + hooks[i].init_func = init_wm_hints; + hooks[i].reload_func = reload_wm_hints; + ++i; if (i != N_HOOKS) g_error ("Initialized %d hooks should have been %d\n", i, N_HOOKS); diff --git a/src/window.c b/src/window.c index 62c48c18..2c3bc862 100644 --- a/src/window.c +++ b/src/window.c @@ -78,9 +78,6 @@ static void constrain_position (MetaWindow *window, int *new_x, int *new_y); -static void update_size_hints (MetaWindow *window); -static void update_protocols (MetaWindow *window); -static void update_wm_hints (MetaWindow *window); static void update_net_wm_state (MetaWindow *window); static void update_mwm_hints (MetaWindow *window); static void update_wm_class (MetaWindow *window); @@ -88,13 +85,11 @@ static void update_transient_for (MetaWindow *window); static void update_sm_hints (MetaWindow *window); static void update_role (MetaWindow *window); static void update_net_wm_type (MetaWindow *window); -static void update_icon (MetaWindow *window); -static void redraw_icon (MetaWindow *window); static void update_struts (MetaWindow *window); static void recalc_window_type (MetaWindow *window); static void recalc_window_features (MetaWindow *window); static void recalc_do_not_cover_struts(MetaWindow *window); -static void invalidate_work_areas (MetaWindow *window); +static void invalidate_work_areas (MetaWindow *window); static void set_wm_state (MetaWindow *window, int state); static void set_net_wm_state (MetaWindow *window); @@ -127,12 +122,18 @@ static void meta_window_move_resize_internal (MetaWindow *window, void meta_window_move_resize_now (MetaWindow *window); +/* FIXME we need an abstraction that covers all these queues. */ + void meta_window_unqueue_calc_showing (MetaWindow *window); void meta_window_flush_calc_showing (MetaWindow *window); void meta_window_unqueue_move_resize (MetaWindow *window); void meta_window_flush_move_resize (MetaWindow *window); +static void meta_window_update_icon_now (MetaWindow *window); +void meta_window_unqueue_update_icon (MetaWindow *window); +void meta_window_flush_update_icon (MetaWindow *window); + static void meta_window_apply_session_info (MetaWindow *window, const MetaWindowSessionInfo *info); @@ -165,7 +166,7 @@ meta_window_new (MetaDisplay *display, MetaWorkspace *space; gulong existing_wm_state; gulong event_mask; -#define N_INITIAL_PROPS 10 +#define N_INITIAL_PROPS 13 Atom initial_props[N_INITIAL_PROPS]; int i; gboolean has_shape; @@ -465,6 +466,8 @@ meta_window_new (MetaDisplay *display, window->using_net_wm_name = FALSE; window->using_net_wm_icon_name = FALSE; + + window->need_reread_icon = TRUE; window->layer = META_LAYER_LAST; /* invalid value */ window->stack_position = -1; @@ -486,13 +489,13 @@ meta_window_new (MetaDisplay *display, initial_props[i++] = display->atom_win_workspace; initial_props[i++] = display->atom_net_startup_id; initial_props[i++] = display->atom_metacity_update_counter; + initial_props[i++] = XA_WM_NORMAL_HINTS; + initial_props[i++] = display->atom_wm_protocols; + initial_props[i++] = XA_WM_HINTS; g_assert (N_INITIAL_PROPS == i); meta_window_reload_properties (window, initial_props, N_INITIAL_PROPS); - update_size_hints (window); - update_protocols (window); - update_wm_hints (window); update_struts (window); update_net_wm_state (window); @@ -503,7 +506,7 @@ meta_window_new (MetaDisplay *display, update_sm_hints (window); /* must come after transient_for */ update_role (window); update_net_wm_type (window); - update_icon (window); + meta_window_update_icon_now (window); if (window->initially_iconic) { @@ -930,6 +933,7 @@ meta_window_free (MetaWindow *window) meta_window_unqueue_calc_showing (window); meta_window_unqueue_move_resize (window); + meta_window_unqueue_update_icon (window); meta_window_free_delete_dialog (window); tmp = window->workspaces; @@ -4071,7 +4075,7 @@ process_property_notify (MetaWindow *window, { meta_verbose ("Property notify on %s for WM_NORMAL_HINTS\n", window->desc); - update_size_hints (window); + meta_window_reload_property (window, XA_WM_NORMAL_HINTS); /* See if we need to constrain current size */ meta_window_queue_move_resize (window); @@ -4080,23 +4084,13 @@ process_property_notify (MetaWindow *window, { meta_verbose ("Property notify on %s for WM_PROTOCOLS\n", window->desc); - update_protocols (window); - - meta_window_queue_move_resize (window); + meta_window_reload_property (window, window->display->atom_wm_protocols); } else if (event->atom == XA_WM_HINTS) { meta_verbose ("Property notify on %s for WM_HINTS\n", window->desc); - meta_icon_cache_property_changed (&window->icon_cache, - window->display, - event->atom); - - update_wm_hints (window); - update_icon (window); - redraw_icon (window); - - meta_window_queue_move_resize (window); + meta_window_reload_property (window, XA_WM_HINTS); } else if (event->atom == window->display->atom_motif_wm_hints) { @@ -4155,8 +4149,7 @@ process_property_notify (MetaWindow *window, meta_icon_cache_property_changed (&window->icon_cache, window->display, event->atom); - update_icon (window); - redraw_icon (window); + meta_window_queue_update_icon (window); } else if (event->atom == window->display->atom_kwm_win_icon) { @@ -4165,8 +4158,7 @@ process_property_notify (MetaWindow *window, meta_icon_cache_property_changed (&window->icon_cache, window->display, event->atom); - update_icon (window); - redraw_icon (window); + meta_window_queue_update_icon (window); } else if (event->atom == window->display->atom_net_wm_strut) { @@ -4234,353 +4226,6 @@ send_configure_notify (MetaWindow *window) meta_error_trap_pop (window->display, FALSE); } -#define FLAG_TOGGLED_ON(old,new,flag) \ - (((old)->flags & (flag)) == 0 && \ - ((new)->flags & (flag)) != 0) - -#define FLAG_TOGGLED_OFF(old,new,flag) \ - (((old)->flags & (flag)) != 0 && \ - ((new)->flags & (flag)) == 0) - -#define FLAG_CHANGED(old,new,flag) \ - (FLAG_TOGGLED_ON(old,new,flag) || FLAG_TOGGLED_OFF(old,new,flag)) - -static void -spew_size_hints_differences (const XSizeHints *old, - const XSizeHints *new) -{ - if (FLAG_CHANGED (old, new, USPosition)) - meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: USPosition now %s\n", - FLAG_TOGGLED_ON (old, new, USPosition) ? "set" : "unset"); - if (FLAG_CHANGED (old, new, USSize)) - meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: USSize now %s\n", - FLAG_TOGGLED_ON (old, new, USSize) ? "set" : "unset"); - if (FLAG_CHANGED (old, new, PPosition)) - meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PPosition now %s\n", - FLAG_TOGGLED_ON (old, new, PPosition) ? "set" : "unset"); - if (FLAG_CHANGED (old, new, PSize)) - meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PSize now %s\n", - FLAG_TOGGLED_ON (old, new, PSize) ? "set" : "unset"); - if (FLAG_CHANGED (old, new, PMinSize)) - meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PMinSize now %s (%d x %d -> %d x %d)\n", - FLAG_TOGGLED_ON (old, new, PMinSize) ? "set" : "unset", - old->min_width, old->min_height, - new->min_width, new->min_height); - if (FLAG_CHANGED (old, new, PMaxSize)) - meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PMaxSize now %s (%d x %d -> %d x %d)\n", - FLAG_TOGGLED_ON (old, new, PMaxSize) ? "set" : "unset", - old->max_width, old->max_height, - new->max_width, new->max_height); - if (FLAG_CHANGED (old, new, PResizeInc)) - meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PResizeInc now %s (width_inc %d -> %d height_inc %d -> %d)\n", - FLAG_TOGGLED_ON (old, new, PResizeInc) ? "set" : "unset", - old->width_inc, new->width_inc, - old->height_inc, new->height_inc); - if (FLAG_CHANGED (old, new, PAspect)) - meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PAspect now %s (min %d/%d -> %d/%d max %d/%d -> %d/%d)\n", - FLAG_TOGGLED_ON (old, new, PAspect) ? "set" : "unset", - old->min_aspect.x, old->min_aspect.y, - new->min_aspect.x, new->min_aspect.y, - old->max_aspect.x, old->max_aspect.y, - new->max_aspect.x, new->max_aspect.y); - if (FLAG_CHANGED (old, new, PBaseSize)) - meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PBaseSize now %s (%d x %d -> %d x %d)\n", - FLAG_TOGGLED_ON (old, new, PBaseSize) ? "set" : "unset", - old->base_width, old->base_height, - new->base_width, new->base_height); - if (FLAG_CHANGED (old, new, PWinGravity)) - meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PWinGravity now %s (%d -> %d)\n", - FLAG_TOGGLED_ON (old, new, PWinGravity) ? "set" : "unset", - old->win_gravity, new->win_gravity); -} - -static void -update_size_hints (MetaWindow *window) -{ - int x, y, w, h; - gulong supplied; - XSizeHints old_hints; - XSizeHints *new_hints; - - meta_topic (META_DEBUG_GEOMETRY, "Updating WM_NORMAL_HINTS for %s\n", window->desc); - - old_hints = window->size_hints; - - /* Save the last ConfigureRequest, which we put here. - * Values here set in the hints are supposed to - * be ignored. - */ - x = window->size_hints.x; - y = window->size_hints.y; - w = window->size_hints.width; - h = window->size_hints.height; - - window->size_hints.flags = 0; - supplied = 0; - new_hints = NULL; - - meta_prop_get_size_hints (window->display, - window->xwindow, - XA_WM_NORMAL_HINTS, - &new_hints, - &supplied); - - /* as far as I can tell, "supplied" is just to check whether we had - * old-style normal hints without gravity, base size as returned by - * XGetNormalHints(), so we don't really use it as we fixup - * window->size_hints to have those fields if they're missing. - */ - - if (new_hints != NULL) - { - window->size_hints = *new_hints; - XFree (new_hints); - new_hints = NULL; - } - - /* Put back saved ConfigureRequest. */ - window->size_hints.x = x; - window->size_hints.y = y; - window->size_hints.width = w; - window->size_hints.height = h; - - if (window->size_hints.flags & PBaseSize) - { - meta_topic (META_DEBUG_GEOMETRY, "Window %s sets base size %d x %d\n", - window->desc, - window->size_hints.base_width, - window->size_hints.base_height); - } - else if (window->size_hints.flags & PMinSize) - { - window->size_hints.base_width = window->size_hints.min_width; - window->size_hints.base_height = window->size_hints.min_height; - } - else - { - window->size_hints.base_width = 0; - window->size_hints.base_height = 0; - } - window->size_hints.flags |= PBaseSize; - - if (window->size_hints.flags & PMinSize) - { - meta_topic (META_DEBUG_GEOMETRY, "Window %s sets min size %d x %d\n", - window->desc, - window->size_hints.min_width, - window->size_hints.min_height); - } - else if (window->size_hints.flags & PBaseSize) - { - window->size_hints.min_width = window->size_hints.base_width; - window->size_hints.min_height = window->size_hints.base_height; - } - else - { - window->size_hints.min_width = 0; - window->size_hints.min_height = 0; - } - window->size_hints.flags |= PMinSize; - - if (window->size_hints.flags & PMaxSize) - { - meta_topic (META_DEBUG_GEOMETRY, "Window %s sets max size %d x %d\n", - window->desc, - window->size_hints.max_width, - window->size_hints.max_height); - } - else - { - window->size_hints.max_width = G_MAXINT; - window->size_hints.max_height = G_MAXINT; - window->size_hints.flags |= PMaxSize; - } - - if (window->size_hints.max_width < window->size_hints.min_width) - { - /* someone is on crack */ - meta_topic (META_DEBUG_GEOMETRY, - "Window %s sets max width %d less than min width %d, disabling resize\n", - window->desc, - window->size_hints.max_width, - window->size_hints.min_width); - window->size_hints.max_width = window->size_hints.min_width; - } - - if (window->size_hints.max_height < window->size_hints.min_height) - { - /* another cracksmoker */ - meta_topic (META_DEBUG_GEOMETRY, - "Window %s sets max height %d less than min height %d, disabling resize\n", - window->desc, - window->size_hints.max_height, - window->size_hints.min_height); - window->size_hints.max_height = window->size_hints.min_height; - } - - if (window->size_hints.flags & PResizeInc) - { - meta_topic (META_DEBUG_GEOMETRY, "Window %s sets resize width inc: %d height inc: %d\n", - window->desc, - window->size_hints.width_inc, - window->size_hints.height_inc); - if (window->size_hints.width_inc == 0) - { - window->size_hints.width_inc = 1; - meta_topic (META_DEBUG_GEOMETRY, "Corrected 0 width_inc to 1\n"); - } - if (window->size_hints.height_inc == 0) - { - window->size_hints.height_inc = 1; - meta_topic (META_DEBUG_GEOMETRY, "Corrected 0 height_inc to 1\n"); - } - } - else - { - window->size_hints.width_inc = 1; - window->size_hints.height_inc = 1; - window->size_hints.flags |= PResizeInc; - } - - if (window->size_hints.flags & PAspect) - { - meta_topic (META_DEBUG_GEOMETRY, "Window %s sets min_aspect: %d/%d max_aspect: %d/%d\n", - window->desc, - window->size_hints.min_aspect.x, - window->size_hints.min_aspect.y, - window->size_hints.max_aspect.x, - window->size_hints.max_aspect.y); - - /* don't divide by 0 */ - if (window->size_hints.min_aspect.y < 1) - window->size_hints.min_aspect.y = 1; - if (window->size_hints.max_aspect.y < 1) - window->size_hints.max_aspect.y = 1; - } - else - { - window->size_hints.min_aspect.x = 1; - window->size_hints.min_aspect.y = G_MAXINT; - window->size_hints.max_aspect.x = G_MAXINT; - window->size_hints.max_aspect.y = 1; - window->size_hints.flags |= PAspect; - } - - if (window->size_hints.flags & PWinGravity) - { - meta_topic (META_DEBUG_GEOMETRY, "Window %s sets gravity %d\n", - window->desc, - window->size_hints.win_gravity); - } - else - { - meta_topic (META_DEBUG_GEOMETRY, "Window %s doesn't set gravity, using NW\n", - window->desc); - window->size_hints.win_gravity = NorthWestGravity; - window->size_hints.flags |= PWinGravity; - } - - recalc_window_features (window); - - spew_size_hints_differences (&old_hints, &window->size_hints); -} - -static void -update_protocols (MetaWindow *window) -{ - Atom *protocols = NULL; - int n_protocols = 0; - int i; - - window->take_focus = FALSE; - window->delete_window = FALSE; - window->net_wm_ping = FALSE; - - meta_error_trap_push (window->display); - - if (XGetWMProtocols (window->display->xdisplay, - window->xwindow, - &protocols, - &n_protocols)) - { - i = 0; - while (i < n_protocols) - { - if (protocols[i] == window->display->atom_wm_take_focus) - window->take_focus = TRUE; - else if (protocols[i] == window->display->atom_wm_delete_window) - window->delete_window = TRUE; - else if (protocols[i] == window->display->atom_net_wm_ping) - window->net_wm_ping = TRUE; - ++i; - } - - meta_XFree (protocols); - } - - meta_verbose ("Window %s has take_focus = %d delete_window = %d net_wm_ping = %d\n", - window->desc, window->take_focus, window->delete_window, - window->net_wm_ping); - - meta_error_trap_pop (window->display, TRUE); -} - -static void -update_wm_hints (MetaWindow *window) -{ - XWMHints *hints; - Window old_group_leader; - - old_group_leader = window->xgroup_leader; - - /* Fill in defaults */ - window->input = TRUE; - window->initially_iconic = FALSE; - window->xgroup_leader = None; - window->wm_hints_pixmap = None; - window->wm_hints_mask = None; - - hints = NULL; - meta_prop_get_wm_hints (window->display, - window->xwindow, - XA_WM_HINTS, - &hints); - - if (hints) - { - if (hints->flags & InputHint) - window->input = hints->input; - - if (hints->flags & StateHint) - window->initially_iconic = (hints->initial_state == IconicState); - - if (hints->flags & WindowGroupHint) - window->xgroup_leader = hints->window_group; - - if (hints->flags & IconPixmapHint) - window->wm_hints_pixmap = hints->icon_pixmap; - - if (hints->flags & IconMaskHint) - window->wm_hints_mask = hints->icon_mask; - - meta_verbose ("Read WM_HINTS input: %d iconic: %d group leader: 0x%lx pixmap: 0x%lx mask: 0x%lx\n", - window->input, window->initially_iconic, - window->xgroup_leader, - window->wm_hints_pixmap, - window->wm_hints_mask); - - meta_XFree (hints); - } - - if (window->xgroup_leader != old_group_leader) - { - meta_verbose ("Window %s changed its group leader to 0x%lx\n", - window->desc, window->xgroup_leader); - - meta_window_group_leader_changed (window); - } -} - static void update_net_wm_state (MetaWindow *window) { @@ -5067,7 +4712,17 @@ update_net_wm_type (MetaWindow *window) } static void -update_icon (MetaWindow *window) +redraw_icon (MetaWindow *window) +{ + /* We could probably be smart and just redraw the icon here, + * instead of the whole frame. + */ + if (window->frame && window->mapped) + meta_ui_queue_frame_draw (window->screen->ui, window->frame->xwindow); +} + +static void +meta_window_update_icon_now (MetaWindow *window) { GdkPixbuf *icon; GdkPixbuf *mini_icon; @@ -5094,18 +4749,109 @@ update_icon (MetaWindow *window) window->icon = icon; window->mini_icon = mini_icon; + + redraw_icon (window); } g_assert (window->icon); g_assert (window->mini_icon); } -static void -redraw_icon (MetaWindow *window) +static guint update_icon_idle = 0; +static GSList *update_icon_pending = NULL; + +static gboolean +idle_update_icon (gpointer data) { - /* We could probably be smart and just redraw the icon here. */ - if (window->frame) - meta_ui_queue_frame_draw (window->screen->ui, window->frame->xwindow); + GSList *tmp; + GSList *copy; + + meta_topic (META_DEBUG_GEOMETRY, "Clearing the update_icon queue\n"); + + /* Work with a copy, for reentrancy. The allowed reentrancy isn't + * complete; destroying a window while we're in here would result in + * badness. But it's OK to queue/unqueue update_icons. + */ + copy = g_slist_copy (update_icon_pending); + g_slist_free (update_icon_pending); + update_icon_pending = NULL; + update_icon_idle = 0; + + destroying_windows_disallowed += 1; + + tmp = copy; + while (tmp != NULL) + { + MetaWindow *window; + + window = tmp->data; + + /* As a side effect, sets window->update_icon_queued = FALSE */ + meta_window_update_icon_now (window); + + tmp = tmp->next; + } + + g_slist_free (copy); + + destroying_windows_disallowed -= 1; + + return FALSE; +} + +void +meta_window_unqueue_update_icon (MetaWindow *window) +{ + if (!window->update_icon_queued) + return; + + meta_topic (META_DEBUG_GEOMETRY, + "Removing %s from the update_icon queue\n", + window->desc); + + /* Note that window may not actually be in update_icon_pending + * because it may have been in "copy" inside the idle handler + */ + update_icon_pending = g_slist_remove (update_icon_pending, window); + window->update_icon_queued = FALSE; + + if (update_icon_pending == NULL && + update_icon_idle != 0) + { + g_source_remove (update_icon_idle); + update_icon_idle = 0; + } +} + +void +meta_window_flush_update_icon (MetaWindow *window) +{ + if (window->update_icon_queued) + { + meta_window_unqueue_update_icon (window); + meta_window_update_icon_now (window); + } +} + +void +meta_window_queue_update_icon (MetaWindow *window) +{ + if (window->unmanaging) + return; + + if (window->update_icon_queued) + return; + + meta_topic (META_DEBUG_GEOMETRY, + "Putting %s in the update_icon queue\n", + window->desc); + + window->update_icon_queued = TRUE; + + if (update_icon_idle == 0) + update_icon_idle = g_idle_add (idle_update_icon, NULL); + + update_icon_pending = g_slist_prepend (update_icon_pending, window); } static GList* @@ -5433,6 +5179,12 @@ set_allowed_actions_hint (MetaWindow *window) #undef MAX_N_ACTIONS } +void +meta_window_recalc_features (MetaWindow *window) +{ + recalc_window_features (window); +} + static void recalc_window_features (MetaWindow *window) { diff --git a/src/window.h b/src/window.h index 9eb94a7a..59ae9986 100644 --- a/src/window.h +++ b/src/window.h @@ -191,6 +191,9 @@ struct _MetaWindow /* Are we in the move_resize queue? */ guint move_resize_queued : 1; + + /* Are we in the update_icon queue? */ + guint update_icon_queued : 1; /* Used by keybindings.c */ guint keys_grabbed : 1; /* normal keybindings grabbed */ @@ -221,6 +224,9 @@ struct _MetaWindow /* has a shape mask */ guint has_shape : 1; + + /* icon props have changed */ + guint need_reread_icon : 1; #ifdef HAVE_XSYNC /* XSync update counter */ @@ -457,4 +463,12 @@ gboolean meta_window_get_icon_geometry (MetaWindow *window, const char* meta_window_get_startup_id (MetaWindow *window); +void meta_window_recalc_features (MetaWindow *window); + +void meta_window_queue_update_icon (MetaWindow *window); + #endif + + + + |