[mutter] keybindings: Trigger locate-pointer on key modifier



commit 851b7d0639fbff491f8c48836752fb344ca18a11
Author: Olivier Fourdan <ofourdan redhat com>
Date:   Wed Feb 20 11:53:54 2019 +0100

    keybindings: Trigger locate-pointer on key modifier
    
    We trigger the "locate-pointer" mechanism when a special key modifier
    (defaults to Control_L) key is pressed and released.
    
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/453
    https://gitlab.gnome.org/GNOME/gnome-shell/issues/981
    https://gitlab.gnome.org/GNOME/gsettings-desktop-schemas/merge_requests/19
    https://gitlab.gnome.org/GNOME/gnome-settings-daemon/merge_requests/86

 data/org.gnome.mutter.gschema.xml.in |   8 +++
 src/core/keybindings-private.h       |   4 ++
 src/core/keybindings.c               | 104 +++++++++++++++++++++++++++--------
 src/core/prefs.c                     |  54 ++++++++++++++++++
 src/meta/prefs.h                     |   2 +
 5 files changed, 149 insertions(+), 23 deletions(-)
---
diff --git a/data/org.gnome.mutter.gschema.xml.in b/data/org.gnome.mutter.gschema.xml.in
index 7bea9d66a..e0a784a01 100644
--- a/data/org.gnome.mutter.gschema.xml.in
+++ b/data/org.gnome.mutter.gschema.xml.in
@@ -127,6 +127,14 @@
       </description>
     </key>
 
+    <key name="locate-pointer-key" type="s">
+      <default>'Control_L'</default>
+      <summary>Modifier to use to locate the pointer</summary>
+      <description>
+        This key will initiate the “locate pointer” action.
+      </description>
+    </key>
+
     <child name="keybindings" schema="org.gnome.mutter.keybindings"/>
 
   </schema>
diff --git a/src/core/keybindings-private.h b/src/core/keybindings-private.h
index d686e6caf..fd1c14212 100644
--- a/src/core/keybindings-private.h
+++ b/src/core/keybindings-private.h
@@ -113,6 +113,9 @@ typedef struct
   MetaKeyCombo overlay_key_combo;
   MetaResolvedKeyCombo overlay_resolved_key_combo;
   gboolean overlay_key_only_pressed;
+  MetaKeyCombo locate_pointer_key_combo;
+  MetaResolvedKeyCombo locate_pointer_resolved_key_combo;
+  gboolean locate_pointer_key_only_pressed;
   MetaResolvedKeyCombo iso_next_group_combo[2];
   int n_iso_next_group_combos;
 
@@ -149,6 +152,7 @@ gboolean meta_prefs_remove_keybinding       (const char    *name);
 
 GList *meta_prefs_get_keybindings (void);
 void meta_prefs_get_overlay_binding (MetaKeyCombo *combo);
+void meta_prefs_get_locate_pointer_binding (MetaKeyCombo *combo);
 const char *meta_prefs_get_iso_next_group_option (void);
 
 void meta_x11_display_grab_keys   (MetaX11Display *x11_display);
diff --git a/src/core/keybindings.c b/src/core/keybindings.c
index a99899f80..8e73ce921 100644
--- a/src/core/keybindings.c
+++ b/src/core/keybindings.c
@@ -33,6 +33,7 @@
 #include "backends/meta-logical-monitor.h"
 #include "backends/meta-monitor-manager-private.h"
 #include "backends/x11/meta-backend-x11.h"
+#include "compositor/compositor-private.h"
 #include "core/edge-resistance.h"
 #include "core/frame.h"
 #include "core/keybindings-private.h"
@@ -780,6 +781,10 @@ reload_combos (MetaKeyBindingManager *keys)
                      &keys->overlay_key_combo,
                      &keys->overlay_resolved_key_combo);
 
+  resolve_key_combo (keys,
+                     &keys->locate_pointer_key_combo,
+                     &keys->locate_pointer_resolved_key_combo);
+
   reload_iso_next_group_combos (keys);
 
   g_hash_table_foreach (keys->key_bindings, binding_reload_combos_foreach, keys);
@@ -871,6 +876,9 @@ rebuild_special_bindings (MetaKeyBindingManager *keys)
 
   meta_prefs_get_overlay_binding (&combo);
   keys->overlay_key_combo = combo;
+
+  meta_prefs_get_locate_pointer_binding (&combo);
+  keys->locate_pointer_key_combo = combo;
 }
 
 static void
