Add Remote controller capture IPC to the host and both SDKs
remote.focus lets a controller keyboard-capture lease ask core to enter or leave remote focus; the reply acknowledges admission only. Core reports the actual state with remote.focus events and forwards routed transitions as remote.input events carrying the source keycode and, on fresh presses, a canonical key name. A full focus mailbox revokes the lease; revocation drains pending focus work. No native capture owner is attached yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
27017bef11
commit
2d5327adf4
10 files changed
+583
-10
No files matched your search
@@ -0,0 +1,50 @@
|
||||
# Remote controller keyboard capture IPC
|
||||
|
||||
Protocol 1.1 now carries controller keyboard capture between the reader and a
|
||||
Remote Tentacle. This document describes the wire contract and host checks;
|
||||
native capture is described in the following sections as it is implemented.
|
||||
|
||||
## Wire contract
|
||||
|
||||
Child-to-host `remote.focus` asks core to enter or leave remote focus:
|
||||
|
||||
```json
|
||||
{"lease":"0123456789abcdef0123456789abcdef","epoch":1,"sequence":3,"remote":true}
|
||||
```
|
||||
|
||||
All four fields are required. It needs the current process session's live
|
||||
controller lease with the separately approved `keyboard-capture` grant and
|
||||
shares the strictly increasing operation sequence. The reply `{}` acknowledges
|
||||
admission only. Without an attached reader capture owner it returns
|
||||
owner-unavailable. A full four-request mailbox revokes the lease, so a lost
|
||||
request to return to local focus can never leave capture active.
|
||||
|
||||
Host-to-child `remote.focus` events report the actual state, `focus` being
|
||||
`local` or `remote` and `reason` one of `requested`, `escape`, `local` (reader
|
||||
policy such as lock, handoff or reader UI) or `unavailable`. A child request
|
||||
never proves that capture is physically active.
|
||||
|
||||
Host-to-child `remote.input` events carry one normalized, routed transition:
|
||||
|
||||
```json
|
||||
{"code":38,"name":"a","pressed":true}
|
||||
{"code":38,"pressed":true,"repeat":true}
|
||||
{"code":38,"pressed":false}
|
||||
```
|
||||
|
||||
`code` is the source Xorg keycode (8–255), used only to pair repeats and
|
||||
releases. `name` is a canonical unshifted key name from
|
||||
`input.ValidRemoteKeyName` and is present only on a fresh press; releases and
|
||||
repeats omit it so a layout change cannot strand a key. A full event queue
|
||||
fails the session rather than losing a release.
|
||||
|
||||
Reader code attaches the mailbox with `Session.EnableRemoteCapture` and
|
||||
publishes with `PublishRemoteInput` and `PublishRemoteFocus`; both require the
|
||||
live controller `keyboard-capture` lease. Go exposes `RemoteCapturedKey`,
|
||||
`RemoteFocusRequest` and validators through `sdk/go/tentacle`; Python exposes
|
||||
`valid_remote_captured_key` and `valid_remote_focus_request` and validates both
|
||||
event kinds. Revocation drains pending focus work.
|
||||
|
||||
Go/Python SDK-process tests cover owner absence, admission and replay,
|
||||
role/grant denial, invalid parameters, saturation revocation, event delivery
|
||||
and rejection after revocation.
|
||||
Reference in new issue
Block a user