Skip to content

feat(compositor): org.gnome.Mutter.InputCapture for the InputCapture portal (#1040) - #1062

Open
hanthor wants to merge 1 commit into
mainfrom
lane/input-capture-1040
Open

hanthor wants to merge 1 commit into
mainfrom
lane/input-capture-1040

Conversation

@hanthor

@hanthor hanthor commented Nov 10, 2026

Copy link
Copy Markdown
Member

Closes part of #1040 (ledger row P-SY-13, added in #1052). Part of #577.

Follows mutter 51.0 meta-input-capture.c, meta-input-capture-session.c, org.gnome.Mutter.InputCapture.xml, and xdg-desktop-portal-gnome inputcapture.c. The real 51 XML is GetZones, AddBarrier(u, (iiii)), ClearBarriers, Enable, Disable, ConnectToEIS, Release(a{sv}), Close; signals Activated, Deactivated, ZonesChanged, Disabled, Closed.

  • Caller policy: only the authenticated installed portal (new Authority::admit_portal) creates sessions; session methods require the owner and are refused while locked; signals go to the owner only. Lock closes every session; the 100 ms revocation scan removes them on owner loss.
  • Barriers: validated exactly as mutter's check_barrier (order and messages); ids are the lowest free from 1.
  • Capture: relative motion crossing an enabled barrier outward emits Activated (barrier, activation id, crossing point); pointer/button/scroll/key input then goes to the session's EIS client (pointer + keyboard devices, reis) instead of clients. Ends on Release (optional warp), Disable, Close, monitor change, Super+Shift+Escape, lock, owner loss. Captured input still counts as activity.
  • Code: mutter/input_capture.rs (interface, state machine, router), mutter/capture_eis.rs (EIS worker), runtime/input_capture.rs (one hook in the DRM input handler, revoke_all in engage_lock); remote_eis.rs keymap memfd code shared.
  • Docs: new docs/input-capture.md; rows in docs/protocols.md and docs/security-model.md.

Recorded divergences (docs): Disabled is emitted when the compositor disables a session itself (mutter declares but never sends it); SupportedCapabilities = 3; a barrier on no monitor edge is refused with a message; keys held across capture start/stop release to where they were pressed; barriers trigger only on relative motion, not under a pointer lock. Not implemented: cursor hiding during capture, the capture-session clipboard, keymap updates during an EIS connection, tablets/absolute pointers crossing barriers, a configurable cancel shortcut.

Local checks (clean target): cargo fmt --all, cargo clippy --workspace --all-targets -D warnings, cargo test -p tuna-compositor --lib (1072 passed, incl. 13 input_capture::tests and 2 private-bus tests with a real reis receiver), --test introspect_shell_name --test runtime, scripts/tuna-test-strategy. Not run: the real portal with Input Leap/Deskflow on a hardware session (the hook is in the DRM input path; the nested backend does not capture).

…portal (#1040)

Serve mutter 51's InputCapture interface to the authenticated installed
portal: sessions with GetZones, AddBarrier (mutter's check_barrier rules
and messages), ClearBarriers, Enable/Disable, ConnectToEIS, Release with
an optional cursor position, and Close. Relative motion crossing an
enabled barrier activates capture: clients get no pointer, button,
scroll or key input, which goes to the session's EIS client instead,
until Release, Disable, Close, a monitor change, Super+Shift+Escape, lock
or owner loss. Never captures while locked.

Signed-off-by: James Reilly <jreilly1821@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant