diff options
author | Havoc Pennington <hp@pobox.com> | 2003-03-17 06:36:34 +0000 |
---|---|---|
committer | Havoc Pennington <hp@src.gnome.org> | 2003-03-17 06:36:34 +0000 |
commit | d745c86e14a80bba2914ecd6cd36bbd18d07318c (patch) | |
tree | 9e75a8772488bff483b1b985534171951238e8ab | |
parent | 6ef319f8eb9f1ecd5386a5ed0a6e50544da9ffee (diff) | |
download | metacity-d745c86e14a80bba2914ecd6cd36bbd18d07318c.tar.gz |
Should fix #108108, #106217, tracked down by Owen Taylor and Frederic
2003-03-11 Havoc Pennington <hp@pobox.com>
Should fix #108108, #106217, tracked down by Owen Taylor and
Frederic Crozat
* src/window.c (meta_window_foreach_transient): change
MetaWindowForeachFunc to return a boolean for whether to continue
(meta_window_foreach_ancestor): new function
(window_should_be_showing): use meta_window_foreach_ancestor
(unminimize_window_and_all_transient_parents): ditto
(update_sm_hints): ditto
(meta_window_is_ancestor_of_transient): ditto
* src/stack.c (get_maximum_layer_of_ancestor): use
meta_window_foreach_ancestor
-rw-r--r-- | ChangeLog | 16 | ||||
-rw-r--r-- | src/stack.c | 49 | ||||
-rw-r--r-- | src/window.c | 219 | ||||
-rw-r--r-- | src/window.h | 17 |
4 files changed, 191 insertions, 110 deletions
@@ -1,3 +1,19 @@ +2003-03-11 Havoc Pennington <hp@pobox.com> + + Should fix #108108, #106217, tracked down by Owen Taylor and + Frederic Crozat + + * src/window.c (meta_window_foreach_transient): change + MetaWindowForeachFunc to return a boolean for whether to continue + (meta_window_foreach_ancestor): new function + (window_should_be_showing): use meta_window_foreach_ancestor + (unminimize_window_and_all_transient_parents): ditto + (update_sm_hints): ditto + (meta_window_is_ancestor_of_transient): ditto + + * src/stack.c (get_maximum_layer_of_ancestor): use + meta_window_foreach_ancestor + 2003-03-13 Christian Rose <menthos@menthos.com> * configure.in: Added "ml" to ALL_LINGUAS. diff --git a/src/stack.c b/src/stack.c index 9aa4b9b0..03caf8c6 100644 --- a/src/stack.c +++ b/src/stack.c @@ -262,37 +262,34 @@ get_standalone_layer (MetaWindow *window) return layer; } -static MetaStackLayer -get_maximum_layer_of_ancestor (MetaWindow *window) +typedef struct { - MetaWindow *w; MetaStackLayer max; +} MaxLayerData; + +static gboolean +max_layer_func (MetaWindow *window, + void *data) +{ + MaxLayerData *d = data; MetaStackLayer layer; - max = get_standalone_layer (window); - - w = window; - while (w != NULL) - { - if (w->xtransient_for == None || - w->transient_parent_is_root_window) - break; - - w = meta_display_lookup_x_window (w->display, w->xtransient_for); - - if (w == window) - break; /* Cute, someone thought they'd make a transient_for cycle */ - - /* w may be null... */ - if (w != NULL) - { - layer = get_standalone_layer (w); - if (layer > max) - max = layer; - } - } + layer = get_standalone_layer (window); + if (layer > d->max) + d->max = layer; - return max; + return TRUE; +} + +static MetaStackLayer +get_maximum_layer_of_ancestor (MetaWindow *window) +{ + MaxLayerData d; + + d.max = get_standalone_layer (window); + meta_window_foreach_ancestor (window, max_layer_func, &d); + + return d.max; } /* Note that this function can never use window->layer only diff --git a/src/window.c b/src/window.c index 5a078de8..3a3ee4ef 100644 --- a/src/window.c +++ b/src/window.c @@ -1136,6 +1136,31 @@ meta_window_visible_on_workspace (MetaWindow *window, } static gboolean +is_minimized_foreach (MetaWindow *window, + void *data) +{ + gboolean *result = data; + + *result = window->minimized; + if (*result) + return FALSE; /* stop as soon as we find one */ + else + return TRUE; +} + +static gboolean +ancestor_is_minimized (MetaWindow *window) +{ + gboolean is_minimized; + + is_minimized = FALSE; + + meta_window_foreach_ancestor (window, is_minimized_foreach, &is_minimized); + + return is_minimized; +} + +static gboolean window_should_be_showing (MetaWindow *window) { gboolean showing, on_workspace; @@ -1184,28 +1209,8 @@ window_should_be_showing (MetaWindow *window) if (showing) { - MetaWindow *w; - - w = window; - while (w != NULL) - { - if (w->minimized) - { - showing = FALSE; - break; - } - - if (w->xtransient_for == None || - w->transient_parent_is_root_window) - break; - - w = meta_display_lookup_x_window (w->display, w->xtransient_for); - - if (w == window) - break; /* Cute, someone thought they'd make a transient_for cycle */ - - /* w may be null... */ - } + if (ancestor_is_minimized (window)) + showing = FALSE; } return showing; @@ -1712,11 +1717,12 @@ meta_window_hide (MetaWindow *window) } } -static void +static gboolean queue_calc_showing_func (MetaWindow *window, void *data) { meta_window_queue_calc_showing (window); + return TRUE; } void @@ -1953,27 +1959,19 @@ meta_window_unshade (MetaWindow *window) } } +static gboolean +unminimize_func (MetaWindow *window, + void *data) +{ + meta_window_unminimize (window); + return TRUE; +} + static void unminimize_window_and_all_transient_parents (MetaWindow *window) { - MetaWindow *w; - - w = window; - while (w != NULL) - { - meta_window_unminimize (w); - - if (w->xtransient_for == None || - w->transient_parent_is_root_window) - break; - - w = meta_display_lookup_x_window (w->display, w->xtransient_for); - - if (w == window) - break; /* Cute, someone thought they'd make a transient_for cycle */ - - /* w may be null... */ - } + meta_window_unminimize (window); + meta_window_foreach_ancestor (window, unminimize_func, NULL); } void @@ -3148,11 +3146,12 @@ meta_window_change_workspace_without_transients (MetaWindow *window, g_assert (window->workspaces->next == NULL); } -static void +static gboolean change_workspace_foreach (MetaWindow *window, void *data) { meta_window_change_workspace_without_transients (window, data); + return TRUE; } void @@ -4841,10 +4840,29 @@ read_client_leader (MetaDisplay *display, return retval; } +typedef struct +{ + Window leader; +} ClientLeaderData; + +static gboolean +find_client_leader_func (MetaWindow *ancestor, + void *data) +{ + ClientLeaderData *d; + + d = data; + + d->leader = read_client_leader (ancestor->display, + ancestor->xwindow); + + /* keep going if no client leader found */ + return d->leader == None; +} + static void update_sm_hints (MetaWindow *window) { - MetaWindow *w; Window leader; window->xclient_leader = None; @@ -4854,26 +4872,17 @@ update_sm_hints (MetaWindow *window) * leader from transient parents. If we find a client * leader, we read the SM_CLIENT_ID from it. */ - leader = None; - w = window; - while (w != NULL) + leader = read_client_leader (window->display, window->xwindow); + if (leader == None) { - leader = read_client_leader (window->display, w->xwindow); - - if (leader != None) - break; - - if (w->xtransient_for == None || - w->transient_parent_is_root_window) - break; - - w = meta_display_lookup_x_window (w->display, w->xtransient_for); - - if (w == window) - break; /* Cute, someone thought they'd make a transient_for cycle */ + ClientLeaderData d; + d.leader = None; + meta_window_foreach_ancestor (window, find_client_leader_func, + &d); + leader = d.leader; } - if (leader) + if (leader != None) { char *str; @@ -6748,7 +6757,10 @@ meta_window_foreach_transient (MetaWindow *window, MetaWindow *transient = tmp->data; if (meta_window_is_ancestor_of_transient (window, transient)) - (* func) (transient, data); + { + if (!(* func) (transient, data)) + break; + } tmp = tmp->next; } @@ -6756,34 +6768,87 @@ meta_window_foreach_transient (MetaWindow *window, g_slist_free (windows); } -gboolean -meta_window_is_ancestor_of_transient (MetaWindow *window, - MetaWindow *transient) +void +meta_window_foreach_ancestor (MetaWindow *window, + MetaWindowForeachFunc func, + void *data) { MetaWindow *w; - - if (window == transient) - return FALSE; + MetaWindow *tortoise; - w = transient; - while (w != NULL) - { + w = window; + tortoise = window; + while (TRUE) + { if (w->xtransient_for == None || w->transient_parent_is_root_window) - return FALSE; + break; + + w = meta_display_lookup_x_window (w->display, w->xtransient_for); + + if (w == NULL || w == tortoise) + break; - if (w->xtransient_for == window->xwindow) - return TRUE; + if (!(* func) (w, data)) + break; + if (w->xtransient_for == None || + w->transient_parent_is_root_window) + break; + w = meta_display_lookup_x_window (w->display, w->xtransient_for); - if (w == transient) - return FALSE; /* Cycle */ + if (w == NULL || w == tortoise) + break; + + if (!(* func) (w, data)) + break; - /* w may be null... */ + tortoise = meta_display_lookup_x_window (tortoise->display, + tortoise->xtransient_for); + + /* "w" should have already covered all ground covered by the + * tortoise, so the following must hold. + */ + g_assert (tortoise != NULL); + g_assert (tortoise->xtransient_for != None); + g_assert (!tortoise->transient_parent_is_root_window); } +} - return FALSE; +typedef struct +{ + MetaWindow *ancestor; + gboolean found; +} FindAncestorData; + +static gboolean +find_ancestor_func (MetaWindow *window, + void *data) +{ + FindAncestorData *d = data; + + if (window == d->ancestor) + { + d->found = TRUE; + return FALSE; + } + + return TRUE; +} + +gboolean +meta_window_is_ancestor_of_transient (MetaWindow *window, + MetaWindow *transient) +{ + FindAncestorData d; + + d.ancestor = window; + d.found = FALSE; + + meta_window_foreach_ancestor (transient, find_ancestor_func, &d); + + return d.found; } static gboolean diff --git a/src/window.h b/src/window.h index e8541f5c..da2d4fd3 100644 --- a/src/window.h +++ b/src/window.h @@ -33,8 +33,8 @@ typedef struct _MetaGroup MetaGroup; -typedef void (*MetaWindowForeachFunc) (MetaWindow *window, - void *data); +typedef gboolean (*MetaWindowForeachFunc) (MetaWindow *window, + void *data); typedef enum { @@ -432,11 +432,14 @@ void meta_window_refresh_resize_popup (MetaWindow *window); void meta_window_free_delete_dialog (MetaWindow *window); -void meta_window_foreach_transient (MetaWindow *window, - MetaWindowForeachFunc func, - void *data); -gboolean meta_window_is_ancestor_of_transient (MetaWindow *window, - MetaWindow *transient); +void meta_window_foreach_transient (MetaWindow *window, + MetaWindowForeachFunc func, + void *data); +gboolean meta_window_is_ancestor_of_transient (MetaWindow *window, + MetaWindow *transient); +void meta_window_foreach_ancestor (MetaWindow *window, + MetaWindowForeachFunc func, + void *data); gboolean meta_window_warp_pointer (MetaWindow *window, MetaGrabOp grab_op); |