backends: Add a11y interface methods to subscribe to key event input

This adds a pair of methods to signal an interest in receiving
all key events without grabbing them, e. g. the previously expected behavior
by screen readers.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4217>
This commit is contained in:
Lukáš Tyrychtr 2025-02-07 14:21:17 +01:00 committed by Marge Bot
parent 800981c40c
commit 20c9b8cf0c
2 changed files with 75 additions and 3 deletions

View File

@ -16,7 +16,7 @@
GrabKeyboard:
Starts grabbing all key events. The client receives the events
through the KeyEvent signal as always, but the events aren't handled
through the KeyEvent signal, and in addition, the events aren't handled
normally by the compositor. This includes changes to the state
of toggles like Caps Lock, Num Lock, and Scroll Lock.
@ -33,9 +33,36 @@
After calling this method, the key grabs specified in the last call
to SetKeyGrabs, if any, are still in effect.
Also, the client will still receive key events through the KeyEvent
signal, if it has called WatchKeyboard.
-->
<method name="UngrabKeyboard" />
<!--
WatchKeyboard:
Starts watching all key events. The client receives the events
through the KeyEvent signal, but the events are still handled
normally by the compositor. This includes changes to the state
of toggles like Caps Lock, Num Lock, and Scroll Lock.
This behavior stays in effect until the same client calls
UnwatchKeyboard or closes its D-Bus connection.
-->
<method name="WatchKeyboard" />
<!--
UnwatchKeyboard:
Reverses the effect of calling WatchKeyboard. If WatchKeyboard wasn't
previously called, this method does nothing.
After calling this method, the key grabs specified in the last call
to SetKeyGrabs, if any, are still in effect,
but other key events are no longer reported to this client.
-->
<method name="UnwatchKeyboard" />
<!--
SetKeyGrabs:
@modifiers: set of custom modifiers to grab
@ -43,7 +70,7 @@
Sets the current key grabs for the calling client, overriding
any previous call to this method. For grabbed key events, the
KeyEvent signal is still emitted, but normal key event handling
KeyEvent signal is emitted, and normal key event handling
is suppressed, including state changes for toggles like Caps Lock
and Num Lock.

View File

@ -63,6 +63,7 @@ typedef struct _MetaA11yKeyGrabber
char *bus_name;
guint bus_name_watcher_id;
gboolean grab_all;
gboolean watch_all;
GArray *modifiers;
GArray *keystrokes;
} MetaA11yKeyGrabber;
@ -209,6 +210,34 @@ handle_ungrab_keyboard (MetaDBusKeyboardMonitor *skeleton,
return G_DBUS_METHOD_INVOCATION_HANDLED;
}
static gboolean
handle_watch_keyboard (MetaDBusKeyboardMonitor *skeleton,
GDBusMethodInvocation *invocation,
MetaA11yManager *a11y_manager)
{
MetaA11yKeyGrabber *grabber;
grabber = ensure_key_grabber (a11y_manager, invocation);
grabber->watch_all = TRUE;
meta_dbus_keyboard_monitor_complete_watch_keyboard (skeleton, invocation);
return G_DBUS_METHOD_INVOCATION_HANDLED;
}
static gboolean
handle_unwatch_keyboard (MetaDBusKeyboardMonitor *skeleton,
GDBusMethodInvocation *invocation,
MetaA11yManager *a11y_manager)
{
MetaA11yKeyGrabber *grabber;
grabber = ensure_key_grabber (a11y_manager, invocation);
grabber->watch_all = FALSE;
meta_dbus_keyboard_monitor_complete_unwatch_keyboard (skeleton, invocation);
return G_DBUS_METHOD_INVOCATION_HANDLED;
}
static gboolean
handle_set_key_grabs (MetaDBusKeyboardMonitor *skeleton,
GDBusMethodInvocation *invocation,
@ -257,6 +286,10 @@ on_bus_acquired (GDBusConnection *connection,
G_CALLBACK (handle_grab_keyboard), manager);
g_signal_connect (manager->keyboard_monitor_skeleton, "handle-ungrab-keyboard",
G_CALLBACK (handle_ungrab_keyboard), manager);
g_signal_connect (manager->keyboard_monitor_skeleton, "handle-watch-keyboard",
G_CALLBACK (handle_watch_keyboard), manager);
g_signal_connect (manager->keyboard_monitor_skeleton, "handle-unwatch-keyboard",
G_CALLBACK (handle_unwatch_keyboard), manager);
g_signal_connect (manager->keyboard_monitor_skeleton, "handle-set-key-grabs",
G_CALLBACK (handle_set_key_grabs), manager);
@ -422,6 +455,18 @@ should_grab_keypress (MetaA11yManager *a11y_manager,
return FALSE;
}
static gboolean
should_watch_keypress (MetaA11yManager *a11y_manager,
MetaA11yKeyGrabber *grabber,
uint32_t keysym,
ClutterModifierType modifiers)
{
if (grabber->watch_all)
return TRUE;
return should_grab_keypress (a11y_manager, grabber, keysym, modifiers);
}
static gboolean
is_grabbed_modifier_key (MetaA11yManager *a11y_manager,
uint32_t keysym)
@ -481,7 +526,7 @@ meta_a11y_manager_notify_clients (MetaA11yManager *a11y_manager,
{
MetaA11yKeyGrabber *grabber = l->data;
if (should_grab_keypress (a11y_manager, grabber, keysym, state))
if (should_watch_keypress (a11y_manager, grabber, keysym, state))
{
notify_client (a11y_manager, grabber, released,
state, keysym, unichar, keycode);