Skip to main content

ScreenCapture

Struct ScreenCapture 

Source
pub struct ScreenCapture {
    pub(crate) id: u64,
    pub(crate) inner: Mutex<ScState>,
}

Fields§

§id: u64§inner: Mutex<ScState>

Implementations§

Source§

impl ScreenCapture

Source

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

Register this capture’s consumer of cursor images in the process-wide slots: the X11 cursor monitor’s, and the compositor’s where one runs, else the stash PENDING_CURSOR_CALLBACK that ensure_compositor applies at creation (the backend slot lock is held across the check so a concurrent creation cannot miss it). Both slots outlive the capture that set them, so they carry the latest live registration (CURSOR_REGISTRATIONS): None withdraws this capture’s own, releasing what it holds and restoring the one registered before it.

Source

pub(crate) fn hand_report(&self, report: ReferenceReport)

Hand what a client said of a frame to the capture: the X11 controls, drained ahead of the next encode, or the shared Wayland backend.

Source

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

Stop this capture: signal the capture thread, drop the live controls, and join.

The path forks on the backend. A Wayland capture only tells the shared compositor to stop when this instance still owns it — ownership is claimed-and-cleared atomically so a stale stop cannot tear down a capture another instance just started. An X11 capture joins its capture thread (which also joins the encode thread) and then its deliver thread, releasing the GIL first because the deliver thread runs the Python callback and holding the GIL across the joins would deadlock. A re-entrant stop arriving on the capture, encode, or deliver thread cannot join itself, so it detaches and lets the threads exit on the stop flag. An X11 capture still starting is only signaled: its start joins it and publishes nothing.

Source§

impl ScreenCapture

Source

pub(crate) fn report(&self) -> Option<Arc<StreamReport>>

The report of the capture this handle runs, whichever backend it is on.

Source§

impl ScreenCapture

Source

pub fn new() -> Self

Source

pub fn active_codec(&self) -> Result<Option<String>, Error>

The codec this capture streams, by name, once its pipeline has been built: the requested one, or the one the selection ladder demoted it to when no encoder could serve the request. None before the first frame or after a stop.

Source

pub fn stream_info(&self) -> Option<StreamInfo>

What this capture streams and how it got there, or None before a start and after a stop: backend (x11, wayland), capture (the path: NvFBC, DRI3, XShm, dmabuf, readback), zero_copy and the capture_reason a faster path was declined for, zero_copy_available (whether the display server offered the encoder a zero-copy path at all), encoder (NVENC, VAAPI, or the software library), hardware and the encoder_reason it is not, codec, fullcolor, striped, and for a hardware session its gpu, kernel driver, and encode_node. A Wayland capture adds how its compositor renders: renderer (gl, pixman), render_node, render_gpu, renderer_reason. The first read of a VA-API session brings a GL context up once to name its GPU, so a caller with an event loop reads this off it.

Source

pub fn stream_stats(&self) -> Option<StreamStats>

Cumulative counters of this capture since it started, or None without one: frames and bytes delivered, and the nanoseconds those frames spent encoding (encode_ns) and from capture to the end of the encode (pipeline_ns). A caller differences two reads; a restart begins again from zero. Beside them, the extremes since the previous read, which each read starts again: pipeline_min_ns and pipeline_max_ns, zero where no frame was timed, and frame_max_bytes, the largest frame.

Source

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

Source

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

Source

pub fn invalidate_reference( &self, frame_id: u16, withheld: bool, ) -> Result<(), Error>

A client lost frame frame_id, 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 of its predictions codes a keyframe instead. Non-blocking, like request_idr_frame.

Source

pub fn acknowledge_reference( &self, frame_id: u16, held: bool, ) -> Result<(), Error>

Every client holds frame frame_id, or where not held was sent it (and may yet lose it): a session keeping long-term references pins the newest anchor they all hold and predicts its anchors from a frame they were all sent, so each client recovers on its own from a loss of any depth, without a keyframe. Non-blocking, like invalidate_reference.

Source

pub fn update_video_bitrate(&self, kbps: i32) -> Result<(), Error>

Apply a live target-bitrate (kbps) change to the running capture.

