[clutter/clutter-1.18] evdev: Implement keyboard repeat
- From: Rui Matos <rtcm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [clutter/clutter-1.18] evdev: Implement keyboard repeat
- Date: Thu, 27 Feb 2014 10:55:05 +0000 (UTC)
commit a6bd53ec426f48441541b484281295316ce0b077
Author: Rui Matos <tiagomatos gmail com>
Date: Mon Jan 13 16:05:57 2014 +0100
evdev: Implement keyboard repeat
The kernel keyboard repeat functionality isn't configurable and
libinput rightfully ignores it.
This implements keyboard repeat in userspace allowing for consumers to
set the initial delay and repeat intervals.
https://bugzilla.gnome.org/show_bug.cgi?id=725102
clutter/evdev/clutter-device-manager-evdev.c | 129 +++++++++++++++++++++++++-
clutter/evdev/clutter-evdev.h | 4 +
2 files changed, 131 insertions(+), 2 deletions(-)
---
diff --git a/clutter/evdev/clutter-device-manager-evdev.c b/clutter/evdev/clutter-device-manager-evdev.c
index 2355e34..391a542 100644
--- a/clutter/evdev/clutter-device-manager-evdev.c
+++ b/clutter/evdev/clutter-device-manager-evdev.c
@@ -72,6 +72,15 @@ struct _ClutterSeatEvdev
xkb_led_index_t num_lock_led;
xkb_led_index_t scroll_lock_led;
uint32_t button_state;
+
+ /* keyboard repeat */
+ gboolean repeat;
+ guint32 repeat_delay;
+ guint32 repeat_interval;
+ guint32 repeat_key;
+ guint32 repeat_count;
+ guint32 repeat_timer;
+ ClutterInputDevice *repeat_device;
};
typedef struct _ClutterEventSource ClutterEventSource;
@@ -207,6 +216,20 @@ remove_key (GArray *keys,
}
static void
+clear_repeat_timer (ClutterSeatEvdev *seat)
+{
+ if (seat->repeat_timer)
+ {
+ g_source_remove (seat->repeat_timer);
+ seat->repeat_timer = 0;
+ g_clear_object (&seat->repeat_device);
+ }
+}
+
+static gboolean
+keyboard_repeat (gpointer data);
+
+static void
clutter_seat_evdev_sync_leds (ClutterSeatEvdev *seat);
static void
@@ -227,7 +250,10 @@ notify_key_device (ClutterInputDevice *input_device,
* associated with the device yet. */
stage = _clutter_input_device_get_stage (input_device);
if (!stage)
- return;
+ {
+ clear_repeat_timer (seat);
+ return;
+ }
event = _clutter_key_event_new_from_evdev (input_device,
seat->core_keyboard,
@@ -253,12 +279,71 @@ notify_key_device (ClutterInputDevice *input_device,
}
}
else
- changed_state = 0;
+ {
+ changed_state = 0;
+ clutter_event_set_flags (event, CLUTTER_EVENT_FLAG_SYNTHETIC);
+ }
queue_event (event);
if (update_keys && (changed_state & XKB_STATE_LEDS))
clutter_seat_evdev_sync_leds (seat);
+
+ if (state == 0 || /* key release */
+ !seat->repeat ||
+ !xkb_keymap_key_repeats (xkb_state_get_keymap (seat->xkb), event->key.hardware_keycode))
+ {
+ clear_repeat_timer (seat);
+ return;
+ }
+
+ if (state == 1) /* key press */
+ seat->repeat_count = 0;
+
+ seat->repeat_count += 1;
+ seat->repeat_key = key;
+
+ switch (seat->repeat_count)
+ {
+ case 1:
+ case 2:
+ {
+ guint32 interval;
+
+ clear_repeat_timer (seat);
+ seat->repeat_device = g_object_ref (input_device);
+
+ if (seat->repeat_count == 1)
+ interval = seat->repeat_delay;
+ else
+ interval = seat->repeat_interval;
+
+ seat->repeat_timer =
+ clutter_threads_add_timeout_full (CLUTTER_PRIORITY_EVENTS,
+ interval,
+ keyboard_repeat,
+ seat,
+ NULL);
+ return;
+ }
+ default:
+ return;
+ }
+}
+
+static gboolean
+keyboard_repeat (gpointer data)
+{
+ ClutterSeatEvdev *seat = data;
+ guint32 time;
+
+ g_return_val_if_fail (seat->repeat_device != NULL, G_SOURCE_REMOVE);
+
+ time = g_source_get_time (g_main_context_find_source_by_id (NULL, seat->repeat_timer)) / 1000;
+
+ notify_key_device (seat->repeat_device, time, seat->repeat_key, AUTOREPEAT_VALUE, FALSE);
+
+ return G_SOURCE_CONTINUE;
}
static void
@@ -642,6 +727,10 @@ clutter_seat_evdev_new (ClutterDeviceManagerEvdev *manager_evdev,
xkb_keymap_unref (keymap);
}
+ seat->repeat = TRUE;
+ seat->repeat_delay = 250; /* ms */
+ seat->repeat_interval = 33; /* ms */
+
return seat;
}
@@ -661,6 +750,8 @@ clutter_seat_evdev_free (ClutterSeatEvdev *seat)
xkb_state_unref (seat->xkb);
g_array_free (seat->keys, TRUE);
+ clear_repeat_timer (seat);
+
libinput_seat_unref (seat->libinput_seat);
g_free (seat);
@@ -773,6 +864,9 @@ clutter_device_manager_evdev_remove_device (ClutterDeviceManager *manager,
seat->devices = g_slist_remove (seat->devices, device);
priv->devices = g_slist_remove (priv->devices, device);
+ if (seat->repeat_timer && seat->repeat_device == device)
+ clear_repeat_timer (seat);
+
g_object_unref (device);
}
@@ -1480,3 +1574,34 @@ clutter_evdev_set_pointer_constrain_callback (ClutterDeviceManager *e
priv->constrain_data = user_data;
priv->constrain_data_notify = user_data_notify;
}
+
+/**
+ * clutter_evdev_set_keyboard_repeat:
+ * @evdev: the #ClutterDeviceManager created by the evdev backend
+ * @repeat: whether to enable or disable keyboard repeat events
+ * @delay: the delay in ms between the hardware key press event and
+ * the first synthetic event
+ * @interval: the period in ms between consecutive synthetic key
+ * press events
+ *
+ * Enables or disables sythetic key press events, allowing for initial
+ * delay and interval period to be specified.
+ */
+void
+clutter_evdev_set_keyboard_repeat (ClutterDeviceManager *evdev,
+ gboolean repeat,
+ guint32 delay,
+ guint32 interval)
+{
+ ClutterDeviceManagerEvdev *manager_evdev;
+ ClutterSeatEvdev *seat;
+
+ g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER_EVDEV (evdev));
+
+ manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (evdev);
+ seat = manager_evdev->priv->main_seat;
+
+ seat->repeat = repeat;
+ seat->repeat_delay = delay;
+ seat->repeat_interval = interval;
+}
diff --git a/clutter/evdev/clutter-evdev.h b/clutter/evdev/clutter-evdev.h
index 5495161..e57dc6b 100644
--- a/clutter/evdev/clutter-evdev.h
+++ b/clutter/evdev/clutter-evdev.h
@@ -85,6 +85,10 @@ void clutter_evdev_set_pointer_constrain_callback (ClutterDeviceManager
void clutter_evdev_set_keyboard_map (ClutterDeviceManager *evdev,
struct xkb_keymap *keymap);
+void clutter_evdev_set_keyboard_repeat (ClutterDeviceManager *evdev,
+ gboolean repeat,
+ guint32 delay,
+ guint32 interval);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]