* feat(text_injection): add RemoteDesktop portal injection backend
Wayland offers exactly one sanctioned key-injection path:
org.freedesktop.portal.RemoteDesktop's NotifyKeyboardKeysym. It reaches
native clients on compositors with no input-method-v2 bridge, works from
inside the Flatpak sandbox without /dev/uinput or a helper daemon, and
delivers keysyms so non-US layouts survive -- unlike ydotool's evdev
keycodes.
RemoteDesktopPortal is a synchronous client over a dedicated worker
thread holding a private bus connection and GLib context, which keeps
Request::Response delivery deterministic. Sessions are created lazily on
first use so startup probing only reads the interface version; v2 portal
sessions persist a restore token (mode 0600 under data_dir) so the
permission prompt appears once.
Backend selection now prefers the portal on Wayland: it is probed at
runtime ahead of ydotool/wtype/xdotool in autodetection, is pinnable via
VOCALINUX_FORCE_BACKEND=portal or text_injection.backend, and demotes to
the previous order on runtime failure. Flatpak still needs --device=all
for evdev hotkeys, but uinput is only a fallback path now.
Closes#750
* fix(text_injection): resolve Greptile findings on RemoteDesktop portal injection
- Move persist_mode/restore_token to SelectDevices options (portal v2
sends them there, not CreateSession); a bad token is ignored rather
than sinking the session, so drop the stale-token retry paths that
could issue a second Start after a user cancel
- Track delivered units on RemoteDesktopPortalError so Wayland
fallbacks retry only the undelivered tail instead of retyping the
prefix (text chars, backspace taps, shortcut steps)
- Give queued portal jobs a single deadline budget across
CreateSession/SelectDevices/Start waits; on submit timeout the job
is cancelled via a Gio.Cancellable plus abort checkpoints so the
worker cannot keep emitting keys after the caller gave up
- Close sessions whose Start never succeeded
- Release held shortcut modifiers on mid-step failure
- Skip the portal probe when an installed wtype/ydotool backend is
explicitly pinned
- Type annotations on the new signatures and touched tests
---------
Co-authored-by: Jatin K Malik <jatinkrmalik@gmail.com>