[gtk+/matthiasc/wayland/slowkeys: 5/9] wayland: implement slow keys
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/matthiasc/wayland/slowkeys: 5/9] wayland: implement slow keys
- Date: Thu, 3 Mar 2016 06:41:50 +0000 (UTC)
commit 3751aa50a943b3c29cd5727085ba4113ab810c8f
Author: Matthias Clasen <mclasen redhat com>
Date: Wed Mar 2 19:54:56 2016 -0500
wayland: implement slow keys
This is a simple client-side implementation of the AccessX
slow keys feature.
gdk/wayland/gdkdevice-wayland.c | 214 ++++++++++++++++++++++++++++++++++++---
1 files changed, 199 insertions(+), 15 deletions(-)
---
diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c
index d71bab7..a6f8c5e 100644
--- a/gdk/wayland/gdkdevice-wayland.c
+++ b/gdk/wayland/gdkdevice-wayland.c
@@ -112,6 +112,10 @@ struct _GdkWaylandSeat
guint32 repeat_count;
GSettings *keyboard_settings;
+ guint32 slow_key_timer;
+ guint32 slow_key;
+ GSettings *a11y_settings;
+
guint cursor_timeout_id;
guint cursor_image_index;
guint cursor_image_delay;
@@ -177,6 +181,10 @@ struct _GdkWaylandDeviceManagerClass
GdkDeviceManagerClass parent_class;
};
+static void process_key_event (GdkWaylandDeviceData *device,
+ uint32_t time_,
+ uint32_t key,
+ uint32_t state);
static void deliver_key_event (GdkWaylandDeviceData *device,
uint32_t time_,
uint32_t key,
@@ -1519,6 +1527,7 @@ keyboard_handle_enter (void *data,
}
static void stop_key_repeat (GdkWaylandDeviceData *device);
+static void stop_slow_keys (GdkWaylandDeviceData *device);
static void
keyboard_handle_leave (void *data,
@@ -1539,6 +1548,7 @@ keyboard_handle_leave (void *data,
*/
stop_key_repeat (device);
+ stop_slow_keys (device);
_gdk_wayland_display_update_serial (display, serial);
@@ -1690,6 +1700,130 @@ get_key_repeat (GdkWaylandDeviceData *device,
return repeat;
}
+static GSettings *
+get_a11y_settings (GdkWaylandDeviceData *device)
+{
+ if (!device->a11y_settings)
+ {
+ GSettingsSchemaSource *source;
+ GSettingsSchema *schema;
+
+ source = g_settings_schema_source_get_default ();
+ schema = g_settings_schema_source_lookup (source, "org.gnome.desktop.a11y.keyboard", FALSE);
+ if (schema != NULL)
+ {
+ device->a11y_settings = g_settings_new_full (schema, NULL, NULL);
+ g_settings_schema_unref (schema);
+ }
+ }
+
+ return device->a11y_settings;
+}
+
+static gboolean
+get_slow_keys_enabled (GdkWaylandDeviceData *device)
+{
+ GSettings *a11y_settings = get_a11y_settings (device);
+
+ if (a11y_settings)
+ return g_settings_get_boolean (a11y_settings, "slowkeys-enable");
+
+ return FALSE;
+}
+
+static gboolean
+get_slow_keys_beep_on_press (GdkWaylandDeviceData *device)
+{
+ GSettings *a11y_settings = get_a11y_settings (device);
+
+ if (a11y_settings)
+ return g_settings_get_boolean (a11y_settings, "slowkeys-beep-press");
+
+ return FALSE;
+}
+
+static gboolean
+get_slow_keys_beep_on_accept (GdkWaylandDeviceData *device)
+{
+ GSettings *a11y_settings = get_a11y_settings (device);
+
+ if (a11y_settings)
+ return g_settings_get_boolean (a11y_settings, "slowkeys-beep-accept");
+
+ return FALSE;
+}
+
+static gboolean
+get_slow_keys_beep_on_reject (GdkWaylandDeviceData *device)
+{
+ GSettings *a11y_settings = get_a11y_settings (device);
+
+ if (a11y_settings)
+ return g_settings_get_boolean (a11y_settings, "slowkeys-beep-reject");
+
+ return FALSE;
+}
+
+static gint
+get_slow_keys_delay (GdkWaylandDeviceData *device)
+{
+ GSettings *a11y_settings = get_a11y_settings (device);
+
+ if (a11y_settings)
+ return g_settings_get_int (a11y_settings, "slowkeys-delay");
+
+ return 100;
+}
+
+static void start_key_repeat (GdkWaylandDeviceData *device,
+ uint32_t key);
+
+static gboolean
+slow_key (gpointer data)
+{
+ GdkWaylandDeviceData *device = data;
+ uint32_t key;
+
+ key = device->slow_key;
+
+ if (key != 0)
+ deliver_key_event (device, device->time, key, 1);
+
+ device->slow_key = 0;
+ device->slow_key_timer = 0;
+
+ start_key_repeat (device, key);
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
+start_slow_keys (GdkWaylandDeviceData *device,
+ uint32_t key)
+{
+ guint timeout;
+
+ timeout = get_slow_keys_delay (device);
+
+ device->slow_key = key;
+
+ device->slow_key_timer =
+ gdk_threads_add_timeout (timeout, slow_key, device);
+ g_source_set_name_by_id (device->slow_key_timer, "[gtk+] slow_key");
+}
+
+static void
+stop_slow_keys (GdkWaylandDeviceData *device)
+{
+ device->slow_key = 0;
+
+ if (device->slow_key_timer)
+ {
+ g_source_remove (device->slow_key_timer);
+ device->slow_key_timer = 0;
+ }
+}
+
static void
start_key_repeat (GdkWaylandDeviceData *device,
uint32_t key)
@@ -1705,10 +1839,9 @@ start_key_repeat (GdkWaylandDeviceData *device,
if (!get_key_repeat (device, &delay, &interval))
return;
- device->repeat_count++;
device->repeat_key = key;
- if (device->repeat_count == 1)
+ if (device->repeat_count == 0)
timeout = delay;
else
timeout = interval;
@@ -1730,7 +1863,7 @@ stop_key_repeat (GdkWaylandDeviceData *device)
g_clear_pointer (&device->repeat_callback, wl_callback_destroy);
}
-static Gdkevent *
+static GdkEvent *
translate_key_event (GdkWaylandDeviceData *device,
uint32_t time_,
uint32_t key,
@@ -1753,7 +1886,7 @@ translate_key_event (GdkWaylandDeviceData *device,
event->key.group = 0;
event->key.hardware_keycode = key;
event->key.keyval = sym;
- event->key.is_modifier = _gdk_wayland_keymap_key_is_modifier (keymap, key);
+ event->key.is_modifier = _gdk_wayland_keymap_key_is_modifier (device->keymap, key);
translate_keyboard_string (&event->key);
@@ -1768,24 +1901,69 @@ deliver_key_event (GdkWaylandDeviceData *device,
{
GdkEvent *event;
- device->time = time_;
- device->key_modifiers = gdk_keymap_get_modifier_state (device->keymap);
+ if (state == 1)
+ {
+ device->repeat_count++;
+ if (get_slow_keys_enabled (device) &&
+ get_slow_keys_beep_on_accept (device))
+ gdk_display_beep (device->display);
+ }
event = translate_key_event (device, time_, key, state);
_gdk_wayland_display_deliver_event (device->display, event);
+}
+
+static void
+process_key_event (GdkWaylandDeviceData *device,
+ uint32_t time_,
+ uint32_t key,
+ uint32_t state)
+{
+ gboolean deliver = TRUE;
+
+ device->time = time_;
+ device->key_modifiers = gdk_keymap_get_modifier_state (device->keymap);
GDK_NOTE (EVENTS,
- g_message ("keyboard event, code %d, sym %d, "
- "string %s, mods 0x%x",
- event->key.hardware_keycode, event->key.keyval,
- event->key.string, event->key.state));
+ g_message ("process key %s, code %d, modifiers 0x%x",
+ state ? "press" : "release",
+ key, device->key_modifiers));
- stop_key_repeat (device);
+ if (get_slow_keys_enabled (device))
+ {
+ if (state)
+ {
+ if (device->slow_key == key)
+ return;
- if (state == 0)
- return;
+ if (device->repeat_count == 0 &&
+ get_slow_keys_beep_on_press (device))
+ gdk_display_beep (device->display);
- start_key_repeat (device, key);
+ start_slow_keys (device, key);
+ deliver = FALSE;
+ }
+ else
+ {
+ if (device->slow_key == key)
+ {
+ if (get_slow_keys_beep_on_reject (device))
+ gdk_display_beep (device->display);
+ deliver = FALSE;
+ }
+ stop_slow_keys (device);
+ }
+ }
+
+ stop_key_repeat (device);
+ if (!get_slow_keys_enabled (device))
+ {
+ if (state == 1)
+ start_key_repeat (device, key);
+ }
+
+ if (deliver)
+ deliver_key_event (device, time_, key, state);
}
static void
@@ -1798,6 +1976,7 @@ sync_after_repeat_callback (void *data,
g_clear_pointer (&device->repeat_callback, wl_callback_destroy);
deliver_key_event (device, device->time, device->repeat_key, 1);
+ start_key_repeat (device, device->repeat_key);
}
static const struct wl_callback_listener sync_after_repeat_callback_listener = {
@@ -1822,6 +2001,8 @@ keyboard_repeat (gpointer data)
&sync_after_repeat_callback_listener,
device);
+ device->repeat_timer = 0;
+
return G_SOURCE_REMOVE;
}
@@ -1841,7 +2022,8 @@ keyboard_handle_key (void *data,
device->repeat_count = 0;
_gdk_wayland_display_update_serial (display, serial);
- deliver_key_event (data, time, key + 8, state_w);
+
+ process_key_event (data, time, key + 8, state_w);
}
static void
@@ -2671,10 +2853,12 @@ gdk_wayland_seat_finalize (GObject *object)
wl_surface_destroy (seat->pointer_surface);
/* FIXME: destroy data_device */
g_clear_object (&seat->keyboard_settings);
+ g_clear_object (&seat->a11y_settings);
g_clear_object (&seat->drop_context);
g_hash_table_destroy (seat->touches);
gdk_window_destroy (seat->foreign_dnd_window);
stop_key_repeat (seat);
+ stop_slow_keys (seat);
G_OBJECT_CLASS (gdk_wayland_seat_parent_class)->finalize (object);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]