backends/native: Update keyboard a11y status in seat impl

Instead of going through the event queue, stage handling code, and
back to the input device via a vmethod call, do this directly in the
MetaSeatImpl. This is not too different from X11, where everything
happens inside the backend.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
This commit is contained in:
Carlos Garnacho 2020-11-19 23:58:56 +01:00 committed by Marge Bot
parent f117a157dc
commit 2ff5bb4299
7 changed files with 44 additions and 63 deletions

View File

@ -34,9 +34,6 @@
G_BEGIN_DECLS G_BEGIN_DECLS
typedef void (*ClutterEmitInputDeviceEvent) (ClutterEvent *event,
ClutterInputDevice *device);
struct _ClutterInputDeviceClass struct _ClutterInputDeviceClass
{ {
GObjectClass parent_class; GObjectClass parent_class;
@ -53,11 +50,6 @@ struct _ClutterInputDeviceClass
int (* get_pad_feature_group) (ClutterInputDevice *device, int (* get_pad_feature_group) (ClutterInputDevice *device,
ClutterInputDevicePadFeature feature, ClutterInputDevicePadFeature feature,
int n_feature); int n_feature);
/* Keyboard accessbility */
void (* process_kbd_a11y_event) (ClutterEvent *event,
ClutterInputDevice *device,
ClutterEmitInputDeviceEvent emit_event_func);
}; };
#define CLUTTER_TYPE_INPUT_DEVICE (clutter_input_device_get_type ()) #define CLUTTER_TYPE_INPUT_DEVICE (clutter_input_device_get_type ())

View File

