[metacity] window: fix appears-focused propagation with attached grandchildren
- From: Alberts Muktupāvels <muktupavels src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [metacity] window: fix appears-focused propagation with attached grandchildren
- Date: Thu, 2 Mar 2017 22:15:59 +0000 (UTC)
commit f2417e841e91e04172fc516992a015b125690cc3
Author: Dan Winship <danw gnome org>
Date: Wed Apr 13 17:08:12 2011 -0400
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
src/core/window-props.c | 4 ++--
src/core/window.c | 30 +++++++++++++++++++++++-------
2 files changed, 25 insertions(+), 9 deletions(-)
---
diff --git a/src/core/window-props.c b/src/core/window-props.c
index fdeab31..6360d17 100644
--- a/src/core/window-props.c
+++ b/src/core/window-props.c
@@ -1532,7 +1532,7 @@ reload_transient_for (MetaWindow *window,
MetaPropValue *value,
gboolean initial)
{
- 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;
@@ -1579,7 +1579,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);
}
diff --git a/src/core/window.c b/src/core/window.c
index 06de75d..196585a 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -1024,6 +1024,8 @@ meta_window_free (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,
@@ -1032,7 +1034,6 @@ meta_window_free (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)
{
@@ -5624,15 +5625,30 @@ meta_window_appears_focused_changed (MetaWindow *window)
meta_frame_queue_draw (window->frame);
}
+/**
+ * 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))
@@ -5641,14 +5657,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;
@@ -5751,6 +5767,8 @@ meta_window_set_focused_internal (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;
window->has_focus = FALSE;
@@ -5759,8 +5777,6 @@ meta_window_set_focused_internal (MetaWindow *window,
if (!window->attached_focus_window)
meta_window_appears_focused_changed (window);
- meta_window_propagate_focus_appearance (window, FALSE);
-
meta_error_trap_push (window->display);
XUninstallColormap (window->display->xdisplay, window->colormap);
meta_error_trap_pop (window->display);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]