Skip to content

feat(libei): remember the input capture permission across sessions - #515

Open
cantona wants to merge 2 commits into
feschber:mainfrom
cantona:libei-persist-capture
Open

cantona wants to merge 2 commits into
feschber:mainfrom
cantona:libei-persist-capture

Conversation

@cantona

@cantona cantona commented Sep 28, 2026

Copy link
Copy Markdown

What

Remember the InputCapture permission across sessions. When the portal offers InputCapture v2, create the session with CreateSession2 and call Start with persist_mode = ExplicitlyRevoked and the stored restore token. On v1, fall back to CreateSession as before.

  • The token lives in $XDG_STATE_HOME/lan-mouse/input-capture-restore-token (falling back to ~/.local/state; only absolute paths are used). It is written with mode 0600 through a per-process temp file and a rename, and the file work runs on spawn_blocking.
  • Tokens are single-use, so every Start replaces the stored one. The stored token is dropped when Start fails or answers without a replacement, because ashpd's errors cannot tell whether the portal saw the token.

Why draft

The v2 path is untested. No portal I have access to reports InputCapture v2. On GNOME 50 (xdg-desktop-portal 1.21.1, xdg-desktop-portal-gnome 50.0), the frontend exposes CreateSession2/Start, but the interface version is 1 and the GNOME backend implements no Start. So ashpd returns RequiresVersion(2, 1) and the fallback runs.

Testing

  • v1 fallback on GNOME 50: logs InputCapture portal is v1, persistence needs v2: permission cannot be remembered, and capture works as before.
  • Checks: cargo fmt --check, clippy -D warnings and test pass locally (workspace minus lan-mouse-gtk, whose system libraries I don't have).

Testing on a portal with InputCapture v2 would be very welcome.

Without a restore token the portal asks for consent each time the
session is created, so the capture dialog comes back after every
restart. Use CreateSession2 and Start with a persistent restore token
when the portal offers InputCapture v2, and fall back to CreateSession
on v1.

The token is single-use, so save the one each Start returns, next to
the RemoteDesktop token in $XDG_CACHE_HOME/lan-mouse and handled the
same way. Close the session when Start fails: ashpd's Session has no
Drop, so it would otherwise stay on the bus.
@feschber

Copy link
Copy Markdown
Owner

Your load and save token functions are overly complicated.
Please take a look at input-emulation/src/libei.rs.
XDG_CACHE_HOME is also the more appropriate location for this I think.

@cantona
cantona force-pushed the libei-persist-capture branch from c36592b to b3c1d9a Compare September 28, 2026 08:43
A restore token lets whoever holds it skip the portal's consent dialog,
but fs::write creates the file with the umask; the remote-desktop.token
on the machine this was tested on was 0664. Create both token files
0600, and tighten the mode of one written by an older version where the
filesystem allows it: a refused chmod only warns, since the file has
already been truncated and the token still has to be written.
@cantona
cantona force-pushed the libei-persist-capture branch 2 times, most recently from b3c1d9a to 44ec8de Compare September 28, 2026 09:08
@cantona

cantona commented Sep 28, 2026

Copy link
Copy Markdown
Author

Thanks, simplified. get_token_file_path / read_token / write_token now follow input-emulation/src/libei.rs, and the token lives in $XDG_CACHE_HOME/lan-mouse/input-capture.token, next to remote-desktop.token. Beyond the RemoteDesktop flow, it only:

  • closes the session when Start fails, since ashpd's Session has no Drop;
  • skips an empty token file;
  • logs the v1 fallback once, because the capture session is recreated on every barrier or device change.

I also added a separate commit that writes both token files with mode 0600. fs::write uses the umask, and my remote-desktop.token was 0664, readable by other local users, while the token lets its holder skip the consent dialog. Happy to drop it or move it to its own PR if you'd rather keep this one to InputCapture.

@cantona
cantona marked this pull request as ready for review September 28, 2026 09:20
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.

2 participants