[mutter/wip/culling: 8/8] window: Separate pointer-focus operations and explicit-focus operations



commit 5adc2bd5cedb4696f660a3ace09fec426326dd82
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Fri Nov 22 12:12:49 2013 -0500

    window: Separate pointer-focus operations and explicit-focus operations
    
    Some clients, like on-screen keyboards, don't want their windows to be
    activated on click, as that would steal focus from the window they're
    trying to send events to. They do this by setting the Input Hint in
    WM_HINTS to be FALSE, along with not specifying WM_TAKE_FOCUS in their
    WM_PROTOCOLS.
    
    However, in this case, when a window tries to get focus in this scenario,
    we focus the frame so that a11y and key navigation works properly.
    Both policies aren't acceptable -- we can't make OSK steal focus from
    windows on click, and we can't make an OSK un-Alt-Tabbable-to.
    
    To solve this, split meta_window_focus() into two different focus policies:
    
     * meta_window_focus_implicitly() should be called on pointer click or
       focus-follows-mouse or similar cases where we may not want to forcibly
       set focus for clients that don't want it.
    
     * meta_window_focus_explicitly() should be called by pagers, like
       the gnome-shell overview, or Alt-Tab. In this case, most of the existing
       clients are using meta_window_activate(), so simply adapting that so
       it calls meta_window_focus_explicitly() should be enough.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=715030

 src/core/core.c           |    4 +-
 src/core/display.c        |    2 +-
 src/core/keybindings.c    |    2 +-
 src/core/screen.c         |    2 +-
 src/core/window-private.h |    3 ++
 src/core/window.c         |   64 +++++++++++++++++++++++++++++++++++----------
 src/core/workspace.c      |    6 ++--
 src/meta/window.h         |    2 +-
 8 files changed, 62 insertions(+), 23 deletions(-)
