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
This commit is contained in:
Havoc Pennington 2003-03-17 06:36:39 +00:00 committed by Havoc Pennington
parent 51e74d4027
commit d34e54785d
4 changed files with 197 additions and 116 deletions

View File

@ -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-16 Rob Adams <robadams@ucla.edu> 2003-03-16 Rob Adams <robadams@ucla.edu>
* window.c (meta_window_show_menu): Free old window menu if it * window.c (meta_window_show_menu): Free old window menu if it

View File

@ -262,37 +262,34 @@ get_standalone_layer (MetaWindow *window)
return layer; return layer;
} }
typedef struct
{
MetaStackLayer max;
} MaxLayerData;
static gboolean
max_layer_func (MetaWindow *window,
void *data)
{
MaxLayerData *d = data;
MetaStackLayer layer;
layer = get_standalone_layer (window);
if (layer > d->max)
d->max = layer;
return TRUE;
}
static MetaStackLayer static MetaStackLayer
get_maximum_layer_of_ancestor (MetaWindow *window) get_maximum_layer_of_ancestor (MetaWindow *window)
{ {
MetaWindow *w; MaxLayerData d;
MetaStackLayer max;
MetaStackLayer layer;
max = get_standalone_layer (window); d.max = get_standalone_layer (window);
meta_window_foreach_ancestor (window, max_layer_func, &d);
w = window; return d.max;
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;
}
}
return max;
} }
/* Note that this function can never use window->layer only /* Note that this function can never use window->layer only

View File

@ -1124,6 +1124,31 @@ meta_window_visible_on_workspace (MetaWindow *window,
meta_workspace_contains_window (workspace, window); meta_workspace_contains_window (workspace, 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 static gboolean
window_should_be_showing (MetaWindow *window) window_should_be_showing (MetaWindow *window)
{ {
@ -1173,28 +1198,8 @@ window_should_be_showing (MetaWindow *window)
if (showing) if (showing)
{ {
MetaWindow *w; if (ancestor_is_minimized (window))
showing = FALSE;
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... */
}
} }
return showing; return showing;
@ -1701,11 +1706,12 @@ meta_window_hide (MetaWindow *window)
} }
} }
static void static gboolean
queue_calc_showing_func (MetaWindow *window, queue_calc_showing_func (MetaWindow *window,
void *data) void *data)
{ {
meta_window_queue_calc_showing (window); meta_window_queue_calc_showing (window);
return TRUE;
} }
void void
@ -1942,27 +1948,19 @@ meta_window_unshade (MetaWindow *window)
} }
} }
static gboolean
unminimize_func (MetaWindow *window,
void *data)
{
meta_window_unminimize (window);
return TRUE;
}
static void static void
unminimize_window_and_all_transient_parents (MetaWindow *window) unminimize_window_and_all_transient_parents (MetaWindow *window)
{ {
MetaWindow *w; meta_window_unminimize (window);
meta_window_foreach_ancestor (window, unminimize_func, NULL);
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... */
}
} }
void void
@ -3141,11 +3139,12 @@ meta_window_change_workspace_without_transients (MetaWindow *window,
g_assert (window->workspaces->next == NULL); g_assert (window->workspaces->next == NULL);
} }
static void static gboolean
change_workspace_foreach (MetaWindow *window, change_workspace_foreach (MetaWindow *window,
void *data) void *data)
{ {
meta_window_change_workspace_without_transients (window, data); meta_window_change_workspace_without_transients (window, data);
return TRUE;
} }
void void
@ -4465,10 +4464,29 @@ read_client_leader (MetaDisplay *display,
return retval; 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 static void
update_sm_hints (MetaWindow *window) update_sm_hints (MetaWindow *window)
{ {
MetaWindow *w;
Window leader; Window leader;
window->xclient_leader = None; window->xclient_leader = None;
@ -4478,26 +4496,17 @@ update_sm_hints (MetaWindow *window)
* leader from transient parents. If we find a client * leader from transient parents. If we find a client
* leader, we read the SM_CLIENT_ID from it. * leader, we read the SM_CLIENT_ID from it.
*/ */
leader = None; leader = read_client_leader (window->display, window->xwindow);
w = window; if (leader == None)
while (w != NULL)
{ {
leader = read_client_leader (window->display, w->xwindow); ClientLeaderData d;
d.leader = None;
if (leader != None) meta_window_foreach_ancestor (window, find_client_leader_func,
break; &d);
leader = d.leader;
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 */
} }
if (leader) if (leader != None)
{ {
char *str; char *str;
@ -6237,7 +6246,10 @@ meta_window_foreach_transient (MetaWindow *window,
MetaWindow *transient = tmp->data; MetaWindow *transient = tmp->data;
if (meta_window_is_ancestor_of_transient (window, transient)) if (meta_window_is_ancestor_of_transient (window, transient))
(* func) (transient, data); {
if (!(* func) (transient, data))
break;
}
tmp = tmp->next; tmp = tmp->next;
} }
@ -6245,34 +6257,87 @@ meta_window_foreach_transient (MetaWindow *window,
g_slist_free (windows); g_slist_free (windows);
} }
void
meta_window_foreach_ancestor (MetaWindow *window,
MetaWindowForeachFunc func,
void *data)
{
MetaWindow *w;
MetaWindow *tortoise;
w = window;
tortoise = window;
while (TRUE)
{
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 == NULL || w == tortoise)
break;
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 == NULL || w == tortoise)
break;
if (!(* func) (w, data))
break;
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);
}
}
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 gboolean
meta_window_is_ancestor_of_transient (MetaWindow *window, meta_window_is_ancestor_of_transient (MetaWindow *window,
MetaWindow *transient) MetaWindow *transient)
{ {
MetaWindow *w; FindAncestorData d;
if (window == transient) d.ancestor = window;
return FALSE; d.found = FALSE;
w = transient; meta_window_foreach_ancestor (transient, find_ancestor_func, &d);
while (w != NULL)
{
if (w->xtransient_for == None ||
w->transient_parent_is_root_window)
return FALSE;
if (w->xtransient_for == window->xwindow) return d.found;
return TRUE;
w = meta_display_lookup_x_window (w->display, w->xtransient_for);
if (w == transient)
return FALSE; /* Cycle */
/* w may be null... */
}
return FALSE;
} }
static gboolean static gboolean

View File

@ -33,8 +33,8 @@
typedef struct _MetaGroup MetaGroup; typedef struct _MetaGroup MetaGroup;
typedef void (*MetaWindowForeachFunc) (MetaWindow *window, typedef gboolean (*MetaWindowForeachFunc) (MetaWindow *window,
void *data); void *data);
typedef enum typedef enum
{ {
@ -442,11 +442,14 @@ void meta_window_refresh_resize_popup (MetaWindow *window);
void meta_window_free_delete_dialog (MetaWindow *window); void meta_window_free_delete_dialog (MetaWindow *window);
void meta_window_foreach_transient (MetaWindow *window, void meta_window_foreach_transient (MetaWindow *window,
MetaWindowForeachFunc func, MetaWindowForeachFunc func,
void *data); void *data);
gboolean meta_window_is_ancestor_of_transient (MetaWindow *window, gboolean meta_window_is_ancestor_of_transient (MetaWindow *window,
MetaWindow *transient); MetaWindow *transient);
void meta_window_foreach_ancestor (MetaWindow *window,
MetaWindowForeachFunc func,
void *data);
gboolean meta_window_warp_pointer (MetaWindow *window, gboolean meta_window_warp_pointer (MetaWindow *window,
MetaGrabOp grab_op); MetaGrabOp grab_op);