202 lines
8.7 KiB
Markdown
202 lines
8.7 KiB
Markdown
# feresectl and IPC events
|
|
|
|
`feresectl` controls a running Ferese session. Run `feresectl --help` for commands
|
|
and `feresectl COMMAND --help` for arguments.
|
|
|
|
## Queries
|
|
|
|
Queries print plain text by default. Add `-j` or `--json` when passing results to
|
|
another program. The flag works before or after a subcommand.
|
|
|
|
```sh
|
|
feresectl outputs
|
|
feresectl windows -j
|
|
feresectl -j workspaces
|
|
feresectl focused-window
|
|
feresectl idle-inhibition
|
|
feresectl keybindings
|
|
feresectl session-state
|
|
feresectl output-profiles
|
|
feresectl theme get
|
|
feresectl xwayland status
|
|
feresectl media
|
|
feresectl activity list
|
|
```
|
|
|
|
`feresectl keybindings` lists the active binding mode's shortcuts. Outside a
|
|
mode it lists the configured default shortcuts. Escape is always available to
|
|
leave a mode; see [Binding modes](configuration/bindings.md#binding-modes).
|
|
|
|
The `get-*` spellings remain hidden aliases for the corresponding queries and
|
|
print a deprecation warning on stderr. They use the same output rules: scripts
|
|
that previously parsed their JSON must add `-j`. New scripts should use the
|
|
canonical names. The aliases will be removed in a later release.
|
|
|
|
Screenshots still write PNG bytes to stdout, including when `-j` is present:
|
|
|
|
```sh
|
|
feresectl screenshot > desktop.png
|
|
feresectl screenshot -g '0,0 800x600' > region.png
|
|
feresectl screenshot-window 7 > window.png
|
|
```
|
|
|
|
## Window focus
|
|
|
|
```sh
|
|
feresectl focus-floating
|
|
```
|
|
|
|
`focus-floating` focuses the most recently focused window in the opposite
|
|
tiled/floating layer on the active workspace. It does nothing when that layer
|
|
has no candidate. `toggle-floating` changes placement; `focus-floating` changes focus.
|
|
|
|
`feresectl move left|right|up|down` and `feresectl resize left|right|up|down`
|
|
also handle floating windows. Moves use 32 logical pixels. Resizing shrinks
|
|
width/height with left/up and grows them with right/down by 32 logical pixels,
|
|
subject to client size limits. Fullscreen and maximized floating windows ignore
|
|
these actions.
|
|
|
|
`toggle-column-tabbed` changes a scrolling column between stacked rows and tabs.
|
|
In either layout, `join-tab left|right|up|down` joins the focused window to a
|
|
neighbouring tab group. `next-tab` and `previous-tab` switch tabs, and `leave-tab`
|
|
splits the focused tab out. See [Tabbed windows](tabbed-windows.md)
|
|
for grouping behavior and shortcuts.
|
|
|
|
## Live Activities
|
|
|
|
Use `feresectl run --title "Tests" -- cargo test` to publish a command's lifetime,
|
|
or `feresectl activity start`, `update`, `end` and `cancel` to publish status from
|
|
an integration. The [Live Activities guide](activities.md) covers setup and
|
|
examples; the [publishing guide](development/activities.md#publisher-ownership-and-lifecycle) explains ownership,
|
|
leases and the `activity-publish`, `activity-get` and `activity-watch` commands.
|
|
|
|
`feresectl activity setup --config PATH` updates a local config for shell
|
|
activities and the panel item without connecting to a session. It preserves an
|
|
explicit `shell-hook #false`; the installer uses it during first-time user setup.
|
|
|
|
## Choose a session
|
|
|
|
Every feresectl IPC command, including theme commands and subscriptions, resolves
|
|
its target in this order:
|
|
|
|
1. `--socket PATH`
|
|
2. A nonempty `FERESE_SOCKET`
|
|
3. `$XDG_RUNTIME_DIR/ferese/control.sock`
|
|
|
|
```sh
|
|
feresectl --socket "$XDG_RUNTIME_DIR/ferese/instances/12345-abcdef/control.sock" outputs
|
|
FERESE_SOCKET="$XDG_RUNTIME_DIR/ferese/instances/12345-abcdef/control.sock" feresectl theme get -j
|
|
```
|
|
|
|
`--socket` selects an existing server; it does not create one or change where the
|
|
compositor listens. DRM uses `$XDG_RUNTIME_DIR/ferese/control.sock`. Nested
|
|
instances use `$XDG_RUNTIME_DIR/ferese/instances/<id>/control.sock`; copy the
|
|
actual path from the compositor's startup log. Each instance removes its own
|
|
socket and directory on normal shutdown. A forced kill can leave the directory
|
|
behind; later instances allocate a different one.
|
|
|
|
Clients launched by a nested compositor inherit its `FERESE_SOCKET`, so
|
|
`feresectl outputs` inside that session connects to that instance.
|
|
`autostart` launches desktop entries locally and does not use IPC.
|
|
|
|
## Connection lifetimes
|
|
|
|
The server permits 64 simultaneous connections. A new connection must begin its
|
|
first request within five seconds; each frame then has five seconds to finish.
|
|
Ordinary connections close after 30 idle seconds and blocked response writes
|
|
expire after two seconds. These bounds release slots held by stalled clients.
|
|
Accepted portal leases remain connected while idle, and pending long polls and
|
|
event subscriptions do not have the ordinary idle deadline.
|
|
|
|
## Follow changes
|
|
|
|
```sh
|
|
feresectl event-stream
|
|
feresectl --socket "$XDG_RUNTIME_DIR/ferese/instances/12345-abcdef/control.sock" event-stream
|
|
```
|
|
|
|
`event-stream` writes one JSON value per line and flushes each line. It always
|
|
uses JSON, so `-j` is optional. `theme subscribe` also keeps its newline-delimited
|
|
JSON output.
|
|
|
|
The first event is a `snapshot` containing outputs, workspaces, windows, focus,
|
|
config status, the logical theme, and lock state. Later events contain replacement
|
|
values for changed domains:
|
|
|
|
| Type | Payload field |
|
|
| --- | --- |
|
|
| `outputs_changed` | `outputs` |
|
|
| `workspaces_changed` | `workspaces` |
|
|
| `windows_changed` | `windows` |
|
|
| `focus_changed` | `focus` |
|
|
| `config_changed` | `config` |
|
|
| `theme_changed` | `theme` |
|
|
| `lock_changed` | `lock` |
|
|
|
|
For example:
|
|
|
|
```json
|
|
{"version":1,"generation":12,"last":true,"type":"focus_changed","focus":{"window":7,"output":1,"workspace":3}}
|
|
```
|
|
|
|
Event schema version 1 is defined in `ferese-ipc::events`, independently of the
|
|
command protocol version. A subscriber requests that version using the framed
|
|
`event-stream` command. The server sends a normal response acknowledging the
|
|
subscription, followed by framed events on the same connection. That connection
|
|
is then reserved for events.
|
|
|
|
Changes are sampled after an event-loop dispatch. Output reconciliation must
|
|
finish before a desktop generation is published. Events from the same dispatch
|
|
share a `generation`; only its final event has `last: true`. Consumers maintaining
|
|
a desktop model should apply the whole generation together. Intermediate changes
|
|
within a dispatch are coalesced, so this stream is not an audit log of every input
|
|
or mutation. Generation numbers may have gaps.
|
|
|
|
Window events describe identity, title, activation, workspace, floating state,
|
|
and fullscreen state. They omit visual geometry, animation frames, and client
|
|
damage. Theme events omit the presented crossfade state and its frame revisions.
|
|
Config revisions advance when a changed configuration is accepted; rejected
|
|
reloads leave that revision intact and report an error. Lock events distinguish
|
|
`unlocked`, `acquiring`, `locked`, and `orphaned`, and include display sleep state.
|
|
While locked, snapshots and replacement events redact windows, workspaces,
|
|
focus, and output workspace/focus fields. Unlocking restores those domains.
|
|
|
|
## Delivery limits
|
|
|
|
The compositor allows at most 16 event subscribers within its existing limit of
|
|
64 IPC connection workers. Each subscriber has a queue of at most 32 events.
|
|
Publishing uses non-blocking sends. A full or disconnected queue removes that
|
|
subscriber; socket writes happen on its worker with a two-second write timeout.
|
|
Idle disconnected streams are checked every 250 milliseconds.
|
|
|
|
Events are not replayed. An overflow can end a stream partway through a generation.
|
|
Discard any generation without `last: true`, reconnect, and replace local state
|
|
with the new initial snapshot. Socket authentication and the existing one-MiB
|
|
frame limit also apply to event streams.
|
|
|
|
When there are no subscribers, event publication does not build desktop
|
|
snapshots. With subscribers, it compares logical domain snapshots after each
|
|
dispatch. Ordinary damage, cursor movement, and redraw code do not publish events
|
|
directly.
|
|
|
|
### Pomodoro controls
|
|
|
|
The `pomodoro` command uses the activity schema version:
|
|
|
|
```json
|
|
{"version":1,"type":"command","id":1,"command":"pomodoro","args":{"version":1,"action":"start","session":null}}
|
|
```
|
|
|
|
Actions are `start`, `pause`, `resume`, `next`, `stop`, `reset` and `status`.
|
|
The result is the current `{id, timer}` record, or `null` when no session exists.
|
|
Activity snapshots include this record in `pomodoro` and its Timer presentation
|
|
in `activities`. Running timers carry a host-authoritative BOOTTIME `deadline`;
|
|
paused timers carry their exact `remaining_ms` and no deadline. The
|
|
`paused-countdown` activity value preserves that duration without ticking.
|
|
|
|
Popup controls send the displayed activity ID in `session`. The host rejects
|
|
it if a reset or restart replaced that session, so a delayed action can't stop
|
|
a new timer. CLI commands use `null` to address the current session. These
|
|
commands use the same authenticated, same-user socket as other activity calls
|
|
and are unavailable while the desktop is locked.
|