Expand description
X11/XShm capture loop, stripe dispatch, and per-stripe change detection.
X11 host capture: grab the root window into host memory as BGRA, composite the XFixes hardware
cursor and the watermark on the CPU, and feed each frame to pipeline::X11Pipeline, which owns
damage/stripe/encode. The grab goes through a shared-memory segment (XShm via x11rb) rather than
a plain GetImage for one reason: a full-screen frame is far too large to copy through the X
protocol socket every tick, so XShm has the server write the pixels straight into memory this
process already has mapped.
run_capture splits the work across two threads because grabbing the next frame and encoding
the previous one have no reason to wait on each other: the caller’s thread grabs frames and owns
the x11rb connection and the pool of shm surfaces, while a spawned encode thread owns the
pipeline::X11Pipeline (and thus the encoder) and runs the delivery callback, so the two overlap for
throughput. Frames hand off through a bounded FramePool that carries only a raw pointer and
geometry — never an X object, none of which is safe to share — so nothing X-related ever crosses
the thread boundary and the encoder never has to touch X. Multi-instance safety for the encoders
is handled inside them (e.g. the libx264 open/close lock); each capture owns its own private xcb
connection, so there is no shared X state to serialize here.
Modules§
- computer_
use - X11 backend for the Computer Use HTTP API: XTEST injection and one-shot root screenshots over a private x11rb connection, so the agent can drive an X session with no active capture and no shared state with any streaming capture thread (the X server itself serializes).
- cursor
- Out-of-band X11 cursor delivery, the X11 counterpart of the Wayland compositor’s cursor
callback: one process-wide monitor thread (the X pointer is global, however many captures
run) parks in
wait_for_eventon its own connection for XFixesDisplayCursorNotifyand hands each new cursor to the Python callback as(msg_type, png_bytes, hot_x, hot_y)— the same payload the Wayland backend sends, so a consumer needs one handler for both. Keeping the cursor out of the framebuffer means pointer motion over static content never dirties the damage hash or re-encodes video;capture_cursorcompositing stays available as the opt-in alternative.
Structs§
- Controls
- Cross-thread controls for a running capture: a bag of atomics (plus two mutex-guarded
payloads) the owning
ScreenCapturepyclass flips from the Python thread and the capture thread reads at the top of each iteration.
Functions§
- run_
capture - Run the X11 capture pipeline until
stopis set, splitting capture and encode across two threads that overlap for throughput.