summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHavoc Pennington <hp@pobox.com>2003-03-17 06:36:34 +0000
committerHavoc Pennington <hp@src.gnome.org>2003-03-17 06:36:34 +0000
commitd745c86e14a80bba2914ecd6cd36bbd18d07318c (patch)
tree9e75a8772488bff483b1b985534171951238e8ab
parent6ef319f8eb9f1ecd5386a5ed0a6e50544da9ffee (diff)
downloadmetacity-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--ChangeLog16
-rw-r--r--src/stack.c49
-rw-r--r--src/window.c219
-rw-r--r--src/window.h17
4 files changed, 191 insertions, 110 deletions
diff --git a/ChangeLog b/ChangeLog
index fdf24e00..db27fb9f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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);