@@ -1062,6 +1070,10 @@ get_keybinding_action (MetaKeyBindingManager *keys,
                                     &keys->overlay_resolved_key_combo))
     return META_KEYBINDING_ACTION_OVERLAY_KEY;
 
+  if (resolved_key_combo_intersect (resolved_combo,
+                                    &keys->locate_pointer_resolved_key_combo))
+    return META_KEYBINDING_ACTION_LOCATE_POINTER_KEY;
+
   binding = get_keybinding (keys, resolved_combo);
   if (binding)
     {
@@ -1487,6 +1499,10 @@ meta_x11_display_change_keygrabs (MetaX11Display *x11_display,
     meta_change_keygrab (keys, x11_display->xroot,
                          grab, &keys->overlay_resolved_key_combo);
 
+  if (keys->locate_pointer_resolved_key_combo.len != 0)
+    meta_change_keygrab (keys, x11_display->xroot,
+                         grab, &keys->locate_pointer_resolved_key_combo);
+
   for (i = 0; i < keys->n_iso_next_group_combos; i++)
     meta_change_keygrab (keys, x11_display->xroot,
                          grab, &keys->iso_next_group_combo[i]);
@@ -1952,37 +1968,31 @@ process_event (MetaDisplay          *display,
 }
 
 static gboolean
-process_overlay_key (MetaDisplay *display,
-                     ClutterKeyEvent *event,
-                     MetaWindow *window)
+process_special_modifier_key (MetaDisplay          *display,
+                              ClutterKeyEvent      *event,
+                              MetaWindow           *window,
+                              gboolean             *modifier_press_only,
+                              MetaResolvedKeyCombo *resolved_key_combo,
+                              GFunc                 trigger_callback)
 {
   MetaKeyBindingManager *keys = &display->key_binding_manager;
   MetaBackend *backend = keys->backend;
   Display *xdisplay;
 
-  if (display->focus_window && !keys->overlay_key_only_pressed)
-    {
-      ClutterInputDevice *source;
-
-      source = clutter_event_get_source_device ((ClutterEvent *) event);
-      if (meta_window_shortcuts_inhibited (display->focus_window, source))
-        return FALSE;
-    }
-
   if (META_IS_BACKEND_X11 (backend))
     xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
   else
     xdisplay = NULL;
 
-  if (keys->overlay_key_only_pressed)
+  if (*modifier_press_only)
     {
-      if (! resolved_key_combo_has_keycode (&keys->overlay_resolved_key_combo,
+      if (! resolved_key_combo_has_keycode (resolved_key_combo,
                                             event->hardware_keycode))
         {
-          keys->overlay_key_only_pressed = FALSE;
+          *modifier_press_only = FALSE;
 
           /* OK, the user hit modifier+key rather than pressing and
-           * releasing the ovelay key. We want to handle the key
+           * releasing the modifier key alone. We want to handle the key
            * sequence "normally". Unfortunately, using
            * XAllowEvents(..., ReplayKeyboard, ...) doesn't quite
            * work, since global keybindings won't be activated ("this
@@ -2021,7 +2031,7 @@ process_overlay_key (MetaDisplay *display,
         {
           MetaKeyBinding *binding;
 
-          keys->overlay_key_only_pressed = FALSE;
+          *modifier_press_only = FALSE;
 
           /* We want to unfreeze events, but keep the grab so that if the user
            * starts typing into the overlay we get all the keys */
@@ -2030,11 +2040,11 @@ process_overlay_key (MetaDisplay *display,
                            clutter_input_device_get_device_id (event->device),
                            XIAsyncDevice, event->time);
 
-          binding = get_keybinding (keys, &keys->overlay_resolved_key_combo);
+          binding = get_keybinding (keys, resolved_key_combo);
           if (binding &&
               meta_compositor_filter_keybinding (display->compositor, binding))
             return TRUE;
-          meta_display_overlay_key_activate (display);
+          trigger_callback (display, NULL);
         }
       else
         {
@@ -2044,7 +2054,7 @@ process_overlay_key (MetaDisplay *display,
            *   while the key is still down
            * - passive grabs are only activated on KeyPress and not KeyRelease.
            *
-           * In this case, keys->overlay_key_only_pressed might be wrong.
+           * In this case, modifier_press_only might be wrong.
            * Mutter still ought to acknowledge events, otherwise the X server
            * will not send the next events.
            *
@@ -2059,12 +2069,12 @@ process_overlay_key (MetaDisplay *display,
       return TRUE;
     }
   else if (event->type == CLUTTER_KEY_PRESS &&
-           resolved_key_combo_has_keycode (&keys->overlay_resolved_key_combo,
+           resolved_key_combo_has_keycode (resolved_key_combo,
                                            event->hardware_keycode))
     {
-      keys->overlay_key_only_pressed = TRUE;
+      *modifier_press_only = TRUE;
       /* We keep the keyboard frozen - this allows us to use ReplayKeyboard
-       * on the next event if it's not the release of the overlay key */
+       * on the next event if it's not the release of the modifier key */
       if (xdisplay)
         XIAllowEvents (xdisplay,
                        clutter_input_device_get_device_id (event->device),
@@ -2076,6 +2086,43 @@ process_overlay_key (MetaDisplay *display,
     return FALSE;
 }
 
+
+static gboolean
+process_overlay_key (MetaDisplay     *display,
+                     ClutterKeyEvent *event,
+                     MetaWindow      *window)
+{
+  MetaKeyBindingManager *keys = &display->key_binding_manager;
+
+  return process_special_modifier_key (display,
+                                       event,
+                                       window,
+                                       &keys->overlay_key_only_pressed,
+                                       &keys->overlay_resolved_key_combo,
+                                       (GFunc) meta_display_overlay_key_activate);
+}
+
+static void
+handle_locate_pointer (MetaDisplay *display)
+{
+  meta_compositor_locate_pointer (display->compositor);
+}
+
+static gboolean
+process_locate_pointer_key (MetaDisplay     *display,
+                            ClutterKeyEvent *event,
+                            MetaWindow      *window)
+{
+  MetaKeyBindingManager *keys = &display->key_binding_manager;
+
+  return process_special_modifier_key (display,
+                                       event,
+                                       window,
+                                       &keys->locate_pointer_key_only_pressed,
+                                       &keys->locate_pointer_resolved_key_combo,
+                                       (GFunc) handle_locate_pointer);
+}
+
 static gboolean
 process_iso_next_group (MetaDisplay *display,
                         ClutterKeyEvent *event)
@@ -2129,6 +2176,10 @@ process_key_event (MetaDisplay     *display,
       if (handled)
         return TRUE;
 
+      handled = process_locate_pointer_key (display, event, window);
+      if (handled) /* Continue with the event even if handled */
+        return FALSE;
+
       handled = process_iso_next_group (display, event);
       if (handled)
         return TRUE;
@@ -2217,6 +2268,7 @@ meta_keybindings_process_event (MetaDisplay        *display,
     case CLUTTER_TOUCH_BEGIN:
     case CLUTTER_TOUCH_END:
       keys->overlay_key_only_pressed = FALSE;
+      keys->locate_pointer_key_only_pressed = FALSE;
       return FALSE;
 
     case CLUTTER_KEY_PRESS:
@@ -4405,6 +4457,12 @@ meta_display_init_keys (MetaDisplay *display)
 
   g_hash_table_insert (key_handlers, g_strdup ("overlay-key"), handler);
 
+  handler = g_new0 (MetaKeyHandler, 1);
+  handler->name = g_strdup ("locate-pointer-key");
+  handler->flags = META_KEY_BINDING_BUILTIN;
+
+  g_hash_table_insert (key_handlers, g_strdup ("locate-pointer-key"), handler);
+
   handler = g_new0 (MetaKeyHandler, 1);
   handler->name = g_strdup ("iso-next-group");
   handler->flags = META_KEY_BINDING_BUILTIN;
diff --git a/src/core/prefs.c b/src/core/prefs.c
index 3f0db8afc..9f11a2842 100644
--- a/src/core/prefs.c
+++ b/src/core/prefs.c
@@ -81,6 +81,7 @@ static gboolean use_system_font = FALSE;
 static PangoFontDescription *titlebar_font = NULL;
 static MetaVirtualModifier mouse_button_mods = Mod1Mask;
 static MetaKeyCombo overlay_key_combo = { 0, 0, 0 };
+static MetaKeyCombo locate_pointer_key_combo = { 0, 0, 0 };
 static GDesktopFocusMode focus_mode = G_DESKTOP_FOCUS_MODE_CLICK;
 static GDesktopFocusNewWindows focus_new_windows = G_DESKTOP_FOCUS_NEW_WINDOWS_SMART;
 static gboolean raise_on_click = TRUE;
@@ -145,6 +146,7 @@ static gboolean titlebar_handler (GVariant*, gpointer*, gpointer);
 static gboolean mouse_button_mods_handler (GVariant*, gpointer*, gpointer);
 static gboolean button_layout_handler (GVariant*, gpointer*, gpointer);
 static gboolean overlay_key_handler (GVariant*, gpointer*, gpointer);
+static gboolean locate_pointer_key_handler (GVariant*, gpointer*, gpointer);
 static gboolean iso_next_group_handler (GVariant*, gpointer*, gpointer);
 
 static void     init_bindings             (void);
@@ -427,6 +429,14 @@ static MetaStringPreference preferences_string[] =
       overlay_key_handler,
       NULL,
     },
+    {
+      { "locate-pointer-key",
+        SCHEMA_MUTTER,
+        META_PREF_KEYBINDINGS,
+      },
+      locate_pointer_key_handler,
+      NULL,
+    },
     { { NULL, 0, 0 }, NULL },
   };
 
@@ -1475,6 +1485,36 @@ overlay_key_handler (GVariant *value,
   return TRUE;
 }
 
+static gboolean
+locate_pointer_key_handler (GVariant *value,
+                            gpointer *result,
+                            gpointer  data)
+{
+  MetaKeyCombo combo;
+  const gchar *string_value;
+
+  *result = NULL; /* ignored */
+  string_value = g_variant_get_string (value, NULL);
+
+  if (!string_value || !meta_parse_accelerator (string_value, &combo))
+    {
+      meta_topic (META_DEBUG_KEYBINDINGS,
+                  "Failed to parse value for locate-pointer-key\n");
+      return FALSE;
+    }
+
+  combo.modifiers = 0;
+
+  if (locate_pointer_key_combo.keysym != combo.keysym ||
+      locate_pointer_key_combo.keycode != combo.keycode)
+    {
+      locate_pointer_key_combo = combo;
+      queue_changed (META_PREF_KEYBINDINGS);
+    }
+
+  return TRUE;
+}
+
 static gboolean
 iso_next_group_handler (GVariant *value,
                         gpointer *result,
@@ -1689,6 +1729,14 @@ init_bindings (void)
   pref->builtin = 1;
 
   g_hash_table_insert (key_bindings, g_strdup ("overlay-key"), pref);
+
+  pref = g_new0 (MetaKeyPref, 1);
+  pref->name = g_strdup ("locate-pointer-key");
+  pref->action = META_KEYBINDING_ACTION_LOCATE_POINTER_KEY;
+  pref->combos = g_slist_prepend (pref->combos, &locate_pointer_key_combo);
+  pref->builtin = 1;
+
+  g_hash_table_insert (key_bindings, g_strdup ("locate-pointer-key"), pref);
 }
 
 static gboolean
@@ -1966,6 +2014,12 @@ meta_prefs_get_overlay_binding (MetaKeyCombo *combo)
   *combo = overlay_key_combo;
 }
 
+void
+meta_prefs_get_locate_pointer_binding (MetaKeyCombo *combo)
+{
+  *combo = locate_pointer_key_combo;
+}
+
 const char *
 meta_prefs_get_iso_next_group_option (void)
 {
diff --git a/src/meta/prefs.h b/src/meta/prefs.h
index 9664b5c07..9db540453 100644
--- a/src/meta/prefs.h
+++ b/src/meta/prefs.h
@@ -322,6 +322,7 @@ int      meta_prefs_get_drag_threshold (void);
  * @META_KEYBINDING_ACTION_MOVE_TO_SIDE_W: FILLME
  * @META_KEYBINDING_ACTION_MOVE_TO_CENTER: FILLME
  * @META_KEYBINDING_ACTION_OVERLAY_KEY: FILLME
+ * @META_KEYBINDING_ACTION_LOCATE_POINTER_KEY: FILLME
  * @META_KEYBINDING_ACTION_ALWAYS_ON_TOP: FILLME
  * @META_KEYBINDING_ACTION_LAST: FILLME
  */
@@ -419,6 +420,7 @@ typedef enum _MetaKeyBindingAction
   META_KEYBINDING_ACTION_MOVE_TO_SIDE_W,
   META_KEYBINDING_ACTION_MOVE_TO_CENTER,
   META_KEYBINDING_ACTION_OVERLAY_KEY,
+  META_KEYBINDING_ACTION_LOCATE_POINTER_KEY,
   META_KEYBINDING_ACTION_ISO_NEXT_GROUP,
   META_KEYBINDING_ACTION_ALWAYS_ON_TOP,
   META_KEYBINDING_ACTION_SWITCH_MONITOR,


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