[metacity] window: add meta_window_propagate_focus_appearance



commit d74cb9edff1fb9baef60967930554dc425f7f2bb
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Thu Mar 2 22:00:52 2017 +0200

    window: add meta_window_propagate_focus_appearance
    
    Based on mutter commit:
    https://git.gnome.org/browse/mutter/commit/?id=f464b85ffc1f55e3551a0227fd614ea39bc33036

 src/core/window-private.h |   10 ++++--
 src/core/window-props.c   |    6 ++++
 src/core/window.c         |   70 ++++++++++++++++++++++++++------------------
 3 files changed, 54 insertions(+), 32 deletions(-)
---
diff --git a/src/core/window-private.h b/src/core/window-private.h
index fc6fb5a..4510535 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -262,9 +262,7 @@ struct _MetaWindow
   /* EWHH demands attention flag */
   guint wm_state_demands_attention : 1;
 
-  /* this flag tracks receipt of focus_in focus_out and
-   * determines whether we draw the focus
-   */
+  /* this flag tracks receipt of focus_in focus_out */
   guint has_focus : 1;
 
   /* Have we placed this window? */
@@ -398,6 +396,9 @@ struct _MetaWindow
 
   /* maintained by group.c */
   MetaGroup *group;
+
+  /* Focused window that is (directly or indirectly) attached to this one */
+  MetaWindow *attached_focus_window;
 };
 
 /* These differ from window->has_foo_func in that they consider
@@ -687,4 +688,7 @@ void meta_window_get_titlebar_rect (MetaWindow    *window,
 void meta_window_configure_notify (MetaWindow      *window,
                                    XConfigureEvent *event);
 
+void meta_window_propagate_focus_appearance (MetaWindow *window,
+                                             gboolean    focused);
+
 #endif
diff --git a/src/core/window-props.c b/src/core/window-props.c
index 89836e9..fdeab31 100644
--- a/src/core/window-props.c
+++ b/src/core/window-props.c
@@ -1532,6 +1532,9 @@ reload_transient_for (MetaWindow    *window,
                       MetaPropValue *value,
                       gboolean       initial)
 {
+  if (window->has_focus && window->xtransient_for != None)
+    meta_window_propagate_focus_appearance (window, FALSE);
+
   window->xtransient_for = None;
 
   if (value->type != META_PROP_VALUE_INVALID)
@@ -1575,6 +1578,9 @@ 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)
+    meta_window_propagate_focus_appearance (window, TRUE);
 }
 
 static void
diff --git a/src/core/window.c b/src/core/window.c
index 185e9e3..6592412 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -446,6 +446,7 @@ meta_window_new (MetaDisplay *display,
 
   window->frame = NULL;
   window->has_focus = FALSE;
+  window->attached_focus_window = NULL;
 
   window->maximized_horizontally = FALSE;
   window->maximized_vertically = FALSE;
@@ -1031,6 +1032,7 @@ 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)
     {
@@ -5622,20 +5624,44 @@ meta_window_appears_focused_changed (MetaWindow *window)
     meta_frame_queue_draw (window->frame);
 }
 
-static void
-check_ancestor_focus_appearance (MetaWindow *window)
+void
+meta_window_propagate_focus_appearance (MetaWindow *window,
+                                        gboolean    focused)
 {
-  MetaWindow *parent = meta_window_get_transient_for (window);
+  MetaWindow *child, *parent;
 
   if (!meta_prefs_get_attach_modal_dialogs ())
     return;
 
-  if (window->type != META_WINDOW_MODAL_DIALOG || !parent || parent == window)
-    return;
+  child = window;
+  parent = meta_window_get_transient_for (child);
+  while (child->type == META_WINDOW_MODAL_DIALOG && parent)
+    {
+      gboolean child_focus_state_changed;
 
-  meta_window_appears_focused_changed (parent);
+      if (focused)
+        {
+          if (parent->attached_focus_window == window)
+            break;
+          child_focus_state_changed = (parent->attached_focus_window == NULL);
+          parent->attached_focus_window = window;
+        }
+      else
+        {
+          if (parent->attached_focus_window != window)
+            break;
+          child_focus_state_changed = (parent->attached_focus_window != NULL);
+          parent->attached_focus_window = NULL;
+        }
 
-  check_ancestor_focus_appearance (parent);
+      if (child_focus_state_changed && !parent->has_focus)
+        {
+          meta_window_appears_focused_changed (parent);
+        }
+
+      child = parent;
+      parent = meta_window_get_transient_for (child);
+    }
 }
 
 static void
@@ -5707,8 +5733,10 @@ meta_window_set_focused_internal (MetaWindow *window,
           !meta_prefs_get_raise_on_click())
         meta_display_ungrab_focus_window_button (window->display, window);
 
-      /* parent window become active. */
-      check_ancestor_focus_appearance (window);
+      if (!window->attached_focus_window)
+        meta_window_appears_focused_changed (window);
+
+      meta_window_propagate_focus_appearance (window, TRUE);
     }
   else
     {
@@ -5727,10 +5755,10 @@ meta_window_set_focused_internal (MetaWindow *window,
 
       meta_compositor_set_active_window (window->display->compositor, NULL);
 
-      /* parent window become active. */
-      check_ancestor_focus_appearance (window);
+      if (!window->attached_focus_window)
+        meta_window_appears_focused_changed (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);
@@ -8791,26 +8819,10 @@ meta_window_get_frame (MetaWindow *window)
   return window->frame;
 }
 
-static gboolean
-transient_has_focus (MetaWindow *window,
-                     void       *data)
-{
-  if (window->type == META_WINDOW_MODAL_DIALOG && meta_window_appears_focused (window))
-    *((gboolean *)data) = TRUE;
-
-  return FALSE;
-}
-
 gboolean
 meta_window_appears_focused (MetaWindow *window)
 {
-  if (!window->has_focus && meta_prefs_get_attach_modal_dialogs ())
-    {
-      gboolean focus = FALSE;
-      meta_window_foreach_transient (window, transient_has_focus, &focus);
-      return focus;
-    }
-  return window->has_focus;
+  return window->has_focus || (window->attached_focus_window != NULL);
 }
 
 gboolean


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]