[metacity] window: fix appears-focused propagation with attached grandchildren



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]