@ -1488,8 +1488,8 @@ emit_touch_event (ClutterEvent *event,
} }
static inline void static inline void
emit_keyboard_event (ClutterEvent *event, process_key_event (ClutterEvent *event,
ClutterInputDevice *device) ClutterInputDevice *device)
{ {
if (_clutter_event_process_filters (event)) if (_clutter_event_process_filters (event))
return; return;
@ -1500,21 +1500,6 @@ emit_keyboard_event (ClutterEvent *event,
emit_event_chain (event); emit_event_chain (event);
} }
static inline void
process_key_event (ClutterEvent *event,
ClutterInputDevice *device)
{
ClutterInputDeviceClass *device_class = CLUTTER_INPUT_DEVICE_GET_CLASS (device);
if (device_class->process_kbd_a11y_event)
{
device_class->process_kbd_a11y_event (event, device, emit_keyboard_event);
return;
}
emit_keyboard_event (event, device);
}
static gboolean static gboolean
is_off_stage (ClutterActor *stage, is_off_stage (ClutterActor *stage,
gfloat x, gfloat x,

View File

@ -48,7 +48,6 @@ typedef struct _SlowKeysEventPending
{ {
MetaInputDeviceNative *device; MetaInputDeviceNative *device;
ClutterEvent *event; ClutterEvent *event;
ClutterEmitInputDeviceEvent emit_event_func;
guint timer; guint timer;
} SlowKeysEventPending; } SlowKeysEventPending;
@ -242,8 +241,7 @@ trigger_slow_keys (gpointer data)
/* Alter timestamp and emit the event */ /* Alter timestamp and emit the event */
key_event->time = us2ms (g_get_monotonic_time ()); key_event->time = us2ms (g_get_monotonic_time ());
slow_keys_event->emit_event_func (slow_keys_event->event, _clutter_event_push (slow_keys_event->event, TRUE);
CLUTTER_INPUT_DEVICE (device));
/* Then remote the pending event */ /* Then remote the pending event */
device->slow_keys_list = g_list_remove (device->slow_keys_list, slow_keys_event); device->slow_keys_list = g_list_remove (device->slow_keys_list, slow_keys_event);
@ -266,21 +264,19 @@ find_pending_event_by_keycode (gconstpointer a,
return kb->hardware_keycode - ka->hardware_keycode; return kb->hardware_keycode - ka->hardware_keycode;
} }
static void static gboolean
start_slow_keys (ClutterEvent *event, start_slow_keys (ClutterEvent *event,
MetaInputDeviceNative *device, MetaInputDeviceNative *device)
ClutterEmitInputDeviceEvent emit_event_func)
{ {
SlowKeysEventPending *slow_keys_event; SlowKeysEventPending *slow_keys_event;
ClutterKeyEvent *key_event = (ClutterKeyEvent *) event; ClutterKeyEvent *key_event = (ClutterKeyEvent *) event;
if (key_event->flags & CLUTTER_EVENT_FLAG_REPEATED) if (key_event->flags & CLUTTER_EVENT_FLAG_REPEATED)
return; return TRUE;
slow_keys_event = g_new0 (SlowKeysEventPending, 1); slow_keys_event = g_new0 (SlowKeysEventPending, 1);
slow_keys_event->device = device; slow_keys_event->device = device;
slow_keys_event->event = clutter_event_copy (event); slow_keys_event->event = clutter_event_copy (event);
slow_keys_event->emit_event_func = emit_event_func;
slow_keys_event->timer = slow_keys_event->timer =
clutter_threads_add_timeout (get_slow_keys_delay (CLUTTER_INPUT_DEVICE (device)), clutter_threads_add_timeout (get_slow_keys_delay (CLUTTER_INPUT_DEVICE (device)),
trigger_slow_keys, trigger_slow_keys,
@ -289,12 +285,13 @@ start_slow_keys (ClutterEvent *event,
if (device->a11y_flags & META_A11Y_SLOW_KEYS_BEEP_PRESS) if (device->a11y_flags & META_A11Y_SLOW_KEYS_BEEP_PRESS)
meta_input_device_native_bell_notify (device); meta_input_device_native_bell_notify (device);
return TRUE;
} }
static void static gboolean
stop_slow_keys (ClutterEvent *event, stop_slow_keys (ClutterEvent *event,
MetaInputDeviceNative *device, MetaInputDeviceNative *device)
ClutterEmitInputDeviceEvent emit_event_func)
{ {
GList *item; GList *item;
@ -310,11 +307,11 @@ stop_slow_keys (ClutterEvent *event,
if (device->a11y_flags & META_A11Y_SLOW_KEYS_BEEP_REJECT) if (device->a11y_flags & META_A11Y_SLOW_KEYS_BEEP_REJECT)
meta_input_device_native_bell_notify (device); meta_input_device_native_bell_notify (device);
return; return TRUE;
} }
/* If no key press event was pending, just emit the key release as-is */ /* If no key press event was pending, just emit the key release as-is */
emit_event_func (event, CLUTTER_INPUT_DEVICE (device)); return FALSE;
} }
static guint static guint
@ -1105,17 +1102,12 @@ handle_mousekeys_release (ClutterEvent *event,
return FALSE; return FALSE;
} }
static void gboolean
meta_input_device_native_process_kbd_a11y_event (ClutterEvent *event, meta_input_device_native_process_kbd_a11y_event (ClutterInputDevice *device,
ClutterInputDevice *device, ClutterEvent *event)
ClutterEmitInputDeviceEvent emit_event_func)
{ {
MetaInputDeviceNative *device_evdev = META_INPUT_DEVICE_NATIVE (device); MetaInputDeviceNative *device_evdev = META_INPUT_DEVICE_NATIVE (device);
/* Ignore key events injected from IM */
if (event->key.flags & CLUTTER_EVENT_FLAG_INPUT_METHOD)
goto emit_event;
if (device_evdev->a11y_flags & META_A11Y_KEYBOARD_ENABLED) if (device_evdev->a11y_flags & META_A11Y_KEYBOARD_ENABLED)
{ {
if (event->type == CLUTTER_KEY_PRESS) if (event->type == CLUTTER_KEY_PRESS)
@ -1128,10 +1120,10 @@ meta_input_device_native_process_kbd_a11y_event (ClutterEvent *eve
{ {
if (event->type == CLUTTER_KEY_PRESS && if (event->type == CLUTTER_KEY_PRESS &&
handle_mousekeys_press (event, device_evdev)) handle_mousekeys_press (event, device_evdev))
return; /* swallow event */ return TRUE; /* swallow event */
if (event->type == CLUTTER_KEY_RELEASE && if (event->type == CLUTTER_KEY_RELEASE &&
handle_mousekeys_release (event, device_evdev)) handle_mousekeys_release (event, device_evdev))
return; /* swallow event */ return TRUE; /* swallow event */
} }
if ((device_evdev->a11y_flags & META_A11Y_BOUNCE_KEYS_ENABLED) && if ((device_evdev->a11y_flags & META_A11Y_BOUNCE_KEYS_ENABLED) &&
@ -1141,7 +1133,7 @@ meta_input_device_native_process_kbd_a11y_event (ClutterEvent *eve
{ {
notify_bounce_keys_reject (device_evdev); notify_bounce_keys_reject (device_evdev);
return; return TRUE;
} }
else if (event->type == CLUTTER_KEY_RELEASE) else if (event->type == CLUTTER_KEY_RELEASE)
start_bounce_keys (event, device_evdev); start_bounce_keys (event, device_evdev);
@ -1151,11 +1143,9 @@ meta_input_device_native_process_kbd_a11y_event (ClutterEvent *eve
(get_slow_keys_delay (device) != 0)) (get_slow_keys_delay (device) != 0))
{ {
if (event->type == CLUTTER_KEY_PRESS) if (event->type == CLUTTER_KEY_PRESS)
start_slow_keys (event, device_evdev, emit_event_func); return start_slow_keys (event, device_evdev);
else if (event->type == CLUTTER_KEY_RELEASE) else if (event->type == CLUTTER_KEY_RELEASE)
stop_slow_keys (event, device_evdev, emit_event_func); return stop_slow_keys (event, device_evdev);
return;
} }
if (device_evdev->a11y_flags & META_A11Y_STICKY_KEYS_ENABLED) if (device_evdev->a11y_flags & META_A11Y_STICKY_KEYS_ENABLED)
@ -1166,8 +1156,7 @@ meta_input_device_native_process_kbd_a11y_event (ClutterEvent *eve
handle_stickykeys_release (event, device_evdev); handle_stickykeys_release (event, device_evdev);
} }
emit_event: return FALSE;
emit_event_func (event, device);
} }
void void
@ -1230,7 +1219,6 @@ meta_input_device_native_class_init (MetaInputDeviceNativeClass *klass)
device_class->get_group_n_modes = meta_input_device_native_get_group_n_modes; device_class->get_group_n_modes = meta_input_device_native_get_group_n_modes;
device_class->is_grouped = meta_input_device_native_is_grouped; device_class->is_grouped = meta_input_device_native_is_grouped;
device_class->get_pad_feature_group = meta_input_device_native_get_pad_feature_group; device_class->get_pad_feature_group = meta_input_device_native_get_pad_feature_group;
device_class->process_kbd_a11y_event = meta_input_device_native_process_kbd_a11y_event;
obj_props[PROP_DEVICE_MATRIX] = obj_props[PROP_DEVICE_MATRIX] =
g_param_spec_boxed ("device-matrix", g_param_spec_boxed ("device-matrix",

View File

@ -149,5 +149,7 @@ void meta_input_device_native_set_coords (MetaInputDeviceNat
void meta_input_device_native_get_coords (MetaInputDeviceNative *device_native, void meta_input_device_native_get_coords (MetaInputDeviceNative *device_native,
float *x, float *x,
float *y); float *y);
gboolean meta_input_device_native_process_kbd_a11y_event (ClutterInputDevice *device,
ClutterEvent *event);
#endif /* META_INPUT_DEVICE_NATIVE_H */ #endif /* META_INPUT_DEVICE_NATIVE_H */

View File

@ -320,6 +320,7 @@ meta_seat_impl_notify_key (MetaSeatImpl *seat_impl,
{ {
ClutterEvent *event = NULL; ClutterEvent *event = NULL;
enum xkb_state_component changed_state; enum xkb_state_component changed_state;
uint32_t keycode;
if (state != AUTOREPEAT_VALUE) if (state != AUTOREPEAT_VALUE)
{ {
@ -342,12 +343,13 @@ meta_seat_impl_notify_key (MetaSeatImpl *seat_impl,
us2ms (time_us), key, state); us2ms (time_us), key, state);
meta_event_native_set_event_code (event, key); meta_event_native_set_event_code (event, key);
keycode = meta_xkb_evdev_to_keycode (key);
/* We must be careful and not pass multiple releases to xkb, otherwise it gets /* We must be careful and not pass multiple releases to xkb, otherwise it gets
confused and locks the modifiers */ confused and locks the modifiers */
if (state != AUTOREPEAT_VALUE) if (state != AUTOREPEAT_VALUE)
{ {
changed_state = xkb_state_update_key (seat_impl->xkb, changed_state = xkb_state_update_key (seat_impl->xkb, keycode,
event->key.hardware_keycode,
state ? XKB_KEY_DOWN : XKB_KEY_UP); state ? XKB_KEY_DOWN : XKB_KEY_UP);
} }
else else
@ -356,7 +358,11 @@ meta_seat_impl_notify_key (MetaSeatImpl *seat_impl,
clutter_event_set_flags (event, CLUTTER_EVENT_FLAG_REPEATED); clutter_event_set_flags (event, CLUTTER_EVENT_FLAG_REPEATED);
} }
queue_event (seat_impl, event); if (!meta_input_device_native_process_kbd_a11y_event (seat_impl->core_keyboard,
event))
queue_event (seat_impl, event);
else
clutter_event_free (event);
if (update_keys && (changed_state & XKB_STATE_LEDS)) if (update_keys && (changed_state & XKB_STATE_LEDS))
{ {
@ -380,7 +386,7 @@ meta_seat_impl_notify_key (MetaSeatImpl *seat_impl,
if (state == 0 || /* key release */ if (state == 0 || /* key release */
!seat_impl->repeat || !seat_impl->repeat ||
!xkb_keymap_key_repeats (xkb_state_get_keymap (seat_impl->xkb), !xkb_keymap_key_repeats (xkb_state_get_keymap (seat_impl->xkb),
event->key.hardware_keycode)) keycode))
{ {
meta_seat_impl_clear_repeat_timer (seat_impl); meta_seat_impl_clear_repeat_timer (seat_impl);
return; return;

View File

@ -62,7 +62,7 @@ meta_key_event_new_from_evdev (ClutterInputDevice *device,
* 0, whereas X11's minimum keycode, for really stupid reasons, is 8. * 0, whereas X11's minimum keycode, for really stupid reasons, is 8.
* So the evdev XKB rules are based on the keycodes all being shifted * So the evdev XKB rules are based on the keycodes all being shifted
* upwards by 8. */ * upwards by 8. */
key += 8; key = meta_xkb_evdev_to_keycode (key);
n = xkb_key_get_syms (xkb_state, key, &syms); n = xkb_key_get_syms (xkb_state, key, &syms);
if (n == 1) if (n == 1)
@ -128,3 +128,10 @@ meta_xkb_keycode_to_evdev (uint32_t xkb_keycode)
*/ */
return xkb_keycode - 8; return xkb_keycode - 8;
} }
uint32_t
meta_xkb_evdev_to_keycode (uint32_t evcode)
{
/* The inverse of meta_xkb_keycode_to_evdev */
return evcode + 8;
}

View File

@ -38,5 +38,6 @@ void meta_xkb_translate_state (ClutterEvent *event,
ClutterModifierType meta_xkb_translate_modifiers (struct xkb_state *state, ClutterModifierType meta_xkb_translate_modifiers (struct xkb_state *state,
ClutterModifierType button_state); ClutterModifierType button_state);
uint32_t meta_xkb_keycode_to_evdev (uint32_t hardware_keycode); uint32_t meta_xkb_keycode_to_evdev (uint32_t hardware_keycode);
uint32_t meta_xkb_evdev_to_keycode (uint32_t evcode);
#endif /* META_XKB_UTILS_H */ #endif /* META_XKB_UTILS_H */