[mutter] clutter/evdev: implement bounce keys support



commit 96ebd1c2142cca3f6fac598f075a73a6ad99ce98
Author: Olivier Fourdan <ofourdan redhat com>
Date:   Thu Oct 12 17:33:33 2017 +0200

    clutter/evdev: implement bounce keys support
    
    Ignore multiple consecutive identical key presses within a time frame.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=788564

 clutter/clutter/evdev/clutter-input-device-evdev.c |   77 ++++++++++++++++++++
 clutter/clutter/evdev/clutter-input-device-evdev.h |    2 +
 2 files changed, 79 insertions(+), 0 deletions(-)
---
diff --git a/clutter/clutter/evdev/clutter-input-device-evdev.c 
b/clutter/clutter/evdev/clutter-input-device-evdev.c
index 0cc37c1..bc7bc8c 100644
--- a/clutter/clutter/evdev/clutter-input-device-evdev.c
+++ b/clutter/clutter/evdev/clutter-input-device-evdev.c
@@ -63,6 +63,7 @@ typedef struct _SlowKeysEventPending
 } SlowKeysEventPending;
 
 static void clear_slow_keys      (ClutterInputDeviceEvdev *device);
+static void stop_bounce_keys     (ClutterInputDeviceEvdev *device);
 
 static void
 clutter_input_device_evdev_finalize (GObject *object)
@@ -78,6 +79,7 @@ clutter_input_device_evdev_finalize (GObject *object)
   _clutter_device_manager_evdev_release_device_id (manager_evdev, device);
 
   clear_slow_keys (device_evdev);
+  stop_bounce_keys (device_evdev);
 
   G_OBJECT_CLASS (clutter_input_device_evdev_parent_class)->finalize (object);
 }
@@ -345,6 +347,65 @@ stop_slow_keys (ClutterEvent               *event,
   emit_event_func (event, CLUTTER_INPUT_DEVICE (device));
 }
 
+static guint
+get_debounce_delay (ClutterInputDevice *device)
+{
+  ClutterKbdA11ySettings a11y_settings;
+
+  clutter_device_manager_get_kbd_a11y_settings (device->device_manager,
+                                                &a11y_settings);
+  /* Settings use int, we use uint, make sure we dont go negative */
+  return MAX (0, a11y_settings.debounce_delay);
+}
+
+static gboolean
+clear_bounce_keys (gpointer data)
+{
+  ClutterInputDeviceEvdev *device = data;
+
+  device->debounce_key = 0;
+  device->debounce_timer = 0;
+
+  return G_SOURCE_REMOVE;
+}
+
+static void
+start_bounce_keys (ClutterEvent            *event,
+                   ClutterInputDeviceEvdev *device)
+{
+  stop_bounce_keys (device);
+
+  device->debounce_key = ((ClutterKeyEvent *) event)->hardware_keycode;
+  device->debounce_timer =
+    clutter_threads_add_timeout (get_debounce_delay (CLUTTER_INPUT_DEVICE (device)),
+                                 clear_bounce_keys,
+                                 device);
+}
+
+static void
+stop_bounce_keys (ClutterInputDeviceEvdev *device)
+{
+  if (device->debounce_timer)
+    {
+      g_source_remove (device->debounce_timer);
+      device->debounce_timer = 0;
+    }
+}
+
+static void
+notify_bounce_keys_reject (ClutterInputDeviceEvdev *device)
+{
+  if (device->a11y_flags & CLUTTER_A11Y_BOUNCE_KEYS_BEEP_REJECT)
+    clutter_input_device_evdev_bell_notify ();
+}
+
+static gboolean
+debounce_key (ClutterEvent            *event,
+              ClutterInputDeviceEvdev *device)
+{
+  return (device->debounce_key == ((ClutterKeyEvent *) event)->hardware_keycode);
+}
+
 static void
 clutter_input_device_evdev_process_kbd_a11y_event (ClutterEvent               *event,
                                                    ClutterInputDevice         *device,
@@ -355,6 +416,19 @@ clutter_input_device_evdev_process_kbd_a11y_event (ClutterEvent               *e
   if (!device_evdev->a11y_flags & CLUTTER_A11Y_KEYBOARD_ENABLED)
     goto emit_event;
 
+  if ((device_evdev->a11y_flags & CLUTTER_A11Y_BOUNCE_KEYS_ENABLED) &&
+      (get_debounce_delay (device) != 0))
+    {
+      if ((event->type == CLUTTER_KEY_PRESS) && debounce_key (event, device_evdev))
+        {
+          notify_bounce_keys_reject (device_evdev);
+
+          return;
+        }
+      else if (event->type == CLUTTER_KEY_RELEASE)
+        start_bounce_keys (event, device_evdev);
+    }
+
   if ((device_evdev->a11y_flags & CLUTTER_A11Y_SLOW_KEYS_ENABLED) &&
       (get_slow_keys_delay (device) != 0))
     {
@@ -379,6 +453,9 @@ clutter_input_device_evdev_apply_kbd_a11y_settings (ClutterInputDeviceEvdev *dev
   if (changed_flags & (CLUTTER_A11Y_KEYBOARD_ENABLED | CLUTTER_A11Y_SLOW_KEYS_ENABLED))
     clear_slow_keys (device);
 
+  if (changed_flags & (CLUTTER_A11Y_KEYBOARD_ENABLED | CLUTTER_A11Y_BOUNCE_KEYS_ENABLED))
+    device->debounce_key = 0;
+
   /* Keep our own copy of keyboard a11y features flags to see what changes */
   device->a11y_flags = settings->controls;
 }
diff --git a/clutter/clutter/evdev/clutter-input-device-evdev.h 
b/clutter/clutter/evdev/clutter-input-device-evdev.h
index a054e0d..ea5957d 100644
--- a/clutter/clutter/evdev/clutter-input-device-evdev.h
+++ b/clutter/clutter/evdev/clutter-input-device-evdev.h
@@ -74,6 +74,8 @@ struct _ClutterInputDeviceEvdev
   /* Keyboard a11y */
   ClutterKeyboardA11yFlags a11y_flags;
   GList *slow_keys_list;
+  guint debounce_timer;
+  guint16 debounce_key;
 };
 
 GType                     _clutter_input_device_evdev_get_type        (void) G_GNUC_CONST;


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