window: fix appears-focused propagation with attached grandchildren

When detaching/attaching a dialog, we were only updating
appears-focused on the parent if the child itself was focused, but in
fact, we need to do it if the child has an attached child which is
focused too.

To simplify the case of detaching a focused subtree from its parent,
we change meta_window_propagate_focus_appearance() to use
@window->display->focus_window as the window to add/remove as the
attached_focus_window, and @window only as the starting point to
propagate from. That way we can propagate focus-removal up to
@window's (soon-to-be-ex-)ancestors without having to remove it from
its descendants as well.

https://bugzilla.gnome.org/show_bug.cgi?id=647712
This commit is contained in:
Dan Winship 2011-04-13 17:08:12 -04:00
parent 6dc79ce60a
commit 48cabd1364
2 changed files with 25 additions and 8 deletions

View File

@ -1470,7 +1470,7 @@ reload_transient_for (MetaWindow *window,
{
MetaWindow *parent = NULL;
if (window->has_focus && window->xtransient_for != None)
if (meta_window_appears_focused (window) && window->xtransient_for != None)
meta_window_propagate_focus_appearance (window, FALSE);
window->xtransient_for = None;
@ -1536,7 +1536,7 @@ reload_transient_for (MetaWindow *window,
if (!window->constructing && !window->override_redirect)
meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
if (window->has_focus && window->xtransient_for != None)
if (meta_window_appears_focused (window) && window->xtransient_for != None)
meta_window_propagate_focus_appearance (window, TRUE);
}

View File

@ -1520,6 +1520,8 @@ meta_window_unmanage (MetaWindow *window,
* on what gets focused, maintaining sloppy focus
* invariants.
*/
if (meta_window_appears_focused (window))
meta_window_propagate_focus_appearance (window, FALSE);
if (window->has_focus)
{
meta_topic (META_DEBUG_FOCUS,
@ -1528,7 +1530,6 @@ meta_window_unmanage (MetaWindow *window,
meta_workspace_focus_default_window (window->screen->active_workspace,
window,
timestamp);
meta_window_propagate_focus_appearance (window, FALSE);
}
else if (window->display->expected_focus_window == window)
{
@ -6415,15 +6416,30 @@ meta_window_client_message (MetaWindow *window,
return FALSE;
}
/**
* meta_window_propagate_focus_appearance:
* @window: the window to start propagating from
* @focused: %TRUE if @window's ancestors should appear focused,
* %FALSE if they should not.
*
* Adjusts the value of #MetaWindow:appears-focused on @window's
* ancestors (but not @window itself). If @focused is %TRUE, each of
* @window's ancestors will have its %attached_focus_window field set
* to the current %focus_window. If @focused if %FALSE, each of
* @window's ancestors will have its %attached_focus_window field
* cleared if it is currently %focus_window.
*/
void
meta_window_propagate_focus_appearance (MetaWindow *window,
gboolean focused)
{
MetaWindow *child, *parent;
MetaWindow *child, *parent, *focus_window;
if (!meta_prefs_get_attach_modal_dialogs ())
return;
focus_window = window->display->focus_window;
child = window;
parent = meta_window_get_transient_for (child);
while (parent && (!focused || child->type == META_WINDOW_MODAL_DIALOG))
@ -6432,14 +6448,14 @@ meta_window_propagate_focus_appearance (MetaWindow *window,
if (focused)
{
if (parent->attached_focus_window == window)
if (parent->attached_focus_window == focus_window)
break;
child_focus_state_changed = (parent->attached_focus_window == NULL);
parent->attached_focus_window = window;
parent->attached_focus_window = focus_window;
}
else
{
if (parent->attached_focus_window != window)
if (parent->attached_focus_window != focus_window)
break;
child_focus_state_changed = (parent->attached_focus_window != NULL);
parent->attached_focus_window = NULL;
@ -6634,6 +6650,8 @@ meta_window_notify_focus (MetaWindow *window,
meta_topic (META_DEBUG_FOCUS,
"* Focus --> NULL (was %s)\n", window->desc);
meta_window_propagate_focus_appearance (window, FALSE);
window->display->focus_window = NULL;
g_object_notify (G_OBJECT (window->display), "focus-window");
window->has_focus = FALSE;
@ -6644,7 +6662,6 @@ meta_window_notify_focus (MetaWindow *window,
if (window->frame)
meta_frame_queue_draw (window->frame);
}
meta_window_propagate_focus_appearance (window, FALSE);
meta_error_trap_push (window->display);
XUninstallColormap (window->display->xdisplay,