Compare commits
9 Commits
wip/matthi
...
matthiasc/
Author | SHA1 | Date | |
---|---|---|---|
|
8c4a81e16e | ||
|
c15327f5e2 | ||
|
2cdcae8473 | ||
|
1e9db1c9de | ||
|
3751aa50a9 | ||
|
38cd533159 | ||
|
4bee19c0a8 | ||
|
345d41e6ac | ||
|
ced14d4ebe |
@@ -429,7 +429,7 @@ fi
|
||||
|
||||
PKG_PROG_PKG_CONFIG
|
||||
|
||||
WAYLAND_DEPENDENCIES="wayland-client >= wayland_required_version wayland-protocols >= wayland_protocols_required_version xkbcommon >= 0.2.0 wayland-cursor >= wayland_required_version wayland-egl"
|
||||
WAYLAND_DEPENDENCIES="wayland-client >= wayland_required_version wayland-protocols >= wayland_protocols_required_version xkbcommon >= 0.2.0 wayland-cursor >= wayland_required_version wayland-egl libcanberra"
|
||||
if test "$enable_wayland_backend" = "maybe" ; then
|
||||
AC_PATH_PROG([WAYLAND_SCANNER],[wayland-scanner],[no])
|
||||
PKG_CHECK_EXISTS($WAYLAND_DEPENDENCIES, [have_wayland_deps=yes], [have_wayland_deps=no])
|
||||
|
@@ -112,6 +112,19 @@ struct _GdkWaylandSeat
|
||||
guint32 repeat_count;
|
||||
GSettings *keyboard_settings;
|
||||
|
||||
guint32 slow_key_timer;
|
||||
guint32 slow_key;
|
||||
guint32 ignore_key_timer;
|
||||
guint32 ignore_key;
|
||||
uint32_t mods_depressed;
|
||||
uint32_t mods_latched;
|
||||
uint32_t mods_locked;
|
||||
uint32_t group;
|
||||
uint32_t shift_count;
|
||||
uint32_t last_shift_time;
|
||||
guint32 toggle_slow_keys_timer;
|
||||
GSettings *a11y_settings;
|
||||
|
||||
guint cursor_timeout_id;
|
||||
guint cursor_image_index;
|
||||
guint cursor_image_delay;
|
||||
@@ -177,6 +190,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 +1536,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 +1557,7 @@ keyboard_handle_leave (void *data,
|
||||
*/
|
||||
|
||||
stop_key_repeat (device);
|
||||
stop_slow_keys (device);
|
||||
|
||||
_gdk_wayland_display_update_serial (display, serial);
|
||||
|
||||
@@ -1690,6 +1709,327 @@ 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 void
|
||||
set_slow_keys_enabled (GdkWaylandDeviceData *device,
|
||||
gboolean enabled)
|
||||
{
|
||||
GSettings *a11y_settings = get_a11y_settings (device);
|
||||
|
||||
if (a11y_settings)
|
||||
g_settings_set_boolean (a11y_settings, "slowkeys-enable", enabled);
|
||||
}
|
||||
|
||||
static void
|
||||
toggle_slow_keys_enabled (GdkWaylandDeviceData *device)
|
||||
{
|
||||
set_slow_keys_enabled (device, !get_slow_keys_enabled (device));
|
||||
}
|
||||
|
||||
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 gboolean
|
||||
get_bounce_keys_enabled (GdkWaylandDeviceData *device)
|
||||
{
|
||||
GSettings *a11y_settings = get_a11y_settings (device);
|
||||
|
||||
if (a11y_settings)
|
||||
return g_settings_get_boolean (a11y_settings, "bouncekeys-enable");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_bounce_keys_beep_on_reject (GdkWaylandDeviceData *device)
|
||||
{
|
||||
GSettings *a11y_settings = get_a11y_settings (device);
|
||||
|
||||
if (a11y_settings)
|
||||
return g_settings_get_boolean (a11y_settings, "bouncekeys-beep-reject");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gint
|
||||
get_bounce_keys_delay (GdkWaylandDeviceData *device)
|
||||
{
|
||||
GSettings *a11y_settings = get_a11y_settings (device);
|
||||
|
||||
if (a11y_settings)
|
||||
return g_settings_get_int (a11y_settings, "bouncekeys-delay");
|
||||
|
||||
return 100;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_toggle_keys_enabled (GdkWaylandDeviceData *device)
|
||||
{
|
||||
GSettings *a11y_settings = get_a11y_settings (device);
|
||||
|
||||
if (a11y_settings)
|
||||
return g_settings_get_boolean (a11y_settings, "togglekeys-enable");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_sticky_keys_enabled (GdkWaylandDeviceData *device)
|
||||
{
|
||||
GSettings *a11y_settings = get_a11y_settings (device);
|
||||
|
||||
if (a11y_settings)
|
||||
return g_settings_get_boolean (a11y_settings, "stickykeys-enable");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
set_sticky_keys_enabled (GdkWaylandDeviceData *device,
|
||||
gboolean enabled)
|
||||
{
|
||||
GSettings *a11y_settings = get_a11y_settings (device);
|
||||
|
||||
if (a11y_settings)
|
||||
g_settings_set_boolean (a11y_settings, "stickykeys-enable", enabled);
|
||||
}
|
||||
|
||||
static void
|
||||
toggle_sticky_keys_enabled (GdkWaylandDeviceData *device)
|
||||
{
|
||||
set_sticky_keys_enabled (device, !get_sticky_keys_enabled (device));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_sticky_keys_modifier_beep (GdkWaylandDeviceData *device)
|
||||
{
|
||||
GSettings *a11y_settings = get_a11y_settings (device);
|
||||
|
||||
if (a11y_settings)
|
||||
return g_settings_get_boolean (a11y_settings, "stickykeys-modifier-beep");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_sticky_keys_two_key_off (GdkWaylandDeviceData *device)
|
||||
{
|
||||
GSettings *a11y_settings = get_a11y_settings (device);
|
||||
|
||||
if (a11y_settings)
|
||||
return g_settings_get_boolean (a11y_settings, "stickykeys-two-key-off");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_access_keys_enabled (GdkWaylandDeviceData *device)
|
||||
{
|
||||
GSettings *a11y_settings = get_a11y_settings (device);
|
||||
|
||||
if (a11y_settings)
|
||||
return g_settings_get_boolean (a11y_settings, "enable");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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 gboolean
|
||||
bounce_key (gpointer data)
|
||||
{
|
||||
GdkWaylandDeviceData *device = data;
|
||||
|
||||
device->ignore_key = 0;
|
||||
device->ignore_key_timer = 0;
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
start_bounce_keys (GdkWaylandDeviceData *device,
|
||||
uint32_t key)
|
||||
{
|
||||
guint timeout;
|
||||
|
||||
timeout = get_bounce_keys_delay (device);
|
||||
|
||||
device->ignore_key = key;
|
||||
|
||||
device->ignore_key_timer =
|
||||
gdk_threads_add_timeout (timeout, bounce_key, device);
|
||||
g_source_set_name_by_id (device->ignore_key_timer, "[gtk+] bounce_key");
|
||||
}
|
||||
|
||||
static void
|
||||
stop_bounce_keys (GdkWaylandDeviceData *device)
|
||||
{
|
||||
device->ignore_key = 0;
|
||||
|
||||
if (device->ignore_key_timer)
|
||||
{
|
||||
g_source_remove (device->ignore_key_timer);
|
||||
device->ignore_key_timer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
toggle_keys_apply (GdkWaylandDeviceData *device,
|
||||
GdkModifierType from,
|
||||
GdkModifierType to)
|
||||
{
|
||||
if (get_toggle_keys_enabled (device))
|
||||
{
|
||||
if ((from ^ to) & (GDK_LOCK_MASK | GDK_MOD4_MASK))
|
||||
gdk_display_beep (device->display);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
start_key_repeat (GdkWaylandDeviceData *device,
|
||||
uint32_t key)
|
||||
{
|
||||
struct xkb_keymap *xkb_keymap;
|
||||
guint delay, interval, timeout;
|
||||
|
||||
xkb_keymap = _gdk_wayland_keymap_get_xkb_keymap (device->keymap);
|
||||
|
||||
if (!xkb_keymap_key_repeats (xkb_keymap, key))
|
||||
return;
|
||||
|
||||
if (!get_key_repeat (device, &delay, &interval))
|
||||
return;
|
||||
|
||||
device->repeat_key = key;
|
||||
|
||||
if (device->repeat_count == 0)
|
||||
timeout = delay;
|
||||
else
|
||||
timeout = interval;
|
||||
|
||||
device->repeat_timer =
|
||||
gdk_threads_add_timeout (timeout, keyboard_repeat, device);
|
||||
g_source_set_name_by_id (device->repeat_timer, "[gtk+] keyboard_repeat");
|
||||
}
|
||||
|
||||
static void
|
||||
stop_key_repeat (GdkWaylandDeviceData *device)
|
||||
{
|
||||
@@ -1702,30 +2042,48 @@ stop_key_repeat (GdkWaylandDeviceData *device)
|
||||
g_clear_pointer (&device->repeat_callback, wl_callback_destroy);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
toggle_slow_keys (gpointer data)
|
||||
{
|
||||
GdkWaylandDeviceData *device = data;
|
||||
|
||||
toggle_slow_keys_enabled (device);
|
||||
device->toggle_slow_keys_timer = 0;
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
deliver_key_event (GdkWaylandDeviceData *device,
|
||||
uint32_t time_,
|
||||
uint32_t key,
|
||||
uint32_t state)
|
||||
start_toggle_slow_keys (GdkWaylandDeviceData *device)
|
||||
{
|
||||
device->toggle_slow_keys_timer =
|
||||
gdk_threads_add_timeout (8000, toggle_slow_keys, device);
|
||||
g_source_set_name_by_id (device->toggle_slow_keys_timer, "[gtk+] toggle_slow_keys");
|
||||
}
|
||||
|
||||
static void
|
||||
stop_toggle_slow_keys (GdkWaylandDeviceData *device)
|
||||
{
|
||||
if (device->toggle_slow_keys_timer)
|
||||
{
|
||||
g_source_remove (device->toggle_slow_keys_timer);
|
||||
device->toggle_slow_keys_timer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static GdkEvent *
|
||||
translate_key_event (GdkWaylandDeviceData *device,
|
||||
uint32_t time_,
|
||||
uint32_t key,
|
||||
uint32_t state)
|
||||
{
|
||||
GdkEvent *event;
|
||||
struct xkb_state *xkb_state;
|
||||
struct xkb_keymap *xkb_keymap;
|
||||
GdkKeymap *keymap;
|
||||
xkb_keysym_t sym;
|
||||
guint delay, interval, timeout;
|
||||
|
||||
stop_key_repeat (device);
|
||||
|
||||
keymap = device->keymap;
|
||||
xkb_state = _gdk_wayland_keymap_get_xkb_state (keymap);
|
||||
xkb_keymap = _gdk_wayland_keymap_get_xkb_keymap (keymap);
|
||||
|
||||
xkb_state = _gdk_wayland_keymap_get_xkb_state (device->keymap);
|
||||
sym = xkb_state_key_get_one_sym (xkb_state, key);
|
||||
|
||||
device->time = time_;
|
||||
device->key_modifiers = gdk_keymap_get_modifier_state (keymap);
|
||||
|
||||
event = gdk_event_new (state ? GDK_KEY_PRESS : GDK_KEY_RELEASE);
|
||||
event->key.window = device->keyboard_focus ? g_object_ref (device->keyboard_focus) : NULL;
|
||||
gdk_event_set_device (event, device->master_keyboard);
|
||||
@@ -1736,38 +2094,177 @@ deliver_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);
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
static void
|
||||
deliver_key_event (GdkWaylandDeviceData *device,
|
||||
uint32_t time_,
|
||||
uint32_t key,
|
||||
uint32_t state)
|
||||
{
|
||||
GdkEvent *event;
|
||||
struct xkb_state *xkb_state;
|
||||
|
||||
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);
|
||||
|
||||
if (state == 1)
|
||||
{
|
||||
if (get_sticky_keys_enabled (device) &&
|
||||
!_gdk_wayland_keymap_key_is_modifier (device->keymap, key))
|
||||
{
|
||||
device->mods_latched = 0;
|
||||
|
||||
device->key_modifiers = device->mods_locked;
|
||||
xkb_state = _gdk_wayland_keymap_get_xkb_state (device->keymap);
|
||||
xkb_state_update_mask (xkb_state, 0, 0, device->mods_locked, device->group, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
process_key_event (GdkWaylandDeviceData *device,
|
||||
uint32_t time_,
|
||||
uint32_t key,
|
||||
uint32_t state)
|
||||
{
|
||||
gboolean deliver = TRUE;
|
||||
struct xkb_state *xkb_state;
|
||||
|
||||
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));
|
||||
|
||||
if (state == 0)
|
||||
return;
|
||||
if (get_sticky_keys_enabled (device))
|
||||
{
|
||||
if (state && device->mods_depressed &&
|
||||
get_sticky_keys_two_key_off (device))
|
||||
{
|
||||
set_sticky_keys_enabled (device, FALSE);
|
||||
device->mods_depressed = 0;
|
||||
device->mods_latched = 0;
|
||||
device->mods_locked = 0;
|
||||
|
||||
if (!xkb_keymap_key_repeats (xkb_keymap, key))
|
||||
return;
|
||||
device->key_modifiers = 0;
|
||||
xkb_state = _gdk_wayland_keymap_get_xkb_state (device->keymap);
|
||||
xkb_state_update_mask (xkb_state, 0, 0, 0, device->group, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (!get_key_repeat (device, &delay, &interval))
|
||||
return;
|
||||
if (get_access_keys_enabled (device))
|
||||
{
|
||||
xkb_keysym_t sym;
|
||||
|
||||
device->repeat_count++;
|
||||
device->repeat_key = key;
|
||||
xkb_state = _gdk_wayland_keymap_get_xkb_state (device->keymap);
|
||||
sym = xkb_state_key_get_one_sym (xkb_state, key);
|
||||
if (state)
|
||||
{
|
||||
if (sym == XKB_KEY_Shift_L || sym == XKB_KEY_Shift_R)
|
||||
{
|
||||
start_toggle_slow_keys (device);
|
||||
if (!get_slow_keys_enabled (device))
|
||||
{
|
||||
if (time_ - device->last_shift_time > 15000)
|
||||
device->shift_count = 1;
|
||||
else
|
||||
device->shift_count++;
|
||||
device->last_shift_time = time_;
|
||||
}
|
||||
}
|
||||
else
|
||||
stop_toggle_slow_keys (device);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sym == XKB_KEY_Shift_L || sym == XKB_KEY_Shift_R)
|
||||
{
|
||||
stop_toggle_slow_keys (device);
|
||||
if (device->shift_count >= 5)
|
||||
{
|
||||
toggle_sticky_keys_enabled (device);
|
||||
device->shift_count = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
device->shift_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (device->repeat_count == 1)
|
||||
timeout = delay;
|
||||
else
|
||||
timeout = interval;
|
||||
if (get_slow_keys_enabled (device))
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
if (device->slow_key == key)
|
||||
return;
|
||||
|
||||
device->repeat_timer =
|
||||
gdk_threads_add_timeout (timeout, keyboard_repeat, device);
|
||||
g_source_set_name_by_id (device->repeat_timer, "[gtk+] keyboard_repeat");
|
||||
if (device->repeat_count == 0 &&
|
||||
get_slow_keys_beep_on_press (device))
|
||||
gdk_display_beep (device->display);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if (get_bounce_keys_enabled (device))
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
if (device->ignore_key == key)
|
||||
{
|
||||
if (get_bounce_keys_beep_on_reject (device))
|
||||
gdk_display_beep (device->display);
|
||||
deliver = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (device->ignore_key == key)
|
||||
{
|
||||
stop_bounce_keys (device);
|
||||
deliver = FALSE;
|
||||
}
|
||||
start_bounce_keys (device, key);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@@ -1780,6 +2277,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 = {
|
||||
@@ -1804,6 +2302,8 @@ keyboard_repeat (gpointer data)
|
||||
&sync_after_repeat_callback_listener,
|
||||
device);
|
||||
|
||||
device->repeat_timer = 0;
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
@@ -1823,7 +2323,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
|
||||
@@ -1839,14 +2340,48 @@ keyboard_handle_modifiers (void *data,
|
||||
GdkKeymap *keymap;
|
||||
struct xkb_state *xkb_state;
|
||||
PangoDirection direction;
|
||||
GdkModifierType modifiers;
|
||||
|
||||
device->mods_depressed = mods_depressed;
|
||||
|
||||
if (get_sticky_keys_enabled (device))
|
||||
{
|
||||
if (mods_depressed == 0)
|
||||
return;
|
||||
|
||||
if (get_sticky_keys_modifier_beep (device))
|
||||
gdk_display_beep (device->display);
|
||||
|
||||
if (device->mods_locked & mods_depressed)
|
||||
{
|
||||
device->mods_locked &= ~mods_depressed;
|
||||
}
|
||||
else if (device->mods_latched == mods_depressed)
|
||||
{
|
||||
device->mods_locked = mods_depressed;
|
||||
device->mods_latched = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
device->mods_latched = mods_depressed;
|
||||
}
|
||||
|
||||
mods_depressed = 0;
|
||||
mods_latched = device->mods_latched;
|
||||
mods_locked = device->mods_locked;
|
||||
}
|
||||
|
||||
keymap = device->keymap;
|
||||
direction = gdk_keymap_get_direction (keymap);
|
||||
xkb_state = _gdk_wayland_keymap_get_xkb_state (keymap);
|
||||
modifiers = device->key_modifiers;
|
||||
device->key_modifiers = mods_depressed | mods_latched | mods_locked;
|
||||
device->group = group;
|
||||
|
||||
xkb_state_update_mask (xkb_state, mods_depressed, mods_latched, mods_locked, group, 0, 0);
|
||||
|
||||
toggle_keys_apply (device, modifiers, device->key_modifiers);
|
||||
|
||||
g_signal_emit_by_name (keymap, "state-changed");
|
||||
if (direction != gdk_keymap_get_direction (keymap))
|
||||
g_signal_emit_by_name (keymap, "direction-changed");
|
||||
@@ -2653,10 +3188,14 @@ 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);
|
||||
stop_bounce_keys (seat);
|
||||
stop_toggle_slow_keys (seat);
|
||||
|
||||
G_OBJECT_CLASS (gdk_wayland_seat_parent_class)->finalize (object);
|
||||
}
|
||||
|
@@ -27,7 +27,9 @@
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include "gdkintl.h"
|
||||
#include "gdkwayland.h"
|
||||
#include "gdkprivate-wayland.h"
|
||||
#include "gdkdisplay.h"
|
||||
#include "gdkdisplay-wayland.h"
|
||||
#include "gdkscreen.h"
|
||||
@@ -39,6 +41,8 @@
|
||||
#include "gdkglcontext-wayland.h"
|
||||
#include "pointer-gestures-unstable-v1-client-protocol.h"
|
||||
|
||||
#include <canberra.h>
|
||||
|
||||
/**
|
||||
* SECTION:wayland_interaction
|
||||
* @Short_description: Wayland backend-specific functions
|
||||
@@ -522,7 +526,25 @@ gdk_wayland_display_get_default_screen (GdkDisplay *display)
|
||||
static void
|
||||
gdk_wayland_display_beep (GdkDisplay *display)
|
||||
{
|
||||
ca_context *c;
|
||||
ca_proplist *p;
|
||||
|
||||
g_return_if_fail (GDK_IS_DISPLAY (display));
|
||||
|
||||
c = gdk_wayland_screen_get_ca_context (gdk_display_get_default_screen (display));
|
||||
if (!c)
|
||||
return;
|
||||
|
||||
ca_proplist_create (&p);
|
||||
ca_proplist_sets (p, CA_PROP_EVENT_ID, "bell-window-system");
|
||||
ca_proplist_sets (p, CA_PROP_EVENT_DESCRIPTION, _("Bell event"));
|
||||
ca_proplist_sets (p, CA_PROP_CANBERRA_CACHE_CONTROL, "permanent");
|
||||
|
||||
ca_proplist_setf (p, CA_PROP_APPLICATION_PROCESS_ID, "%d", getpid ());
|
||||
|
||||
ca_context_play_full (c, 1, p, NULL, NULL);
|
||||
|
||||
ca_proplist_destroy (p);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -36,6 +36,8 @@
|
||||
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
#include <canberra.h>
|
||||
|
||||
#include "gdkinternals.h"
|
||||
#include "wayland/gtk-primary-selection-client-protocol.h"
|
||||
|
||||
@@ -276,4 +278,6 @@ EGLSurface gdk_wayland_window_get_dummy_egl_surface (GdkWindow *window,
|
||||
void gdk_wayland_seat_set_global_cursor (GdkSeat *seat,
|
||||
GdkCursor *cursor);
|
||||
|
||||
ca_context *gdk_wayland_screen_get_ca_context (GdkScreen *screen);
|
||||
|
||||
#endif /* __GDK_PRIVATE_WAYLAND_H__ */
|
||||
|
@@ -31,6 +31,8 @@
|
||||
|
||||
#include "wm-button-layout-translation.h"
|
||||
|
||||
#include "canberra.h"
|
||||
|
||||
typedef struct _GdkWaylandScreen GdkWaylandScreen;
|
||||
typedef struct _GdkWaylandScreenClass GdkWaylandScreenClass;
|
||||
|
||||
@@ -70,6 +72,7 @@ struct _GdkWaylandScreen
|
||||
|
||||
GHashTable *settings;
|
||||
GsdXftSettings xft_settings;
|
||||
ca_context *ca_context;
|
||||
|
||||
guint32 shell_capabilities;
|
||||
};
|
||||
@@ -159,6 +162,9 @@ gdk_wayland_screen_finalize (GObject *object)
|
||||
|
||||
deinit_multihead (GDK_SCREEN (object));
|
||||
|
||||
if (screen_wayland->ca_context)
|
||||
ca_context_destroy (screen_wayland->ca_context);
|
||||
|
||||
g_hash_table_destroy (screen_wayland->settings);
|
||||
|
||||
G_OBJECT_CLASS (_gdk_wayland_screen_parent_class)->finalize (object);
|
||||
@@ -595,6 +601,83 @@ find_translation_entry_by_setting (const gchar *setting)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ca_context *
|
||||
gdk_wayland_screen_get_ca_context (GdkScreen *screen)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
||||
ca_context *c;
|
||||
ca_proplist *p;
|
||||
const char *name;
|
||||
GSettings *settings;
|
||||
|
||||
if (screen_wayland->ca_context)
|
||||
goto out;
|
||||
|
||||
if (ca_context_create (&c) != CA_SUCCESS)
|
||||
return NULL;
|
||||
|
||||
if (ca_proplist_create (&p) != CA_SUCCESS)
|
||||
{
|
||||
ca_context_destroy (c);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
name = g_get_application_name ();
|
||||
if (name)
|
||||
ca_proplist_sets (p, CA_PROP_APPLICATION_NAME, name);
|
||||
|
||||
settings = g_hash_table_lookup (screen_wayland->settings, "org.gnome.desktop.sound");
|
||||
|
||||
if (settings)
|
||||
{
|
||||
char *theme_name;
|
||||
gboolean event_sounds;
|
||||
|
||||
theme_name = g_settings_get_string (settings, "theme-name");
|
||||
event_sounds = g_settings_get_boolean (settings, "event-sounds");
|
||||
|
||||
ca_proplist_sets (p, CA_PROP_CANBERRA_XDG_THEME_NAME, theme_name);
|
||||
ca_proplist_sets (p, CA_PROP_CANBERRA_ENABLE, event_sounds ? "1" : "0");
|
||||
|
||||
g_free (theme_name);
|
||||
}
|
||||
|
||||
ca_context_change_props_full (c, p);
|
||||
ca_proplist_destroy (p);
|
||||
|
||||
screen_wayland->ca_context = c;
|
||||
|
||||
out:
|
||||
return screen_wayland->ca_context;
|
||||
}
|
||||
|
||||
static void
|
||||
update_sound_settings (GSettings *settings,
|
||||
const char *key,
|
||||
GdkScreen *screen)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
||||
|
||||
if (screen_wayland->ca_context == NULL)
|
||||
return;
|
||||
|
||||
if (strcmp (key, "theme-name") == 0)
|
||||
{
|
||||
gchar *theme_name;
|
||||
|
||||
theme_name = g_settings_get_string (settings, key);
|
||||
ca_context_change_props (screen_wayland->ca_context, CA_PROP_CANBERRA_XDG_THEME_NAME, theme_name, NULL);
|
||||
g_free (theme_name);
|
||||
}
|
||||
else if (strcmp (key, "event-sounds") == 0)
|
||||
{
|
||||
gboolean event_sounds;
|
||||
|
||||
event_sounds = g_settings_get_boolean (settings, key);
|
||||
ca_context_change_props (screen_wayland->ca_context, CA_PROP_CANBERRA_ENABLE, event_sounds ? "1" : "0", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
settings_changed (GSettings *settings,
|
||||
const gchar *key,
|
||||
@@ -606,6 +689,9 @@ settings_changed (GSettings *settings,
|
||||
|
||||
if (entry != NULL)
|
||||
{
|
||||
if (strcmp (entry->schema, "org.gnome.desktop.sound") == 0)
|
||||
update_sound_settings (settings, key, screen);
|
||||
|
||||
if (entry->type != G_TYPE_NONE)
|
||||
notify_setting (screen, entry->setting);
|
||||
else
|
||||
|
Reference in New Issue
Block a user