On the X11 path the dirty flag is Release-published after the payload store, so the encode thread’s Acquire read can never observe the flag set against a stale bitrate.

Apply the rate (kbps) the path the stream crosses carries, as the transport measures it, which a still screen’s constant-rate cleanup may run at; 0 where the transport has no measure, which keeps the cleanup to the stream’s rate.

Source

pub fn update_framerate(&self, fps: f64) -> Result<(), Error>

Source

pub fn update_vbv_multiplier(&self, multiplier: f64) -> Result<(), Error>

Live CBR VBV change, as a multiple of one frame’s bit budget (<= 0 = policy default).

Source

pub fn update_capture_region( &self, x: i32, y: i32, width: i32, height: i32, ) -> Result<(), Error>

Move/resize the live X11 capture region (root-relative). The capture loop drains in-flight frames, re-targets its surfaces, and the encoder follows in place where it can (NVENC reconfigure / stripe re-derive) – no capture restart. width/ height <= 0 mean “to the root edge”. On Wayland the output IS the capture region: restart the capture with new dimensions instead (in-place there too).

Source

pub fn is_capturing(&self) -> bool

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 in one message.

Source

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

Source

pub fn set_keymap_overlay(&self, binds: Vec<(u32, u32)>) -> Result<(), Error>

Bind explicit (keycode, keysym) pairs onto the current base keymap in one swap; false when no backend runs or no base keymap is installed. See the backend method for the split of responsibility.

Source

pub fn set_app_wayland_display(&self, display: String)

Compositor apps run under (a nested labwc/kwin session pixelflux captures), the target for Computer-Use text injection and, under KWin, for relative pointer motion through its fake-input device; selkies resolves it and hands it over. Empty clears it. Stored process-wide since the CU server is per-process.

Source

pub fn type_text_wayland(&self, display: &str, text: &str) -> Result<(), Error>

Type text through display‘s zwp_virtual_keyboard_manager_v1 as a one-shot client: selkies’ text-injection path, targeting whichever compositor the apps live under (the nested session’s, or pixelflux’s own in a direct session). Blocking; releases the GIL for the duration. Raises [VirtualKeyboardUnavailable] when the compositor lacks the protocol.

Source

pub fn type_keysyms_wayland( &self, display: &str, keysyms: &[u32], ) -> Result<(), Error>

Tap keysyms in order through display‘s virtual keyboard, verbatim: the caller owns which keysym spells which character (selkies’ policy layer); this owns delivery. Same one-shot client and errors as type_text_wayland.

Source

pub fn set_app_output_scale( &self, display: &str, scale: f64, index: usize, ) -> Result<bool, Error>

Scale the app compositor’s index-th screen, so its applications draw larger while the capture keeps its full resolution. False when that compositor manages no outputs for clients (KWin), whose scale follows the capture output’s instead.

Source

pub fn set_app_screen_geometry( &self, display: &str, width: i32, height: i32, scale: f64, index: usize, ) -> Result<bool, Error>

Give the app compositor’s index-th screen this mode and scale in one configuration, so the session lays its desktop out once. Setting them separately exposes a geometry that never exists — the pre-connect mode at the new scale — and a client that does not lay out again keeps it. False = that compositor manages no outputs for clients: a nested KWin accepts a scale over its own output management and then ignores it, its screens taking their scale from the host window’s preferred fractional scale, which is the capture output’s.

Source

pub fn set_app_screen_layout( &self, display: &str, rects: Vec<(i32, i32, i32, i32)>, ) -> Result<usize, Error>

Lay the app compositor’s screens out at rects — (x, y, width, height) per screen in screen order — so the session arranges its desktop the way the capture outputs were placed rather than by its own default rule. A fallback ladder: zwlr_output_management_v1 first, then KWin’s kde_output_management_v2 (positions only there — a nested KWin screen’s size follows its host window). Returns how many were positioned; 0 = that compositor manages no outputs for clients.

Source

pub fn list_app_screens(&self, display: &str) -> Result<Vec<AppScreen>, Error>

