Handling Orca shortcuts in Mutter
Writing this issue to give some shape to the problems around handling Orca shortcuts, and discuss possible ways ahead.
Currently, Orca offers a wide variety of actions mappable to keyboard shortcuts, that can be changed individually, and 2 pre-made layouts (i.e. shortcut mappings), optimized for keyboards without a numeric keypad ("laptop" layout), and keyboards with one ("desktop" layout). A major difference in those layouts is the "Orca modifier" across the predefined shortcut mappings, it is the CapsLock key for the laptop layout, and the Keypad Insert key for the desktop layout.
These keys chosen as the Orca modifier have the trouble that they must doubly act as modifiers, and preserve their standalone actions. Currently Orca requires users to press the key twice to fallback to their original action. Handling these keys as modifiers have effect all the way down, e.g. the CapsLock should not toggle, its LED should stay off, ...
But not every key can be neatly used as a modifier, at least not according to the xkbcommon library underneath. To a large extent, we let it drive our keyboard state, by feeding it the key events that happen (meta_seat_impl_notify_key_in_impl()
) and asking for the outcome (e.g. updating leds at meta_seat_impl_sync_leds_in_impl()
, or getting the current pressed/locked/latched modifiers). Handling these two keys as modifiers brings in the need for two entirely disconnected pieces of work:
- For CapsLock, we already have a foot in, since it is naturally a modifier (albeit one that gets locked). In order to let it behave as a pure-modifier, we have to counter that "locked" nature either by adding our own logic on top of the state tracked by
xkb_state
(i.e. undoing the state change after the fact, throughxkb_state_update_mask()
). Since this low level handling of keymap levels (e.g. shift) and LEDs is entirely disconnected from shortcut handling (/src/core/keybindings.c
is a consumer of events emitted based on the former), this precludes any special handling that only applies with Orca set up, e.g. "press twice for CapsLock". - For the Insert key, we would require xkbcommon to consider it a modifier at all, first. We definitely cannot do that for random keys, so the a "plausibly working" hack I could think of would be to rewrite the current keymap to remap the Insert key as an actual modifier, and use that modifier in place of the Insert key in shortcut handling. The other option is a complete rewrite of the shortcut machinery, so it doesn't depend on what xkbcommon deems "modifiers", at this point it is very clear that we are actively working against xkbcommon instead of having it work for us.
These are pretty independent pieces of work, and both are necessary if we wanted to support Orca shortcuts as they currently exist and behave. I have rather strong feelings against keymap rewrites for Insert (or any random key) acting as a modifiers, since that treads into i18n territory, and IBus, and custom keymaps, ... Feels like a deep rabbit hole. OTOH, CapsLock (or *Lock) gaining modifier-only state handling sounds like a more natural fit, we might even argue xkbcommon should make the latter easier out of the box.
IMO, we'd have an easier time if Orca could make some concessions in shortcut handling:
- Change the options for Orca modifier keys so we just have to adopt one "solution". E.g. switching from Insert to Numlock makes Mutter able to generalize it together with the CapsLock case, while still using an uncommon key in the numeric keypad.
- Dropping the "press Orca modifier twice to use the regular key" and making these keys usable as shortcut modifiers without interfering with regular usage. Or this was maybe a concession wrt X11 already?
If those are possible, a (overly optimistic) roadmap could be:
- Making the low-level state/led handling in
src/backends/native
friendly to*Lock
keys being used as modifiers: Delaying locked state change until key release, as long as no other keys were pressed in between (i.e. it was used in a keycombo, handled or not) - Making the high-level shortcut machinery observe *Lock when parsing shortcut strings (e.g.
<CapsLock>a
). - Adding the a11y/shortcut portal handling bits
- Switching Orca desktop layout to use NumLock as Orca modifier.
CC @joanmarie @tait @jadahl (probably I miss others). I'd be interested to know if this is a feasible path ahead.