Skip to main content

Compositor

Struct Compositor 

Source
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: AtomicU64

The 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

Source

pub(crate) fn send(&self, cmd: ThreadCommand) -> Result<(), String>

Source

pub fn set_cursor_sink( &self, sink: Option<Arc<dyn CursorSink>>, ) -> Result<(), Error>

Register the consumer of cursor images; None withdraws it.

Source

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.

Source

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.

Source

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

Source

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.

Source

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.

Source

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.

Source

pub fn stop_capture(&self, display_id: u32) -> Result<(), Error>

Stop the capture bound to display_id (default: the primary display).

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn inject_key(&self, scancode: u32, state: u32) -> Result<(), Error>

Source

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.

Source

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.

Source

pub fn set_keymap_string(&self, text: String) -> Result<(), Error>

Source

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.

Source

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).

Source

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).

Source

pub fn inject_mouse_button(&self, btn: u32, state: u32) -> Result<(), Error>

Source

pub fn inject_mouse_scroll(&self, x: f64, y: f64) -> Result<(), Error>

Source

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.

Source

pub fn inject_finger_scroll_end(&self) -> Result<(), Error>

End a finger’s scroll: the axis stop a toolkit starts its kinetic scroll on.

Source

pub fn set_cursor_rendering(&self, enabled: bool) -> Result<(), Error>

Source

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).

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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

Source

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§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<T> Downcast for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert 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>

Convert 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)

Convert &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)

Convert &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
where T: Any + Send + Sync,

§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync> ⓘ

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts 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
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more