pub struct Compositor {
pub(crate) tx: Sender<ThreadCommand>,
pub(crate) pointer: Arc<PointerShare>,
pub(crate) motions: AtomicU64,
pub(crate) wake_tx: Sender<()>,
}Expand description
The handle to the one long-lived compositor thread. Because calloop, EGL/GBM, and the
Wayland display are all thread-affine and the compositor has to keep running to serve its
clients even between captures, the backend cannot be a passive object that starts work on
demand: constructing it spawns that thread and it stays up for the process lifetime. The
struct itself is nothing but the command-channel sender used to drive that thread across
the boundary; ensure_wayland_display hands out the process-wide one.
Fields§
§tx: Sender<ThreadCommand>§pointer: Arc<PointerShare>The compositor’s pointer, as its thread last published it (pointer_location).
motions: AtomicU64The number the last motion sent was given.
wake_tx: Sender<()>Wakes the calloop after each command send: the command channel itself is drained in place by the compositor thread (render tick and wake handler), not registered as its own source, so input never waits behind an in-flight render tick’s timer wakeup.
Implementations§
Source§impl Compositor
impl Compositor
pub(crate) fn send(&self, cmd: ThreadCommand) -> Result<(), String>
Sourcepub fn set_cursor_sink(
&self,
sink: Option<Arc<dyn CursorSink>>,
) -> Result<(), Error>
pub fn set_cursor_sink( &self, sink: Option<Arc<dyn CursorSink>>, ) -> Result<(), Error>
Register the consumer of cursor images; None withdraws it.
Sourcepub fn install_window_policy(
&self,
policy: Box<dyn WindowPolicy>,
) -> Result<(), Error>
pub fn install_window_policy( &self, policy: Box<dyn WindowPolicy>, ) -> Result<(), Error>
Install the window policy: from here on it decides placement, focus, stacking, frames, and bindings for every window.
Sourcepub fn start_xwayland(&self, notify: Option<Sender<u32>>) -> Result<(), Error>
pub fn start_xwayland(&self, notify: Option<Sender<u32>>) -> Result<(), Error>
Start Xwayland for X11 clients, managed with the Wayland ones; notify receives the
display number once the server is up.
Sourcepub fn set_clipboard_sink(
&self,
sink: Arc<dyn ClipboardSink>,
) -> Result<(), Error>
pub fn set_clipboard_sink( &self, sink: Arc<dyn ClipboardSink>, ) -> Result<(), Error>
Register the consumer of what client applications copy to the clipboard.
Source§impl Compositor
impl Compositor
Sourcepub fn new(
width: i32,
height: i32,
dri_node: String,
auto_gpu_selected: bool,
cursor_size: i32,
) -> Self
pub fn new( width: i32, height: i32, dri_node: String, auto_gpu_selected: bool, cursor_size: i32, ) -> Self
Construct the backend and spawn the long-lived compositor thread, handing it the strongest scheduling edge (nice -15) because it drives the calloop, input dispatch, the render loop, and — on the zero-copy path — the encode itself, all on this single thread, so any scheduling starvation here surfaces directly as dropped or late frames.
Sourcepub fn pointer_location(&self) -> Option<(f64, f64, f64, u64)>
pub fn pointer_location(&self) -> Option<(f64, f64, f64, u64)>
Where the compositor’s pointer is as of its thread’s last pass, as (x, y, scale, motion): physical union-layout coordinates (where inject_mouse_move puts it), the
scale of the output under it, by which a relative move’s pixels travel physically,
and the number of the last move applied (what inject_mouse_move and
inject_relative_mouse_move return), so a caller can tell which of its moves the
position includes. An app’s warp is included too, since the position is read back
rather than summed from what was injected. None before the first pass and, under host
capture, before its first cursor meta or where the host paints its cursor into the
frames. Never waits on the compositor.
Sourcepub fn start_capture(
&self,
sink: Arc<dyn FrameSink>,
settings: CaptureSettings,
) -> Result<(), Error>
pub fn start_capture( &self, sink: Arc<dyn FrameSink>, settings: CaptureSettings, ) -> Result<(), Error>
Begin a capture with the given frame callback and settings. The target display is
the settings’ display_id attribute (absent = 0, the primary); each display id runs
at most one capture, independent of every other display’s.
Issuing the start also clears the interpreter-teardown gate: starting from Python proves the interpreter is live again after a manual atexit sweep.
Sourcepub fn stop_capture(&self, display_id: u32) -> Result<(), Error>
pub fn stop_capture(&self, display_id: u32) -> Result<(), Error>
Stop the capture bound to display_id (default: the primary display).
Sourcepub fn create_output(
&self,
id: u32,
width: i32,
height: i32,
x: i32,
y: i32,
scale: f64,
) -> Result<bool, Error>
pub fn create_output( &self, id: u32, width: i32, height: i32, x: i32, y: i32, scale: f64, ) -> Result<bool, Error>
Create an additional output (WxH physical pixels at fractional scale) mapped into
the layout at offset (x, y); id is the display key used by every per-display API.
False when the id is taken, the geometry/scale is invalid, the rectangle overlaps a
live output, or the GPU render target cannot be allocated. Capture reconfigures
(start_capture on an existing output) resize without this validation, so a
multi-step relayout must stay overlap-free at every step by caller ordering.
Sourcepub fn create_view(
&self,
id: u32,
owner: u32,
x: i32,
y: i32,
width: i32,
height: i32,
) -> Result<bool, Error>
pub fn create_view( &self, id: u32, owner: u32, x: i32, y: i32, width: i32, height: i32, ) -> Result<bool, Error>
Add a display over a rectangle of an existing output, capturing that rectangle without publishing a screen of its own.
The session then sees one screen where the client sees several, which is what a
window drag needs: a pointer grab stays inside the one surface as it crosses from
one display to the next, instead of stopping at the edge of the screen it started
on. x and y are relative to owner’s output. False when the id is taken, the
owner is unknown or itself a view, or the rectangle leaves the owner’s output.
Sourcepub fn resize_output(
&self,
id: u32,
width: i32,
height: i32,
scale: f64,
) -> Result<bool, Error>
pub fn resize_output( &self, id: u32, width: i32, height: i32, scale: f64, ) -> Result<bool, Error>
Resize a screen’s output in place, keeping its position: the desk the displays cut out of it are laid over. False for a view, an unknown id, or a size that would leave one of the screen’s views outside it.
Sourcepub fn destroy_output(&self, id: u32) -> Result<bool, Error>
pub fn destroy_output(&self, id: u32) -> Result<bool, Error>
Destroy a secondary output: its capture ends cleanly and its windows relocate to the primary output. False for the primary (id 0) or an unknown id.
Sourcepub fn reposition_output(&self, id: u32, x: i32, y: i32) -> Result<bool, Error>
pub fn reposition_output(&self, id: u32, x: i32, y: i32) -> Result<bool, Error>
Move an existing output (the primary, id 0, included) to layout offset (x, y);
its windows, absolute input injection, and cursor compositing follow. False for an
unknown id or a destination overlapping a live output. Capture reconfigures
(start_capture on an existing output) resize without this validation, so a
multi-step relayout must stay overlap-free at every step by caller ordering.
Sourcepub fn list_outputs(&self) -> Result<Vec<OutputDesc>, Error>
pub fn list_outputs(&self) -> Result<Vec<OutputDesc>, Error>
Every live output as (id, x, y, width, height, scale, capturing) — width/height in
physical pixels, (x, y) the layout offset.
Sourcepub fn output_capacity(&self) -> Result<i64, Error>
pub fn output_capacity(&self) -> Result<i64, Error>
How many displays this backend can back with real content: -1 when self-compositing (outputs are created on demand, no fixed bound), otherwise the host compositor’s output count. Host-capture mode reports -1 until the first capture start establishes the host session; 0 when the backend is unresponsive.
Sourcepub fn move_window_to_output(
&self,
window_id: u32,
output_id: u32,
) -> Result<bool, Error>
pub fn move_window_to_output( &self, window_id: u32, output_id: u32, ) -> Result<bool, Error>
Move the window with the given id onto output output_id, fullscreened at that
output’s logical size. False for an unknown window or output id.
Sourcepub fn list_windows(&self) -> Result<Vec<WindowDesc>, Error>
pub fn list_windows(&self) -> Result<Vec<WindowDesc>, Error>
Every mapped window as (window_id, title, app_id, output_id, waiting). A waiting
window is tagged for that output but mapped clear of every one of them, holding its
size until an output exists for it — a nested session’s spare screens.
Sourcepub fn desktop_view(&self) -> Result<Option<DesktopView>, Error>
pub fn desktop_view(&self) -> Result<Option<DesktopView>, Error>
The desktop as the installed window policy holds it: every window’s place, state, and
stacking. None with no policy installed, or where the compositor does not answer.
Sourcepub fn window_request(
&self,
id: WindowId,
request: Request,
) -> Result<bool, Error>
pub fn window_request( &self, id: WindowId, request: Request, ) -> Result<bool, Error>
Ask the installed window policy to act on a window (activate, close, minimize, and the like), as a taskbar asks. False with no policy installed, for a window the policy has not placed, or where the compositor does not answer; the policy decides what becomes of the request.
Sourcepub fn set_cursor_size(&self, size: i32) -> Result<bool, Error>
pub fn set_cursor_size(&self, size: i32) -> Result<bool, Error>
Recreate the cursor theme at size pixels — no restart: subsequent named-cursor
callbacks and the burned-in cursor overlay render at the new size. False for a
non-positive size.
Sourcepub fn set_clipboard(
&self,
entries: Vec<(String, Vec<u8>)>,
) -> Result<(), Error>
pub fn set_clipboard( &self, entries: Vec<(String, Vec<u8>)>, ) -> Result<(), Error>
Compositor-side clipboard offer: serve one payload per (mime, data) entry, so a
client pasting rich text takes the markup and one pasting into a plain field takes
the text the source itself wrote, instead of both taking whichever flavor was
picked for them.
pub fn inject_key(&self, scancode: u32, state: u32) -> Result<(), Error>
Sourcepub fn inject_keys(&self, events: Vec<(u32, u32)>) -> Result<(), Error>
pub fn inject_keys(&self, events: Vec<(u32, u32)>) -> Result<(), Error>
Inject an ordered run of (keycode, state) events as one message, so a paste
costs one channel send and one wake instead of one per event.
Sourcepub fn set_keymap_overlay(&self, binds: Vec<(u32, u32)>) -> Result<(), Error>
pub fn set_keymap_overlay(&self, binds: Vec<(u32, u32)>) -> Result<(), Error>
Swap the seat keyboard’s xkb keymap (XKB_KEYMAP_FORMAT_TEXT_V1 text). The caller
owns keysym-to-keycode policy: define keycodes here, then press them via
inject_key. Ordered with key events on the one compositor channel.
Bind explicit (keycode, keysym) pairs onto the current base keymap in ONE swap.
The caller owns the assignment — which keysym goes to which keycode, and when to recycle one — because that tracks layouts and user reports. This end only assembles the xkb text and delivers it, reusing the installed base rather than recompiling a re-supplied one. False when no base keymap is installed yet.
pub fn set_keymap_string(&self, text: String) -> Result<(), Error>
Sourcepub fn get_xkb_keymap_string(&self) -> Result<String, Error>
pub fn get_xkb_keymap_string(&self) -> Result<String, Error>
Return the active xkb keymap as an XKB_KEYMAP_FORMAT_TEXT_V1 string so a consumer can build a reverse keysym->keycode map from the identical keymap.
The GIL is released while awaiting the reply, because the Wayland thread can call back into Python and would otherwise deadlock; the wait is bounded so a stall cannot hang the caller, and an empty string is returned when the keymap cannot be read in time.
Sourcepub fn inject_mouse_move(&self, x: f64, y: f64) -> Result<u64, Error>
pub fn inject_mouse_move(&self, x: f64, y: f64) -> Result<u64, Error>
Move the pointer to a point in physical union-layout coordinates. Returns the
move’s number (pointer_location).
Sourcepub fn inject_relative_mouse_move(&self, dx: f64, dy: f64) -> Result<u64, Error>
pub fn inject_relative_mouse_move(&self, dx: f64, dy: f64) -> Result<u64, Error>
Move the pointer by a delta. On the seat this is an absolute move plus a
zwp_relative_pointer_v1 event; a nested KWin session, which forwards no
delta from its host seat, receives it through its org_kde_kwin_fake_input
device on the app compositor socket named by set_app_wayland_display. Returns the
move’s number (pointer_location).
pub fn inject_mouse_scroll(&self, x: f64, y: f64) -> Result<(), Error>
Sourcepub fn inject_finger_scroll(&self, dx: f64, dy: f64) -> Result<(), Error>
pub fn inject_finger_scroll(&self, dx: f64, dy: f64) -> Result<(), Error>
Scroll by a finger’s travel of (dx, dy) physical pixels, the way a touchpad does:
fractional, with no wheel steps, until inject_finger_scroll_end.
Sourcepub fn inject_finger_scroll_end(&self) -> Result<(), Error>
pub fn inject_finger_scroll_end(&self) -> Result<(), Error>
End a finger’s scroll: the axis stop a toolkit starts its kinetic scroll on.
pub fn set_cursor_rendering(&self, enabled: bool) -> Result<(), Error>
Sourcepub fn request_idr_frame(&self, display_id: u32) -> Result<(), Error>
pub fn request_idr_frame(&self, display_id: u32) -> Result<(), Error>
Forces an IDR/keyframe on the next captured frame so a (re)connecting client or a decoder reset can resume immediately. With the default infinite GOP this is the only recovery path, so every consumer that can lose decoder state must call it. No-op cost on the JPEG/software path (keyframes are N/A).
Sourcepub fn invalidate_reference(
&self,
frame_id: u16,
display_id: u32,
withheld: bool,
) -> Result<(), Error>
pub fn invalidate_reference( &self, frame_id: u16, display_id: u32, withheld: bool, ) -> Result<(), Error>
A client lost frame frame_id of the given display’s capture, or its sender withheld it to
hold the stream to a rate (withheld): the frames after it stop predicting from it, so the
next one decodes there without a keyframe. An encoder that cannot leave a frame out codes a
keyframe instead.
Sourcepub fn acknowledge_reference(
&self,
frame_id: u16,
display_id: u32,
held: bool,
) -> Result<(), Error>
pub fn acknowledge_reference( &self, frame_id: u16, display_id: u32, held: bool, ) -> Result<(), Error>
Every client holds frame frame_id of one display’s capture, or where not held was
sent it, so a session keeping long-term references pins the newest anchor they all hold
and predicts its anchors from a frame they were all sent: each client recovers on its own
from a loss of any depth, without a keyframe.
Sourcepub fn update_rate(
&self,
bitrate_kbps: Option<i32>,
vbv_multiplier: Option<f64>,
fps: Option<f64>,
display_id: u32,
) -> Result<(), Error>
pub fn update_rate( &self, bitrate_kbps: Option<i32>, vbv_multiplier: Option<f64>, fps: Option<f64>, display_id: u32, ) -> Result<(), Error>
Apply a live bitrate (kbps) / VBV (kb) / framerate change to the given display’s running capture.
Sourcepub fn set_xkb_layout(
&self,
layout: String,
variant: String,
options: String,
model: String,
rules: String,
) -> Result<bool, Error>
pub fn set_xkb_layout( &self, layout: String, variant: String, options: String, model: String, rules: String, ) -> Result<bool, Error>
Set the seat’s BASE xkb layout from RMLVO names at runtime (empty strings select the xkbcommon defaults). Returns whether the layout compiled and was applied; overlay binds rebuild on top with their keycodes unchanged.
Sourcepub fn get_keyboard_state(&self) -> Result<(Vec<u32>, u32), Error>
pub fn get_keyboard_state(&self) -> Result<(Vec<u32>, u32), Error>
Debug/verification readback of the seat keyboard: (pressed_keycodes, modifier_mask)
with mask bits 1 ctrl, 2 shift, 4 alt, 8 logo, 16 caps, 32 num, 64 altgr, 128 level5.
Sourcepub fn get_realized_geometry(
&self,
display_id: u32,
) -> Result<Option<(i32, i32, f64)>, Error>
pub fn get_realized_geometry( &self, display_id: u32, ) -> Result<Option<(i32, i32, f64)>, Error>
The capture geometry actually live on the given display: (width, height, scale) in
physical pixels, or None when the compositor did not answer in time. Reflects any
degrade a start_capture performed (H.264 even-masking, GBM allocation failure keeping
the previous mode, a host that kept its own mode), and the command channel is FIFO, so
calling this after start_capture returns what that start realized. A host-capture
start answers once the host has ruled on the requested mode (the compositor thread
keeps serving input meanwhile), so a slow-but-live start reads its real size instead
of being reported as a timeout; the None a genuine timeout returns lets the caller
treat the geometry as unknown, not as “nothing to reconcile”, which a (0, 0, 0.0)
sentinel could not.
Sourcepub fn capture_state(&self, display_id: u32) -> (String, Option<String>)
pub fn capture_state(&self, display_id: u32) -> (String, Option<String>)
Lifecycle of display_id’s capture as (state, last_error): state is "running"
(pipeline live), "failed" (start left no live pipeline), or "idle" (never started
/ stopped clean); last_error is the reason a start failed, or a caveat a live
capture came up with (host connect refused -> local compositing, a hardware encoder
that fell back to CPU, a refused resize). Read straight from the recorded outcome, so
pair it with a prior get_realized_geometry when the ordering after a start matters.
Source§impl Compositor
impl Compositor
Sourcepub fn update_tunables(
&self,
display_id: u32,
t: LiveTunables,
) -> Result<(), Error>
pub fn update_tunables( &self, display_id: u32, t: LiveTunables, ) -> Result<(), Error>
Retune the live per-frame knobs of display_id’s capture without restarting it.
Auto Trait Implementations§
impl !Freeze for Compositor
impl RefUnwindSafe for Compositor
impl Send for Compositor
impl Sync for Compositor
impl Unpin for Compositor
impl UnsafeUnpin for Compositor
impl UnwindSafe for Compositor
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> DowncastSync for T
impl<T> DowncastSync for T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more