---
diff --git a/src/core/core.c b/src/core/core.c
index 1808f4e..1bc8464 100644
--- a/src/core/core.c
+++ b/src/core/core.c
@@ -303,7 +303,7 @@ meta_core_user_focus (Display *xdisplay,
 {
   MetaWindow *window = get_window (xdisplay, frame_xwindow);
   
-  meta_window_focus (window, timestamp);
+  meta_window_focus_implicitly (window, timestamp);
 }
 
 void
@@ -482,7 +482,7 @@ meta_core_show_window_menu (Display *xdisplay,
   
   if (meta_prefs_get_raise_on_click ())
     meta_window_raise (window);
-  meta_window_focus (window, timestamp);
+  meta_window_focus_implicitly (window, timestamp);
 
   meta_window_show_menu (window, root_x, root_y, button, timestamp);
 }
diff --git a/src/core/display.c b/src/core/display.c
index db34bfb..7f2fa54 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -2244,7 +2244,7 @@ event_callback (XEvent   *event,
                           meta_topic (META_DEBUG_FOCUS,
                                       "Focusing %s due to unmodified button %u press (display.c)\n",
                                       window->desc, device_event->detail);
-                          meta_window_focus (window, device_event->time);
+                          meta_window_focus_implicitly (window, device_event->time);
                         }
                       else
                         /* However, do allow terminals to lose focus due to new
diff --git a/src/core/keybindings.c b/src/core/keybindings.c
index 35de8d5..bb91f56 100644
--- a/src/core/keybindings.c
+++ b/src/core/keybindings.c
@@ -1578,7 +1578,7 @@ meta_window_grab_all_keys (MetaWindow  *window,
   meta_topic (META_DEBUG_FOCUS,
               "Focusing %s because we're grabbing all its keys\n",
               window->desc);
-  meta_window_focus (window, timestamp);
+  meta_window_focus_implicitly (window, timestamp);
 
   grabwindow = window->frame ? window->frame->xwindow : window->xwindow;
 
diff --git a/src/core/screen.c b/src/core/screen.c
index fc0c3ae..ae334fe 100644
--- a/src/core/screen.c
+++ b/src/core/screen.c
@@ -2984,7 +2984,7 @@ meta_screen_show_desktop (MetaScreen *screen,
       if (w->screen == screen  && 
           w->type == META_WINDOW_DESKTOP)
         {
-          meta_window_focus (w, timestamp);
+          meta_window_focus_explicitly (w, timestamp);
           break;
         }
       
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 1fc4d59..abdc727 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -701,4 +701,7 @@ void meta_window_handle_enter (MetaWindow  *window,
                                guint        root_x,
                                guint        root_y);
 
+void meta_window_focus_implicitly (MetaWindow *window,
+                                   guint32     timestamp);
+
 #endif
diff --git a/src/core/window.c b/src/core/window.c
index ff27d0a..f197762 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -3183,7 +3183,7 @@ meta_window_show (MetaWindow *window)
 
           timestamp = meta_display_get_current_time_roundtrip (window->display);
 
-          meta_window_focus (window, timestamp);
+          meta_window_focus_explicitly (window, timestamp);
         }
       else
         {
@@ -4225,7 +4225,7 @@ meta_window_shade (MetaWindow  *window,
       meta_topic (META_DEBUG_FOCUS,
                   "Re-focusing window %s after shading it\n",
                   window->desc);
-      meta_window_focus (window, timestamp);
+      meta_window_focus_explicitly (window, timestamp);
 
       set_net_wm_state (window);
     }
@@ -4249,7 +4249,7 @@ meta_window_unshade (MetaWindow  *window,
       meta_topic (META_DEBUG_FOCUS,
                   "Focusing window %s after unshading it\n",
                   window->desc);
-      meta_window_focus (window, timestamp);
+      meta_window_focus_explicitly (window, timestamp);
 
       set_net_wm_state (window);
     }
@@ -4348,7 +4348,7 @@ window_activate (MetaWindow     *window,
   meta_topic (META_DEBUG_FOCUS,
               "Focusing window %s due to activation\n",
               window->desc);
-  meta_window_focus (window, timestamp);
+  meta_window_focus_explicitly (window, timestamp);
 
   meta_window_check_alive (window, timestamp);
 }
@@ -5972,17 +5972,18 @@ get_modal_transient (MetaWindow *window)
 }
 
 /* XXX META_EFFECT_FOCUS */
-void
-meta_window_focus (MetaWindow  *window,
-                   guint32      timestamp)
+static void
+meta_window_focus_internal (MetaWindow  *window,
+                            guint32      timestamp,
+                            gboolean     explicit_focus)
 {
   MetaWindow *modal_transient;
 
   g_return_if_fail (!window->override_redirect);
 
   meta_topic (META_DEBUG_FOCUS,
-              "Setting input focus to window %s, input: %d take_focus: %d\n",
-              window->desc, window->input, window->take_focus);
+              "%s setting input focus to window %s, input: %d take_focus: %d\n",
+              explicit_focus ? "Explicitly" : "Implicitly", window->desc, window->input, window->take_focus);
 
   if (window->display->grab_window &&
       window->display->grab_window->all_keys_grabbed)
@@ -6017,15 +6018,16 @@ meta_window_focus (MetaWindow  *window,
       return;
     }
 
-  /* For output-only or shaded windows, focus the frame.
-   * This seems to result in the client window getting key events
-   * though, so I don't know if it's icccm-compliant.
+  /* For output-only or shaded windows, focus the frame if it was
+   * an explicit focus event. This seems to result in the client
+   * window getting key events though, so I don't know if it's
+   * icccm-compliant.
    *
    * Still, we have to do this or keynav breaks for these windows.
    */
   if (window->frame &&
       (window->shaded ||
-       (!window->input && !window->take_focus)))
+       (explicit_focus && !window->input && !window->take_focus)))
     {
       if (window->frame)
         {
@@ -6068,6 +6070,40 @@ meta_window_focus (MetaWindow  *window,
 /*  meta_effect_run_focus(window, NULL, NULL); */
 }
 
+/**
+ * meta_window_focus_explicitly:
+ * @window: A #MetaWindow
+ * @timestamp: The timestamp to focus the window with
+ *
+ * Explicitly grab the window's focus. This should be used in cases
+ * where the user wants to focus the window with Alt-Tab, pagers,
+ * or other means like that, as opposed to simply clicking on the
+ * window or other focus-modes like focus-follows-mouse.
+ */
+void
+meta_window_focus_explicitly (MetaWindow *window,
+                              guint32     timestamp)
+{
+  meta_window_focus_internal (window, timestamp, TRUE);
+}
+
+/**
+ * meta_window_focus_implicitly:
+ * @window: A #MetaWindow
+ * @timestamp: The timestamp to focus the window with
+ *
+ * Implicitly focus the window. This should be done if the user
+ * simply clicks on the window. Most of the time, this should be
+ * handled by mutter internally, and you should never have to
+ * call this.
+ */
+void
+meta_window_focus_implicitly (MetaWindow *window,
+                              guint32     timestamp)
+{
+  meta_window_focus_internal (window, timestamp, FALSE);
+}
+
 static void
 meta_window_change_workspace_without_transients (MetaWindow    *window,
                                                  MetaWorkspace *workspace)
@@ -11467,7 +11503,7 @@ mouse_mode_focus (MetaWindow  *window,
       meta_topic (META_DEBUG_FOCUS,
                   "Focusing %s at time %u.\n", window->desc, timestamp);
 
-      meta_window_focus (window, timestamp);
+      meta_window_focus_implicitly (window, timestamp);
 
       if (meta_prefs_get_auto_raise ())
         meta_display_queue_autoraise_callback (display, window);
diff --git a/src/core/workspace.c b/src/core/workspace.c
index e5da6d2..4617dd4 100644
--- a/src/core/workspace.c
+++ b/src/core/workspace.c
@@ -1256,7 +1256,7 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace,
             {
               meta_topic (META_DEBUG_FOCUS,
                           "Focusing mouse window %s\n", window->desc);
-              meta_window_focus (window, timestamp);
+              meta_window_focus_explicitly (window, timestamp);
             }
 
           if (workspace->screen->display->autoraise_window != window &&
@@ -1319,7 +1319,7 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace,
                       "Focusing %s, ancestor of %s\n", 
                       ancestor->desc, not_this_one->desc);
       
-          meta_window_focus (ancestor, timestamp);
+          meta_window_focus_explicitly (ancestor, timestamp);
 
           /* Also raise the window if in click-to-focus */
           if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
@@ -1338,7 +1338,7 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace,
       meta_topic (META_DEBUG_FOCUS,
                   "Focusing workspace MRU window %s\n", window->desc);
       
-      meta_window_focus (window, timestamp);
+      meta_window_focus_explicitly (window, timestamp);
 
       /* Also raise the window if in click-to-focus */
       if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
diff --git a/src/meta/window.h b/src/meta/window.h
index 66cdfad..5bf92c3 100644
--- a/src/meta/window.h
+++ b/src/meta/window.h
@@ -227,7 +227,7 @@ void        meta_window_stick              (MetaWindow  *window);
 void        meta_window_unstick            (MetaWindow  *window);
 
 void        meta_window_kill               (MetaWindow  *window);
-void        meta_window_focus              (MetaWindow  *window,
+void        meta_window_focus_explicitly   (MetaWindow  *window,
                                             guint32      timestamp);
 
 void        meta_window_check_alive        (MetaWindow  *window,


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