The app compositor’s enabled screens as (name, x, y, width, height) in screen order, which is what it did with a layout and a mode rather than what it was asked for — the readback set_app_screen_geometry has no other way to be checked against. The same ladder as set_app_screen_layout (zwlr, then KWin’s output devices). Empty = that compositor manages no outputs for clients.

Source

pub fn app_screen_control_offered(&self, display: &str) -> Result<bool, Error>

Whether the app compositor serves KWin’s zkde_screencast_unstable_v1 virtual outputs – the rung selkies offers a second display on when the session serves no control socket. A registry read that touches no screen: whether the compositor registers the screen it grows is proven when a display asks for one (add_app_screen refuses one that does not).

Source

pub fn add_app_screen( &self, display: &str, name: &str, width: i32, height: i32, scale: f64, ) -> Result<(), Error>

Grow a screen named name on the app compositor, held open until remove_app_screen. The name is what list_app_screens reports and removal addresses; width/height/scale only seed the screen, whose size follows the capture output that adopts its host window.

Source

pub fn remove_app_screen(&self, name: &str) -> Result<bool, Error>

Remove a screen add_app_screen grew; the compositor’s own output-destroy path returns its windows to the primary. False when no such screen is held.

Source

pub fn hold_spare_app_screens( &self, display: &str, keep: usize, width: i32, height: i32, ) -> Result<usize, Error>

Hold the app compositor’s screens past the first keep at a small size, so a session that opened more screens than there are capture outputs does not lay its desktop out across one nobody sees. Returns how many were resized (0 = that compositor manages no outputs for clients).

Source

pub fn clipboard_types_app(&self, display: &str) -> Result<Vec<String>, Error>

Mimes the app compositor’s current selection offers (empty = nothing copied).

Source

pub fn clipboard_read_app( &self, display: &str, mime: &str, ) -> Result<Option<Vec<u8>>, Error>

The app compositor selection’s payload for mime, or None when nothing is copied or the selection does not offer that mime.

Source

pub fn clipboard_write_app( &self, display: &str, entries: Vec<(String, Vec<u8>)>, ) -> Result<(), Error>

Take the app compositor’s selection, serving entries (mime, bytes) to every paster from a background thread until another client copies.

Source

pub fn clipboard_served_app(&self, after: usize, timeout_s: f64) -> Vec<String>

The mimes the selection clipboard_write_app last took has served to pasters, in order, once it has served more than after of them or timeout_s has passed (at most a minute).

Source

pub fn clipboard_clear_app(&self, display: &str) -> Result<(), Error>

Drop the app compositor’s selection.

Source

pub fn clipboard_unwatch_app(&self, display: &str)

Stop the selection watch for display (no-op without one).

Source

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

The move’s number (pointer_location), or None without a running compositor.

Source

pub fn inject_relative_mouse_move( &self, dx: f64, dy: f64, ) -> Result<Option<u64>, Error>

The move’s number (pointer_location), or None without a running compositor.

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>

WaylandBackend.inject_finger_scroll; nothing without a running compositor.

Source

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

WaylandBackend.inject_finger_scroll_end; nothing without a running compositor.

Source

pub fn pointer_location(&self) -> Option<(f64, f64, f64, u64)>

Where the Wayland compositor’s pointer is, as (x, y, scale, motion) (WaylandBackend.pointer_location), or None without a running compositor or before its first pass. Under host capture the host’s cursor answers, None before its first cursor meta or where the host paints its cursor. An X11 session reads its pointer from the X server.

Source

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

Toggle compositing the cursor into captured frames (the alternative to the out-of-band cursor callback): the X11 grab re-reads the flag per frame, Wayland forwards to the compositor.

Source

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

Source

pub fn set_clipboard( &self, entries: Vec<(String, Vec<u8>)>, ) -> Result<(), Error>

Compositor-side clipboard offer: serve one payload per (mime, data) entry.

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; false when no backend runs or the layout fails to compile.

Source

pub fn get_keyboard_state(&self) -> Result<(Vec<u32>, u32), Error>

Seat keyboard readback: (pressed_keycodes, modifier_mask); empty when no backend runs.

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); None when no Wayland backend runs or the compositor did not answer in time (a timeout is distinct from a real answer so the caller treats it as unknown rather than “nothing to reconcile”). X11 has no compositor to read back and returns None.

