Expand description
Holding devices across a VT switch.
A compositor that owns the display cannot simply open /dev/dri/card0 and
keep it: switching to another virtual terminal has to take the display away
and give it back. A seat – logind, seatd, or a bare-root fallback – is
what arbitrates that, handing out descriptors it can revoke.
What arrives from the seat is two events. Paused: stop touching every
descriptor immediately, because the ioctls will start failing. Resumed:
here are fresh descriptors, and every per-descriptor kernel object you had
– framebuffers, property blobs, client caps, GEM handles – is gone.
drmkit_cursor::Paused is the shape that pairs with this on the other
side.
§Why the backend is a trait
Because a seat cannot be opened on a machine that has no session. Over SSH, in a container, on a CI runner, logind says the session is busy, seatd is not running, and the builtin backend wants root and a TTY. That is most places this code will be built.
So the sequencing – which devices are held, what happens to them across a
pause, when the pause is acknowledged, what a caller is allowed to do while
inactive – lives in Session over a Backend, and is tested against
a fake. The libseat binding is a thin adapter behind the libseat feature,
and libseat’s own diagnostics arrive through drmkit-log, tagged
[libseat], at error level.
§Not here yet
Two things the reference has and this does not.
TakeDeviceOpts::preserve_fd_across_resume asks the seat to hand back the
same descriptor rather than a fresh one, on the grounds that the
capability-revoking backends leave it valid. Plausible, and it saves a
reopen per device per switch, but it is an optimization over a path that is
already correct – and getting it wrong means scanning out through a
descriptor the kernel has stopped honoring, on a machine none of the CI
lanes resemble. It waits for a device to be proved on.
Seat::input_opener routes libinput’s privileged device opens through the
same seat, so input descriptors get the revocable lifetime the DRM one has.
Both halves it needs now exist: this crate opens devices through a seat,
and drmkit_input::Seat::open_with takes any LibinputInterface the caller
supplies. What is missing is the piece between them — an implementation of
that trait backed by a Session, so an input descriptor is revoked and
reissued on a VT switch the way the DRM one is. Until it exists a caller
passing their own opener gets input descriptors with an ordinary lifetime,
which works and is not what the seat is for.
Structs§
- Device
Id - A seat’s handle for one open device.
- Libseat
Backend libseat - A session backed by libseat.
- Session
- Devices held across VT switches.
- Taken
Device - A device this session is holding.
Enums§
- RawEvent
- What a seat says, before the session has made sense of it.
- Session
Error - What can go wrong holding a session.
- Session
Event - What a caller needs to act on.
Constants§
- DEFAULT_
ENABLE_ TIMEOUT libseat - How long
LibseatBackend::openwaits for the seat to activate.
Traits§
- Backend
- What a seat has to be able to do.