mirror of
https://github.com/brl/mutter.git
synced 2024-12-23 11:32:04 +00:00
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:
parent
6dc79ce60a
commit
48cabd1364
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user