Source

pub fn capture_state(&self, display_id: u32) -> (String, Option<String>)

Lifecycle of this capture as (state, last_error): state is "running", "failed", or "idle"; last_error gives the reason a start failed, or a caveat a live capture came up with (encoder fell back to CPU, host connect refused, a refused resize). The Wayland outcome is recorded by the compositor thread; the X11 outcome is the capture thread’s own exit error. display_id selects a Wayland output; X11 ignores it.

Source

pub fn create_output( &self, id: u32, width: i32, height: i32, x: i32, y: i32, scale: f64, ) -> Result<bool, Error>

Create an additional Wayland output (see WaylandBackend.create_output); false when no backend runs.

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 Wayland output (see WaylandBackend.create_view); false when no backend runs.

Source

pub fn resize_output( &self, id: u32, width: i32, height: i32, scale: f64, ) -> Result<bool, Error>

Resize a Wayland screen’s output in place (see WaylandBackend.resize_output); false when no backend runs.

Source

pub fn destroy_output(&self, id: u32) -> Result<bool, Error>

Destroy a secondary Wayland output; false when no backend runs.

Source

pub fn reposition_output(&self, id: u32, x: i32, y: i32) -> Result<bool, Error>

Move a Wayland output (the primary included) to layout offset (x, y); false when no backend runs or the id is unknown.

Source

pub fn set_cursor_size(&self, size: i32) -> Result<bool, Error>

Recreate the Wayland cursor theme at size pixels (named-cursor callbacks and the burned-in overlay); false when no backend runs or the size is non-positive.

Source

pub fn list_outputs(&self) -> Result<Vec<OutputDesc>, Error>

Every live Wayland output as (id, x, y, width, height, scale, capturing); empty when no backend runs.

Source

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

Display capacity (see WaylandBackend.output_capacity); -1 when no backend runs.

Source

pub fn move_window_to_output( &self, window_id: u32, output_id: u32, ) -> Result<bool, Error>

Move a window onto an output (fullscreened there); false when no backend runs.

Source

pub fn list_windows(&self) -> Result<Vec<WindowDesc>, Error>

Every mapped window as (window_id, title, app_id, output_id, waiting); empty when no backend runs.

Source

pub fn start_capture( &self, sink: Arc<dyn FrameSink>, settings: CaptureSettings, ) -> Result<(), Error>

Begin a capture delivering every frame to sink, on the backend settings select (CaptureSettings::wants_wayland): the shared compositor’s display display_id, or an X11 capture of this instance’s own. A start on a Wayland display this instance already captures reconfigures it in place; any other start stops what ran before.

Source

pub fn update_tunables(&self, settings: &CaptureSettings) -> Result<(), Error>

Retune the live per-frame knobs (LiveTunables::from_settings) of a running capture without restarting it.

Source

pub fn set_clipboard_sink( &self, sink: Arc<dyn ClipboardSink>, ) -> Result<(), Error>

Register the consumer of what client applications copy to the compositor’s clipboard.

Source

pub fn clipboard_watch_app( &self, display: &str, watch: Arc<dyn SelectionWatch>, ) -> Result<(), Error>

Report every selection change of the application compositor display to watch, from a thread of its own; a second watch on the same display replaces the first.

Trait Implementations§

Source§

impl Default for ScreenCapture

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Drop for ScreenCapture

Best-effort teardown: flag the capture thread to exit without joining.

Joining would need the GIL (the thread calls back into Python), which Drop cannot safely take, so this only sets the stop flag; the actual join is left to an explicit stop_capture or the atexit sweep.

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

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> NoneValue for T
where T: Default,

§

type NoneType = T

The type of the none-equivalent value that [NoneValue::null_value] produces.
§

fn null_value() -> T

The none-equivalent value.
§

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<R, P> ReadPrimitive<R> for P
where R: Read + ReadEndian<P>, P: Default,

Source§

fn read_from_little_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_little_endian().
Source§

fn read_from_big_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_big_endian().
Source§

fn read_from_native_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_native_endian().
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