Selkies

DataStreamingServer

The websockets-transport streaming service.

Owns the data WebSocket plane end to end: connection auth and roles, input/settings/control dispatch, per-display pixelflux captures with their per-client _VideoRelay fan-out, ACK-driven backpressure, the shared pcmflux audio broadcast (with its all-clients Opus+RED gate), microphone forwarding, stats collectors, and the display layout/reconfiguration engine (X11 xrandr monitors or Wayland compositor outputs).

Concurrency contracts: _reconfigure_lock serializes reconfiguration (with _reconfigure_pending coalescing requests that arrive during a hold); _audio_lock serializes the audio pipeline's start, stop and re-gating, taken inside _reconfigure_lock where a path holds both and never around it, so a sound server slow to answer holds up the audio alone (pcmflux's start waits up to its handshake window while its connect retries run); _video_capture_lock serializes per-display capture start/stop underneath the reconfigure lock. Native capture objects are persistent per display so restarts keep the encoder backend warm.

Attributes

attributedata_wsOptional[web.WebSocketResponse]
= None
attributeclientsset[web.WebSocketResponse]
= set()

Every connected data socket, the audio and control fan-out set.

attributeapp
= None
attributecli_args
= settings
attributeis_secure_mode
= False
attributeinput_handler
= None
attribute_tasks_to_run
= []
attributeRECONNECT_DEBOUNCE_MS
= 500
attributeRECONNECT_GRACE_S
= 3.0

How long a disconnected display's entry (and its running capture) waits for the page to come back before teardown.

attributeHIDDEN_OWNER_HANDOFF_S
= 1.0

How long the primary's owner stays hidden before a visible page beside it owns the display (_settle_display_owner); a reloading page closes its socket sooner.

attributeIDLE_OWNER_HANDOFF_S
= 3.0

How long the primary's owner goes without its user's input before a page beside it of the same credential that its user acts through owns the display (_take_display_in_use).

attribute_display_teardown_tasks
= set()
attributeMAX_RECENT_CLIENTS
= 1000
attributelast_connection_times
= OrderedDict()
attribute_latest_client_render_fps
= 0.0
attribute_last_time_client_ok
= 0.0
attribute_client_acknowledged_frame_id
= -1
attribute_last_client_acknowledged_frame_id_update_time
= 0.0
attribute_previous_ack_id_for_stall_check
= -1
attribute_previous_sent_id_for_stall_check
= -1
attribute_sent_frames_log
= deque()
attributerc_mode
= RateControlMode.CRF
attributeconfig_gate
= asyncio.Event()
attributeshutdown_event
= asyncio.Event()
attribute_shutdown_called
= False
attributesupervisor
= supervisor
attribute_initial_video_crf
= get_initial_value('video_crf')
attributevideo_crf
= self._initial_video_crf
attribute_initial_video_fullcolor
= get_initial_value('video_fullcolor')
attributevideo_fullcolor
= self._initial_video_fullcolor
attribute_initial_video_10bit
= get_initial_value('video_10bit')
attributevideo_10bit
= self._initial_video_10bit
attribute_initial_video_streaming_mode
= get_initial_value('video_streaming_mode')
attributevideo_streaming_mode
= self._initial_video_streaming_mode
attributecapture_cursor
= False
attribute_initial_jpeg_quality
= get_initial_value('jpeg_quality')
attributejpeg_quality
= self._initial_jpeg_quality
attribute_initial_paint_over_jpeg_quality
= get_initial_value('paint_over_jpeg_quality')
attributepaint_over_jpeg_quality
= self._initial_paint_over_jpeg_quality
attribute_initial_video_paintover_crf
= get_initial_value('video_paintover_crf')
attributevideo_paintover_crf
= self._initial_video_paintover_crf
attribute_initial_video_paintover_burst_frames
= get_initial_value('video_paintover_burst_frames')
attributevideo_paintover_burst_frames
= self._initial_video_paintover_burst_frames
attribute_initial_use_cpu
= get_initial_value('use_cpu')
attributeuse_cpu
= self._initial_use_cpu
attribute_initial_cpu_encode_threading
= get_initial_value('cpu_encode_threading')
attributecpu_encode_threading
= self._initial_cpu_encode_threading
attribute_cpu_encode_threading_provided
= bool(app_settings.was_provided('cpu_encode_threading'))
attribute_initial_use_paint_over_quality
= get_initial_value('use_paint_over_quality')
attributeuse_paint_over_quality
= self._initial_use_paint_over_quality
attribute_initial_video_bitrate
= get_initial_value('video_bitrate')
attributevideo_bitrate
= self._initial_video_bitrate
attribute_resource_monitorOptional[resource_stats.ResourceMonitor]
= None

The one sampler of CPU, memory, and GPU (resource_stats.ResourceMonitor), started with the first connection and stopped with the last; its tick sends stream_stats and it samples only while _stats_subscribers is not empty.

attribute_stats_subscribersSet[web.WebSocketResponse]
= set()

The controller sockets whose page has its stats open (the _stats verb, stream_stats module docstring).

attribute_stats_sendingSet[web.WebSocketResponse]
= set()
attribute_stream_watchesDict[str, stream_stats.StreamWatch]
= {}

Display id to the stream_stats.StreamWatch following that display's capture.

attributeuinput_mouse_socket
= UINPUT_MOUSE_SOCKET
attributejs_socket_path
= socket_dir(settings.js_socket_path)
attributeenable_clipboard
= settings.enable_clipboard
attributeenable_binary_clipboard
= self.cli_args.enable_binary_clipboard[0]
attributeenable_cursors
= ENABLE_CURSORS
attributecursor_size
= CURSOR_SIZE
attributecursor_scale
= 1.0
attributecursor_debug
= DEBUG_CURSORS
attribute_last_adjustment_timestamp
= 0.0
attributeclient_settings_received
= asyncio.Event()
attribute_reconfigure_lock
= asyncio.Lock()
attribute_audio_lock
= asyncio.Lock()
attribute_video_capture_lock
= asyncio.Lock()
attribute_is_reconfiguring
= False
attribute_reconfigure_pending
= False
attributelast_start_video_request_times
= {}
attribute_repair_timesDict[Tuple[Any, str], float]
= {}
attributevideo_paused_clients
= set()

Sockets that sent STOP_VIDEO (hidden tab) — any shared client, not viewers alone — excluded from the primary video fan-out until their next START_VIDEO while capture, control, cursor, and audio keep running.

attribute_beside_audioDict[Any, bool]
= {}
attribute_session_audioOptional[bool]
= None
attribute_page_hidden_atDict[Any, Optional[float]]
= {}
attribute_page_shown_atDict[Any, float]
= {}
attribute_tab_used_atDict[str, float]
= {}
attribute_owner_settle_taskOptional[asyncio.Task]
= None
attribute_deferred_viewer_rejoins
= {}
attributeallowed_desync_ms
= BACKPRESSURE_ALLOWED_DESYNC_MS
attributebackpressure_check_interval_s
= BACKPRESSURE_CHECK_INTERVAL_S
attributeBACKPRESSURE_QUEUE_SIZE
= getattr(settings, 'backpressure_queue_size', 120)

Audio queue depth (chunks dropped past it); video is bounded per client by the relay byte budget instead.

attribute_last_client_frame_id_report_time
= 0.0
attributecapture_loop
= None
attribute_framed_displaysset
= set()
attributedisplay_clients
= {}

Display id to its owning socket and per-display state (geometry, tunables, frame-id/ACK/RTT bookkeeping, video_active, backpressure_task).

attributeco_controllersDict[str, OrderedDict[Any, Optional[str]]]
= {}
attribute_page_settingsDict[Any, dict]
= {}
attributevideo_relay_groups
= {}

Display id to {ws: _VideoRelay}; the dict's presence marks the capture as delivering, and relays are created lazily by the fan-out.

attributecommon_framesDict[Tuple[str, bool], CommonFrames]
= {}

(display id, held) to the frames every one of its relays' clients holds, or where not held was handed (CommonFrames), told to its encoder.

attributecapture_instances
= {}

Display id to {module, callback, settings} for a running capture; callback and settings are retained so a resize re-targets the live module and a reconfigure can judge whether the running session is structurally compatible with the desired one.

attribute_starting_capturesDict[str, Dict[str, Any]]
= {}
attributedisplay_layouts
= {}

Display id to its {x, y, w, h} rectangle in the union desktop, as last computed by a reconfigure pass.

attribute_persistent_capture_modules
= {}

One ScreenCapture per display id for the server's lifetime, so a restart does not re-initialize the backend (NVENC session, CUDA context, compositor handle).

attribute_wayland_ctl_module
= None

Fallback pixelflux handle for output management when no primary module exists yet (any handle reaches the backend).

attribute_host_output_capacity
= None

Host-capture mode only: how many outputs the host compositor exposes; None until a query answers.

attribute_last_keyframe_request
= {}

Display id to monotonic time of the last IDR request; _last_keyframe_log and _keyframe_log_suppressed throttle only the log line, never the request.

attribute_last_keyframe_log
= {}
attribute_keyframe_log_suppressed
= {}
attribute_last_lost_frame
= {}

Display id to monotonic time of the last frame a client reported lost, which floors the invalidations a burst of clients can ask of one encoder; _invalidation_log throttles the log line to one per display per five seconds.

attribute_invalidation_log
= {}
attributeaudio_device_name
= self.cli_args.audio_device_name
attributepcmflux_module
= None
attributeis_pcmflux_capturing
= False
attributepcmflux_settings
= None
attribute_pcmflux_reported_failure
= None

(module id, reason) of the failure already logged for the current audio run.

attribute_pcmflux_last_restart
= 0.0
attributeaudio_redundancy_by_ws
= {}

Per-socket Opus+RED capability from the audioRedundancy settings field.

attribute_red_unsettled
= set()

Sockets that joined a running capture and have not yet said what they decode (AUDIO_RED_SETTLE_S).

attribute_heard_atDict[Any, float]
= {}
attributeaudio_redundancy_enabled
= bool(settings.audio_redundancy[0])
attribute_active_audio_red_distance
= 0

RED distance the running audio pipeline was started with.

attributepcmflux_callback
= None
attributepcmflux_audio_queue
= None
attributepcmflux_send_task
= None
attributepcmflux_capture_loop
= None
attribute_last_display_count
= 0
attribute_wm_swap
= MultiMonitorWindowManager()

Swaps in a multi-monitor-capable window manager on X11.

Functions

constructor__init__(supervisor=None) -> None
Source Code
def __init__(self, supervisor: Optional[Any] = None) -> None:
    super().__init__("websockets")
    self.data_ws: Optional[web.WebSocketResponse] = (
        None
    )
    self.clients: set[web.WebSocketResponse] = set()
    self.app = None
    self.cli_args = settings
    self.is_secure_mode = False
    self.input_handler = None
    self._tasks_to_run = []
    self.RECONNECT_DEBOUNCE_MS = 500
    self.RECONNECT_GRACE_S = 3.0
    self.HIDDEN_OWNER_HANDOFF_S = 1.0
    self.IDLE_OWNER_HANDOFF_S = 3.0
    self._display_teardown_tasks = set()
    self.MAX_RECENT_CLIENTS = 1000
    self.last_connection_times = OrderedDict()
    self._latest_client_render_fps = 0.0
    self._last_time_client_ok = 0.0
    self._client_acknowledged_frame_id = -1
    self._last_client_acknowledged_frame_id_update_time = 0.0
    self._previous_ack_id_for_stall_check = -1
    self._previous_sent_id_for_stall_check = -1
    self._sent_frames_log = deque()
    self.rc_mode = RateControlMode.CRF
    self.config_gate = asyncio.Event()
    self.shutdown_event = asyncio.Event()
    self._shutdown_called = False
    self.supervisor = supervisor

    def get_initial_value(setting_name: str):
        """Get the correct initial integer/bool from a processed setting."""
        processed_value = getattr(self.cli_args, setting_name)
        setting_def = next((s for s in SETTING_DEFINITIONS if s['name'] == setting_name), None)
        if not setting_def: return None

        if setting_def['type'] == 'range':
            min_val, max_val = processed_value
            return min_val if min_val == max_val else setting_def.get('meta', {}).get('default_value')
        elif setting_def['type'] == 'bool':
            return processed_value[0]
        return processed_value

    self._initial_video_crf = get_initial_value('video_crf')
    self.video_crf = self._initial_video_crf
    self._initial_video_fullcolor = get_initial_value('video_fullcolor')
    self.video_fullcolor = self._initial_video_fullcolor
    self._initial_video_10bit = get_initial_value('video_10bit')
    self.video_10bit = self._initial_video_10bit
    self._initial_video_streaming_mode = get_initial_value('video_streaming_mode')
    self.video_streaming_mode = self._initial_video_streaming_mode
    self.capture_cursor = False
    self._initial_jpeg_quality = get_initial_value('jpeg_quality')
    self.jpeg_quality = self._initial_jpeg_quality
    self._initial_paint_over_jpeg_quality = get_initial_value('paint_over_jpeg_quality')
    self.paint_over_jpeg_quality = self._initial_paint_over_jpeg_quality
    self._initial_video_paintover_crf = get_initial_value('video_paintover_crf')
    self.video_paintover_crf = self._initial_video_paintover_crf
    self._initial_video_paintover_burst_frames = get_initial_value('video_paintover_burst_frames')
    self.video_paintover_burst_frames = self._initial_video_paintover_burst_frames
    self._initial_use_cpu = get_initial_value('use_cpu')
    self.use_cpu = self._initial_use_cpu
    self._initial_cpu_encode_threading = get_initial_value('cpu_encode_threading')
    self.cpu_encode_threading = self._initial_cpu_encode_threading
    # Unset, a display's threads follow its encoder (`effective_cpu_encode_threading`).
    self._cpu_encode_threading_provided = bool(app_settings.was_provided('cpu_encode_threading'))
    self._initial_use_paint_over_quality = get_initial_value('use_paint_over_quality')
    self.use_paint_over_quality = self._initial_use_paint_over_quality
    self._initial_video_bitrate = get_initial_value('video_bitrate')
    self.video_bitrate = self._initial_video_bitrate

    self._resource_monitor: Optional[resource_stats.ResourceMonitor] = None
    self._stats_subscribers: Set[web.WebSocketResponse] = set()
    self._stats_sending: Set[web.WebSocketResponse] = set()
    self._stream_watches: Dict[str, stream_stats.StreamWatch] = {}
    self.uinput_mouse_socket = UINPUT_MOUSE_SOCKET
    self.js_socket_path = socket_dir(settings.js_socket_path)
    self.enable_clipboard = settings.enable_clipboard
    self.enable_binary_clipboard = self.cli_args.enable_binary_clipboard[0]
    self.enable_cursors = ENABLE_CURSORS
    self.cursor_size = CURSOR_SIZE
    self.cursor_scale = 1.0
    self.cursor_debug = DEBUG_CURSORS
    self._last_adjustment_timestamp = 0.0
    self.client_settings_received = asyncio.Event()
    self._reconfigure_lock = asyncio.Lock()
    self._audio_lock = asyncio.Lock()
    self._video_capture_lock = asyncio.Lock()
    self._is_reconfiguring = False
    self._reconfigure_pending = False
    self.last_start_video_request_times = {}
    # When each page that does not own its display last had a repair of its
    # stream taken, by kind (`_repair_taken`).
    self._repair_times: Dict[Tuple[Any, str], float] = {}
    self.video_paused_clients = set()
    # The audio each controller beside the primary's owner asked for, its own:
    # the owner's page decides it for itself and the viewers, None until it
    # says, which leaves it to the start policy (`_hears_audio`).
    self._beside_audio: Dict[Any, bool] = {}
    self._session_audio: Optional[bool] = None
    # When each controller page that reports its visibility (`PAGE_VISIBILITY`)
    # last hid, None while it shows, and when it last showed: a page that
    # never reported is in neither (`_settle_display_owner`).
    self._page_hidden_at: Dict[Any, Optional[float]] = {}
    self._page_shown_at: Dict[Any, float] = {}
    # When each controller tab's user last acted through it (`page_put_to_use`),
    # or it took the primary; by tab, so a reconnect keeps it.
    self._tab_used_at: Dict[str, float] = {}
    self._owner_settle_task: Optional[asyncio.Task] = None
    self._deferred_viewer_rejoins = {}
    self.allowed_desync_ms = BACKPRESSURE_ALLOWED_DESYNC_MS
    self.backpressure_check_interval_s = BACKPRESSURE_CHECK_INTERVAL_S
    self.BACKPRESSURE_QUEUE_SIZE = getattr(settings, 'backpressure_queue_size', 120)
    self._last_client_frame_id_report_time = 0.0
    self.capture_loop = None
    # Displays whose live capture has delivered a frame, for the first-frame check.
    self._framed_displays: set = set()

    self.display_clients = {}
    # Controllers of a display beside its owner, oldest first: a page of
    # another tab takes the stream and input with it, where the owner keeps
    # the display's size and encoding, and the oldest owns it once the owner
    # is gone for good (`_promote_co_controller`), the one that showed last
    # once the owner's tab is hidden (`_settle_display_owner`).
    self.co_controllers: Dict[str, "OrderedDict[Any, Optional[str]]"] = {}
    # Each controller page's last SETTINGS: a later one applies the stream
    # settings it changed, not the ones it repeats (`_settings_changed_by`).
    self._page_settings: Dict[Any, dict] = {}
    self.video_relay_groups = {}
    self.common_frames: Dict[Tuple[str, bool], CommonFrames] = {}
    self.capture_instances = {}
    # A display's capture while its start is awaited: its module takes rate,
    # tunable and key-frame requests meanwhile, and the settings registered
    # once it runs carry what was applied (`_opcode_display_module`).
    self._starting_captures: Dict[str, Dict[str, Any]] = {}
    self.display_layouts = {}
    self._persistent_capture_modules = {}
    self._wayland_ctl_module = None
    self._host_output_capacity = None
    self._last_keyframe_request = {}
    self._last_keyframe_log = {}
    self._keyframe_log_suppressed = {}
    self._last_lost_frame = {}
    self._invalidation_log = {}

    self.audio_device_name = self.cli_args.audio_device_name
    self.pcmflux_module = None
    self.is_pcmflux_capturing = False
    self.pcmflux_settings = None
    self._pcmflux_reported_failure = None
    self._pcmflux_last_restart = 0.0
    self.audio_redundancy_by_ws = {}
    self._red_unsettled = set()
    # When each socket's page last sent anything (pings and pongs are the browser's own).
    self._heard_at: Dict[Any, float] = {}
    self.audio_redundancy_enabled = bool(settings.audio_redundancy[0])
    self._active_audio_red_distance = 0
    # The vendored WebRTC RedOpusEncoder reads its depth from audio_config,
    # so one control (0 = plain Opus) drives both transports.
    _red_dist = getattr(settings, "audio_redundancy_distance", AUDIO_RED_DISTANCE)
    audio_config.set_red_distance(
        _red_dist if self.audio_redundancy_enabled else 0
    )
    self.pcmflux_callback = None
    self.pcmflux_audio_queue = None
    self.pcmflux_send_task = None
    self.pcmflux_capture_loop = None

    self._last_display_count = 0
    self._wm_swap = MultiMonitorWindowManager()
paramsupervisorOptional[Any]
= None

Returns

None
funcinitialize() -> None

Create the SelkiesStreamingApp and InputHandler and wire their callbacks.

Must be called before run(). Also resolves secure vs legacy mode (a set master token closes the config gate until tokens are provisioned, and governs who holds input authority) and installs the WebRTC-dialect live verbs (_arg_fps, vb, ab, _rc, _crf) so both transports honor the same per-key tunables. With metrics enabled, the registry-global Prometheus gauges are fed server-side (ACK-derived client fps and smoothed RTT from the backpressure loop, GPU from the stats collector) and by the shared _f,/_l, verbs when a client reports directly.

Source Code
def initialize(self) -> None:
    """Create the SelkiesStreamingApp and InputHandler and wire their callbacks.

    Must be called before run(). Also resolves secure vs legacy mode (a set
    master token closes the config gate until tokens are provisioned, and
    governs who holds input authority) and installs the WebRTC-dialect live
    verbs (`_arg_fps`, `vb`, `ab`, `_rc`, `_crf`) so both transports honor
    the same per-key tunables. With metrics enabled, the registry-global
    Prometheus gauges are fed server-side (ACK-derived client fps and
    smoothed RTT from the backpressure loop, GPU from the stats collector)
    and by the shared `_f,`/`_l,` verbs when a client reports directly.
    """
    self.is_secure_mode = bool(self.cli_args.master_token)
    if self.is_secure_mode:
        logger.debug("Secure Mode ENABLED (SELKIES_MASTER_TOKEN is set).")
    else:
        logger.debug("Legacy Mode ENABLED (SELKIES_MASTER_TOKEN is not set).")
        self.config_gate.set()

    global TARGET_FRAMERATE
    processed_framerate = settings.framerate
    min_fr, max_fr = processed_framerate
    if min_fr == max_fr:
        TARGET_FRAMERATE = min_fr
    else:
        fr_def = next((s for s in SETTING_DEFINITIONS if s['name'] == 'framerate'), None)
        TARGET_FRAMERATE = fr_def['meta']['default_value'] if fr_def else 60

    initial_encoder = settings.encoder

    logger.debug(f"Initializing DataStreamingServer with encoder: {initial_encoder}, Framerate: {TARGET_FRAMERATE}")

    event_loop = asyncio.get_running_loop()
    self.app = SelkiesStreamingApp(
        event_loop,
        framerate=TARGET_FRAMERATE,
        encoder=initial_encoder,
        mode="websockets",
    )
    self.app.server_enable_resize = ENABLE_RESIZE
    self.app.last_resize_success = True
    self.app.data_streaming_server = self
    logger.debug(
        f"SelkiesStreamingApp initialized: encoder={self.app.encoder}, display={self.app.display_width}x{self.app.display_height}"
    )

    if settings.enable_rate_control[0]:
        self.rc_mode = RateControlMode(settings.rate_control_mode)

    # The normalized policy string (true/false/in/out); the input handler gates
    # directions off it.
    clipboard_mode = settings.enable_clipboard

    self.input_handler = InputHandler(
        self.app,
        self.uinput_mouse_socket,
        self.js_socket_path,
        clipboard_mode,
        str(settings.enable_binary_clipboard[0]).lower(),
        self.enable_cursors,
        self.cursor_size,
        1.0,
        self.cursor_debug,
        data_server_instance=self,
        is_wayland=IS_WAYLAND,
        wayland_socket_index=settings.wayland_socket_index,
        app_wayland_display=(settings.app_wayland_display
                             or settings.wayland_host_display),
        uinput_gamepad=settings.uinput_gamepad,
    )

    self.input_handler.on_clipboard_read = self.app.send_ws_clipboard_data
    self.input_handler.on_set_fps = self._handle_opcode_fps
    self.input_handler.on_video_encoder_bit_rate = self._handle_opcode_video_bitrate
    self.input_handler.on_audio_encoder_bit_rate = self._handle_opcode_audio_bitrate
    self.input_handler.on_update_rate_control_mode = self._handle_opcode_rate_control
    self.input_handler.on_update_crf = self._handle_opcode_crf
    self.metrics = None
    if settings.enable_metrics_http[0]:
        self.metrics = Metrics()
        self.input_handler.on_client_fps = (
            lambda fps: self.metrics.set_fps(fps) if self.metrics else None
        )
        self.input_handler.on_client_latency = (
            lambda latency: self.metrics.set_latency(latency) if self.metrics else None
        )
    self.input_handler.on_mouse_pointer_visible = self.set_native_cursor_rendering
    self.input_handler.on_session_compositor_adopted = self._resync_wayland_session_scale
    self.input_handler.on_session_screens_changed = self._republish_second_screen
    self.input_handler.on_scaling_ratio = self._handle_scaling

    if ENABLE_RESIZE:
        self.input_handler.on_resize = self._handle_resize
    else:
        # Only the resolution is frozen: a DPI sync still scales the desktop.
        self.input_handler.on_resize = lambda res_str, display_id='primary': logger.warning("Resize disabled.")
    logger.debug("DataStreamingServer initialization complete.")

Returns

None
funcset_native_cursor_rendering(enabled) -> None

Compose the cursor into the captured video (vs the client-drawn overlay).

Applies to every display's capture. Reached both from the SET_NATIVE_CURSOR_RENDERING message and the shared input protocol's pointer-visibility toggle ("p,N"), which map to the same tunable.

Source Code
async def set_native_cursor_rendering(self, enabled: bool) -> None:
    """Compose the cursor into the captured video (vs the client-drawn overlay).

    Applies to every display's capture. Reached both from the
    SET_NATIVE_CURSOR_RENDERING message and the shared input protocol's
    pointer-visibility toggle ("p,N"), which map to the same tunable.
    """
    if self.capture_cursor == enabled:
        data_logger.debug(f"Native cursor rendering: value {enabled} is already set.")
        return
    self.capture_cursor = enabled
    if len(self.capture_instances) > 0:
        data_logger.info("Cursor rendering changed, triggering display reconfiguration.")
        await self.reconfigure_displays()
paramenabledbool

Returns

None
func_opcode_display_module(display_id) -> Optional[Any]

The display's ScreenCapture module, running or starting, or None if not capturing: pixelflux takes rate, tunable and key-frame requests while a capture starts.

Source Code
def _opcode_display_module(self, display_id: str) -> Optional[Any]:
    """The display's ScreenCapture module, running or starting, or None if
    not capturing: pixelflux takes rate, tunable and key-frame requests while
    a capture starts."""
    inst = self.capture_instances.get(display_id) or self._starting_captures.get(display_id)
    return inst.get('module') if inst else None
paramdisplay_idstr

Returns

typing.Optional[typing.Any]
func_track_capture_settings(display_id, fresh=None, **live_fields) -> None

Record what the display's running capture is actually configured with.

Pass fresh after rebuilding the whole settings object, or individual fields after a targeted rate update.

The tracked object is what _video_relay_budget sizes new relays from and what a layout-following reconfigure re-pushes to the module, so a live change that skipped it would be applied to the encoder and then silently reverted.

Source Code
def _track_capture_settings(self, display_id: str, fresh: Optional[Any] = None,
                            **live_fields: Any) -> None:
    """Record what the display's running capture is actually configured with.

    Pass `fresh` after rebuilding the whole settings object, or individual
    fields after a targeted rate update.

    The tracked object is what _video_relay_budget sizes new relays from and
    what a layout-following reconfigure re-pushes to the module, so a live
    change that skipped it would be applied to the encoder and then silently
    reverted.
    """
    inst = self.capture_instances.get(display_id) or self._starting_captures.get(display_id)
    if inst is None:
        return
    if fresh is not None:
        inst['settings'] = fresh
        return
    cs = inst.get('settings')
    if cs is None:
        return
    for name, value in live_fields.items():
        setattr(cs, name, value)
paramdisplay_idstr
paramfreshOptional[Any]
= None
paramlive_fieldsAny
= {}

Returns

None
func_joins_beside_owner(websocket, tab_id) -> bool

Whether a controller's SETTINGS for the primary makes it a controller beside the display's owner rather than its owner: with sharing on, a page of another tab than the live owner's, or one already beside it. A page that names no tab (an older client), or the owner's own tab reloading, takes the display over as before.

Source Code
def _joins_beside_owner(self, websocket: Any, tab_id: Optional[str]) -> bool:
    """Whether a controller's SETTINGS for the primary makes it a controller
    beside the display's owner rather than its owner: with sharing on, a
    page of another tab than the live owner's, or one already beside it. A
    page that names no tab (an older client), or the owner's own tab
    reloading, takes the display over as before.
    """
    if websocket in self.co_controllers.get('primary', ()):
        return True
    if not getattr(self.cli_args, 'enable_sharing', (True,))[0]:
        return False
    owner = self.display_clients.get('primary')
    owner_ws = owner.get('ws') if owner else None
    return (owner_ws is not None and owner_ws is not websocket and not owner_ws.closed
            and bool(tab_id) and bool(owner.get('tab_id')) and tab_id != owner.get('tab_id'))
paramwebsocketAny
paramtab_idOptional[str]

Returns

bool
func_promote_co_controller(display_id) -> bool

Hand a display whose owner is gone for good to the oldest controller beside it that holds full permissions, else to the oldest one: told DISPLAY_OWNER <display>, the page sends its settings again, and that SETTINGS takes the entry over, with full control of the display, its own changes now applying. False when none is left to tell.

Source Code
async def _promote_co_controller(self, display_id: str) -> bool:
    """Hand a display whose owner is gone for good to the oldest controller
    beside it that holds full permissions, else to the oldest one: told
    `DISPLAY_OWNER <display>`, the page sends its settings again, and that
    SETTINGS takes the entry over, with full control of the display, its own
    changes now applying. False when none is left to tell."""
    joiners = self.co_controllers.get(display_id)
    while joiners:
        ws = next((w for w in joiners if not w.closed and self._holds_full_control(w)), next(iter(joiners)))
        joiners.pop(ws)
        if ws.closed:
            continue
        try:
            await asyncio.wait_for(ws.send_str(f"DISPLAY_OWNER {display_id}"), timeout=2.0)
        except (asyncio.TimeoutError, ConnectionResetError, OSError, RuntimeError):
            continue
        data_logger.info(f"The controller beside '{display_id}' owns it now.")
        return True
    return False
paramdisplay_idstr

Returns

bool
func_seat_display_page(display_id, display_state, websocket, tab_id) -> None

Point a display's entry at the page that owns it now: its decode pace, frame acknowledgements and round trips start over, and its stream waits for a key frame.

Source Code
def _seat_display_page(self, display_id: str, display_state: dict, websocket: Any,
                       tab_id: Optional[str]) -> None:
    """Point a display's entry at the page that owns it now: its decode pace,
    frame acknowledgements and round trips start over, and its stream waits
    for a key frame."""
    display_state['ws'] = websocket
    display_state['tab_id'] = tab_id
    self._apply_decode_pace(display_id, display_state, None)
    display_state['acknowledged_frame_id'] = -1
    display_state['acked_sent_at'] = None
    display_state['unacked_since'] = None
    display_state['stall_gated_at'] = None
    _expect_key_frame(display_state)
    display_state['sent_timestamps'].clear()
    display_state['rtt_samples'].clear()
    display_state['smoothed_rtt'] = 0.0
paramdisplay_idstr
paramdisplay_statedict
paramwebsocketAny
paramtab_idOptional[str]

Returns

None
func_settle_display_owner() -> None

Hand the primary to the controller beside its owner that showed or was used last (_hand_display_to), once the owner's page has been hidden for HIDDEN_OWNER_HANDOFF_S: a phone put away, the display left to another device. Only pages that report their visibility and hold full permissions take it; a hidden owner with none beside it keeps the display, as does one whose socket closed, which the reconnect grace answers instead.

Source Code
async def _settle_display_owner(self) -> None:
    """Hand the primary to the controller beside its owner that showed or was
    used last (`_hand_display_to`), once the owner's page has been hidden
    for HIDDEN_OWNER_HANDOFF_S: a phone put away, the display left to
    another device. Only pages that report their visibility and hold full
    permissions take it; a hidden owner with none beside it keeps the
    display, as does one whose socket closed, which the reconnect grace
    answers instead."""
    entry = self.display_clients.get('primary')
    owner = entry.get('ws') if entry else None
    hidden_at = self._page_hidden_at.get(owner) if owner is not None else None
    if owner is None or owner.closed or hidden_at is None:
        return
    joiners = self.co_controllers.get('primary') or {}
    visible = [ws for ws in joiners if not ws.closed and ws in self._page_hidden_at
               and self._page_hidden_at[ws] is None and self._holds_full_control(ws)]
    if not visible:
        return
    wait = hidden_at + self.HIDDEN_OWNER_HANDOFF_S - time.monotonic()
    if wait > 0:
        if self._owner_settle_task is None or self._owner_settle_task.done():
            async def _settle_later() -> None:
                await asyncio.sleep(wait)
                self._owner_settle_task = None
                await self._settle_display_owner()
            self._owner_settle_task = asyncio.create_task(_settle_later())
        return
    heir = max(visible, key=lambda ws: max(self._page_shown_at.get(ws, 0.0),
                                           self._tab_used_at.get(joiners[ws] or '', 0.0)))
    await self._hand_display_to(heir, "hid its page: the visible controller beside it")

Returns

None
func_take_display_in_use(websocket) -> None

Hand the primary to the controller beside its owner whose user just acted through it, once the owner has gone IDLE_OWNER_HANDOFF_S without its own user's: one person moving between devices takes the display along, and nobody is disconnected. Only between pages of the same credential (the same token, or none), so a page of another token, a collaborator's, stays beside the owner; and only between pages that report their visibility, the one acting shown and holding full permissions.

Source Code
async def _take_display_in_use(self, websocket: Any) -> None:
    """Hand the primary to the controller beside its owner whose user just
    acted through it, once the owner has gone IDLE_OWNER_HANDOFF_S without
    its own user's: one person moving between devices takes the display
    along, and nobody is disconnected. Only between pages of the same
    credential (the same token, or none), so a page of another token, a
    collaborator's, stays beside the owner; and only between pages that
    report their visibility, the one acting shown and holding full
    permissions."""
    entry = self.display_clients.get('primary')
    owner = entry.get('ws') if entry else None
    if (owner is None or owner.closed or websocket not in self.co_controllers.get('primary', ())
            or owner not in self._page_hidden_at or websocket not in self._page_hidden_at
            or self._page_hidden_at[websocket] is not None
            or time.monotonic() - self._tab_used_at.get(entry.get('tab_id') or '', 0.0)
            < self.IDLE_OWNER_HANDOFF_S
            or (client_permissions.get(websocket) or {}).get('token')
            != (client_permissions.get(owner) or {}).get('token')
            or not self._holds_full_control(websocket)):
        return
    await self._hand_display_to(websocket, "went unused: the controller beside it in use")
paramwebsocketAny

Returns

None
func_capture_for_page_beside(websocket) -> None

Start the primary capture a hidden owner stopped for a page that joined beside it and is still there once the owner's hand-off had its time (_settle_display_owner): an older page, or one without full control, never takes the display, and would wait on the owner. The owner's own feed stays paused until its START_VIDEO.

Source Code
def _capture_for_page_beside(self, websocket: Any) -> None:
    """Start the primary capture a hidden owner stopped for a page that
    joined beside it and is still there once the owner's hand-off had its
    time (`_settle_display_owner`): an older page, or one without full
    control, never takes the display, and would wait on the owner. The
    owner's own feed stays paused until its START_VIDEO."""
    async def _later() -> None:
        await asyncio.sleep(self.HIDDEN_OWNER_HANDOFF_S + 0.5)
        owner = (self.display_clients.get('primary') or {}).get('ws')
        if (websocket.closed or websocket not in self.co_controllers.get('primary', ())
                or 'primary' in self.capture_instances or owner is None or owner.closed
                or not pipeline_starts_on('video', 'primary')):
            return
        self.video_paused_clients.add(owner)
        data_logger.info("Starting the 'primary' capture its hidden owner stopped, for the page beside it.")
        if await self._ensure_viewer_capture():
            try:
                await websocket.send_str("PIPELINE_RESETTING primary")
            except (ConnectionResetError, OSError, RuntimeError):
                pass
            self._schedule_idr_for_display('primary')
    _spawn_background_task(_later(), name="capture-for-page-beside")
paramwebsocketAny

Returns

None
func_hand_display_to(heir, why) -> None

Make heir, a controller beside the primary's owner, its owner: told DISPLAY_OWNER primary, it sends its settings and its size, which lay the display out, and the owner stays beside it, paused while hidden.

Source Code
async def _hand_display_to(self, heir: Any, why: str) -> None:
    """Make `heir`, a controller beside the primary's owner, its owner: told
    `DISPLAY_OWNER primary`, it sends its settings and its size, which lay
    the display out, and the owner stays beside it, paused while hidden."""
    entry = self.display_clients['primary']
    owner = entry['ws']
    joiners = self.co_controllers['primary']
    heir_tab = joiners.pop(heir)
    owner_tab = entry.get('tab_id')
    joiners[owner] = owner_tab
    self._seat_display_page('primary', entry, heir, heir_tab)
    _forget_path(entry)
    if heir_tab:
        self._tab_used_at[heir_tab] = time.monotonic()
    # Each page keeps the audio it asked for: the new owner's is the session's now.
    heir_audio = self._beside_audio.pop(heir, None)
    self._beside_audio[owner] = (self._session_audio if self._session_audio is not None
                                 else pipeline_starts_on('audio', 'primary'))
    if heir_audio is not None:
        self._session_audio = heir_audio
    if self._page_hidden_at.get(owner) is not None:
        self.video_paused_clients.add(owner)
    data_logger.info(
        f"The owner of 'primary' {why} owns the display now "
        f"(tab {(heir_tab or 'none')[:8]}, the old owner's {(owner_tab or 'none')[:8]}).")
    try:
        await asyncio.wait_for(heir.send_str("DISPLAY_OWNER primary"), timeout=2.0)
    except (asyncio.TimeoutError, ConnectionResetError, OSError, RuntimeError):
        pass
paramheirAny
paramwhystr

Returns

None
func_owns_display(websocket, display_id) -> bool

Whether websocket is the page that owns display_id, the primary for none.

Source Code
def _owns_display(self, websocket: Any, display_id: Optional[str]) -> bool:
    """Whether `websocket` is the page that owns `display_id`, the primary for none."""
    return (self.display_clients.get(display_id or 'primary') or {}).get('ws') is websocket
paramwebsocketAny
paramdisplay_idOptional[str]

Returns

bool
func_repair_taken(websocket, display_id, kind) -> bool

Whether a page's request to repair its display's stream (kind: a keyframe or a lost frame) is taken: always from the page that owns the display, at most once a second from any other, a viewer or a controller beside the owner, since any number of them share the owner's stream.

Source Code
def _repair_taken(self, websocket: Any, display_id: Optional[str], kind: str) -> bool:
    """Whether a page's request to repair its display's stream (`kind`: a
    keyframe or a lost frame) is taken: always from the page that owns the
    display, at most once a second from any other, a viewer or a controller
    beside the owner, since any number of them share the owner's stream."""
    if self._owns_display(websocket, display_id):
        return True
    now = time.monotonic()
    if now - self._repair_times.get((websocket, kind), 0.0) < 1.0:
        return False
    self._repair_times[(websocket, kind)] = now
    return True
paramwebsocketAny
paramdisplay_idOptional[str]
paramkindstr

Returns

bool
func_hears_audio(websocket) -> bool

Whether the audio fan-out serves a page: a controller beside the primary's owner by its own START_AUDIO, every other page by the owner's.

Source Code
def _hears_audio(self, websocket: Any) -> bool:
    """Whether the audio fan-out serves a page: a controller beside the
    primary's owner by its own START_AUDIO, every other page by the owner's."""
    if websocket in self.co_controllers.get('primary', ()):
        return self._beside_audio.get(websocket, False)
    if self._session_audio is not None:
        return self._session_audio
    return pipeline_starts_on('audio', 'primary')
paramwebsocketAny

Returns

bool
func_audio_wanted() -> bool

Whether a page the audio fan-out serves wants the capture running.

Source Code
def _audio_wanted(self) -> bool:
    """Whether a page the audio fan-out serves wants the capture running."""
    return any(self._hears_audio(ws) for ws in self._audio_listeners())

Returns

bool
func_holds_full_control(websocket) -> bool

Whether a page holds a display's full permissions: a controller that may drive keyboard and mouse, not a viewer, which only watches, nor a gamepad player.

Source Code
def _holds_full_control(self, websocket: Any) -> bool:
    """Whether a page holds a display's full permissions: a controller that
    may drive keyboard and mouse, not a viewer, which only watches, nor a
    gamepad player."""
    perms = client_permissions.get(websocket) if websocket is not None else None
    return bool(perms) and perms.get("role") == "controller" and self._holds_input_authority(websocket)
paramwebsocketAny

Returns

bool
func_cpu_encode_threading_for(encoder, requested) -> bool

Whether a display on encoder threads its software encode: the client's request, the operator's value, or what the encoder defaults to (effective_cpu_encode_threading).

Source Code
def _cpu_encode_threading_for(self, encoder: str, requested: Optional[bool]) -> bool:
    """Whether a display on `encoder` threads its software encode: the client's request,
    the operator's value, or what the encoder defaults to (`effective_cpu_encode_threading`)."""
    return effective_cpu_encode_threading(encoder, requested, bool(self._initial_cpu_encode_threading),
                                          self._cpu_encode_threading_provided)
paramencoderstr
paramrequestedOptional[bool]

Returns

bool
func_display_settings(display_id) -> Dict[str, Any]

What a display streams with, keyed as SETTINGS carries it: the use_cpu the display asks for rather than the one a CPU-only encoder implies, and the session's audio bitrate.

Source Code
def _display_settings(self, display_id: str) -> Dict[str, Any]:
    """What a display streams with, keyed as SETTINGS carries it: the
    `use_cpu` the display asks for rather than the one a CPU-only encoder
    implies, and the session's audio bitrate."""
    state = self.display_clients.get(display_id) or {}
    values = {key: state.get(key) for key in STREAM_SETTINGS}
    requested = state.get("use_cpu_requested")
    values["use_cpu"] = bool(self._initial_use_cpu) if requested is None else bool(requested)
    values["audio_bitrate"] = self.app.audio_bitrate
    return {key: value for key, value in values.items() if value is not None}
paramdisplay_idstr

Returns

typing.Dict[str, typing.Any]
func_tell_display_settings(display_id, sockets) -> None

Tell pages what display_id streams with (display_settings): a page beside the display's owner holds it for its tab, as does the owner once another page's pick changed it, so each shows and asks for what the display does.

Source Code
async def _tell_display_settings(self, display_id: str, sockets: Any) -> None:
    """Tell pages what `display_id` streams with (`display_settings`): a
    page beside the display's owner holds it for its tab, as does the owner
    once another page's pick changed it, so each shows and asks for what
    the display does."""
    sockets = {ws for ws in sockets if ws is not None and ws in self.clients}
    if not sockets:
        return
    message = json.dumps({"type": "display_settings", "displayId": display_id,
                          "settings": self._display_settings(display_id)})
    for ws in await _broadcast_to_clients(sockets, message, watched=True):
        self.clients.discard(ws)
paramdisplay_idstr
paramsocketsAny

Returns

None
func_settings_changed_by(websocket, settings) -> dict

A page's later SETTINGS without the stream settings it repeats from its last one: a page beside its owner may have changed them since. An encoder whose fallback mark changed counts as changed.

Source Code
def _settings_changed_by(self, websocket: Any, settings: dict) -> dict:
    """A page's later SETTINGS without the stream settings it repeats from
    its last one: a page beside its owner may have changed them since. An
    encoder whose fallback mark changed counts as changed."""
    last = self._page_settings.get(websocket) or {}
    self._page_settings[websocket] = settings
    changed = {key for key in STREAM_SETTINGS if settings.get(key) != last.get(key)}
    if settings.get("encoderFallback") != last.get("encoderFallback"):
        changed.add("encoder")
    return {key: value for key, value in settings.items() if key not in STREAM_SETTINGS or key in changed}
paramwebsocketAny
paramsettingsdict

Returns

dict
func_take_pick_beside_owner(websocket, settings, client_role) -> None

A later SETTINGS from a controller beside the primary's owner. What its user picked of the stream (picked) applies to the display where both pages hold full permissions, and the display's pages are told; the rest, its own size and density and what its page changed on its own, follows the owner, and the page is told what that is.

Source Code
async def _take_pick_beside_owner(self, websocket: Any, settings: dict, client_role: str) -> None:
    """A later SETTINGS from a controller beside the primary's owner. What
    its user picked of the stream (`picked`) applies to the display where
    both pages hold full permissions, and the display's pages are told; the
    rest, its own size and density and what its page changed on its own,
    follows the owner, and the page is told what that is."""
    picks = {key: settings[key] for key in (settings.get("picked") or ())
             if key in STREAM_SETTINGS and settings.get(key) is not None}
    owner_ws = (self.display_clients.get('primary') or {}).get('ws')
    if not (picks and self._holds_full_control(websocket) and self._holds_full_control(owner_ws)):
        await self._tell_display_settings('primary', {websocket})
        return
    data_logger.info(f"Applying {', '.join(sorted(picks))} picked by the controller beside the owner of 'primary'.")
    # Every other key as a payload that does not carry it: what the owner's
    # page sends of the display's geometry stays as it was.
    applied = dict.fromkeys(settings)
    applied.update(picks, displayId='primary')
    if "encoder" in picks:
        applied["encoderFallback"] = settings.get("encoderFallback")
    await self._apply_client_settings(websocket, applied, False, client_role)
    await self._tell_display_settings('primary', {owner_ws, *self.co_controllers.get('primary', {})})
paramwebsocketAny
paramsettingsdict
paramclient_rolestr

Returns

None
func_handle_resize(res_str, display_id='primary') -> None

Route a client resize once the displays have been laid out.

The layout comes from an initial SETTINGS, and a client's own carries the geometry, so a resize ahead of it is left to it: waited for here, it would hold the message loop that has to read that SETTINGS.

Source Code
async def _handle_resize(self, res_str: str, display_id: str = 'primary') -> None:
    """Route a client resize once the displays have been laid out.

    The layout comes from an initial SETTINGS, and a client's own carries
    the geometry, so a resize ahead of it is left to it: waited for here,
    it would hold the message loop that has to read that SETTINGS.
    """
    if not self.client_settings_received.is_set():
        data_logger.debug("Ignoring resize request received before initial SETTINGS.")
        return
    await on_resize_handler(res_str, self.app, self, display_id)
paramres_strstr
paramdisplay_idstr
= 'primary'

Returns

None
func_handle_scaling(dpi_value, display_id='primary') -> None

Apply a client DPI sync to the desktop (WebRTC handle_scaling parity).

Fractional DPI is legal on the shared verb; the desktop property itself is integral and bounded by the declared span, and an operator-set DPI governs the desktop over any client's. X11 takes one DPI for the session; on Wayland the display's own screen takes it, while the cursor cap and size stay the primary's. The DPI is stored where SETTINGS stores it, or a later partial SETTINGS re-applies one the desktop has moved off. A sync ahead of the initial SETTINGS, which carries the DPI, is left to it, as _handle_resize leaves a resize.

Source Code
async def _handle_scaling(self, dpi_value: float, display_id: str = 'primary') -> None:
    """Apply a client DPI sync to the desktop (WebRTC `handle_scaling` parity).

    Fractional DPI is legal on the shared verb; the desktop property itself
    is integral and bounded by the declared span, and an operator-set DPI
    governs the desktop over any client's. X11 takes one DPI for the
    session; on Wayland the display's own screen takes it, while the cursor
    cap and size stay the primary's. The DPI is stored where SETTINGS
    stores it, or a later partial SETTINGS re-applies one the desktop has
    moved off. A sync ahead of the initial SETTINGS, which carries the DPI,
    is left to it, as `_handle_resize` leaves a resize.
    """
    if not self.client_settings_received.is_set():
        data_logger.debug("Ignoring DPI sync received before initial SETTINGS.")
        return
    try:
        dpi_value = min(SCALING_DPI_MAX,
                        max(SCALING_DPI_MIN, int(round(float(dpi_value)))))
    except (TypeError, ValueError, OverflowError):
        data_logger.error(f"Invalid DPI value: {dpi_value!r}")
        return
    if app_settings._overridden.get("scaling_dpi", False):
        data_logger.info("Ignoring client DPI sync: scaling_dpi is operator-overridden.")
        return
    data_logger.debug(f"Received DPI setting from client: {dpi_value}")
    try:
        if not IS_WAYLAND:
            if await set_dpi(dpi_value):
                data_logger.info(f"Successfully set DPI to {dpi_value}")
            else:
                data_logger.error(f"Failed to set DPI to {dpi_value}")
            self._update_cursor_cap(dpi_value)
        else:
            # Before the restart, which reads the cap through CaptureSettings.
            if display_id in (None, 'primary'):
                self._update_cursor_cap(dpi_value)
            await self._realize_wayland_display_dpi(display_id, dpi_value)

        dpi_state = self.display_clients.get(display_id)
        if dpi_state is not None:
            dpi_state["scaling_dpi"] = dpi_value

        if CURSOR_SIZE is not None:
            if IS_WAYLAND:
                if display_id in (None, 'primary'):
                    await self._apply_wayland_cursor_size(dpi_value)
            else:
                new_cursor_size = cursor_size_for_dpi(dpi_value, CURSOR_SIZE)
                data_logger.debug(f"Attempting to set cursor size to: {new_cursor_size} (based on DPI {dpi_value})")
                if await set_cursor_size(new_cursor_size):
                    data_logger.debug(f"Successfully set cursor size to {new_cursor_size}")
                else:
                    data_logger.error(f"Failed to set cursor size to {new_cursor_size}")
    except Exception as e_dpi:
        data_logger.error(f"Error applying DPI {dpi_value}: {e_dpi}", exc_info=True)
paramdpi_valuefloat
paramdisplay_idstr
= 'primary'

Returns

None
func_capture_fps(display_state) -> float

The rate a display's capture runs at: the rate its client chose, or the session's, held to what that client's decoder keeps up with (DECODE_PACE).

Source Code
def _capture_fps(self, display_state: dict) -> float:
    """The rate a display's capture runs at: the rate its client chose, or
    the session's, held to what that client's decoder keeps up with
    (`DECODE_PACE`)."""
    rate = float(display_state.get('framerate') or self.app.framerate)
    pace = display_state.get('decode_pace')
    return min(rate, pace) if pace else rate
paramdisplay_statedict

Returns

float
func_apply_decode_pace(display_id, display_state, pace) -> None

Hold a display's capture to pace, the rate its client's decoder keeps up with, or lift the hold (None), live where the capture runs. The pace lives in the display's entry: a new connection taking the entry over starts without it, and the rate the client chose stays stored.

Source Code
def _apply_decode_pace(self, display_id: str, display_state: dict, pace: Optional[float]) -> None:
    """Hold a display's capture to `pace`, the rate its client's decoder
    keeps up with, or lift the hold (None), live where the capture runs. The
    pace lives in the display's entry: a new connection taking the entry
    over starts without it, and the rate the client chose stays stored."""
    before = self._capture_fps(display_state)
    display_state['decode_pace'] = pace
    after = self._capture_fps(display_state)
    if after == before:
        return
    data_logger.info(
        f"Display '{display_id}': its client's decoder keeps up with {fps_label(pace)} fps; capturing at that."
        if pace else f"Display '{display_id}': capturing at the chosen {fps_label(after)} fps again.")
    module = self.capture_instances.get(display_id, {}).get('module')
    if module is not None:
        try:
            module.update_framerate(after)
            self._track_capture_settings(display_id, target_fps=after)
        except Exception as e:
            data_logger.warning(f"Live framerate update failed for '{display_id}' ({e}).")
paramdisplay_idstr
paramdisplay_statedict
parampaceOptional[float]

Returns

None
func_handle_opcode_fps(fps, display_id='primary') -> None

Live framerate for the shared '_arg_fps' verb (WebRTC-mode parity): sanitize against the server range, store, and live-update the display's capture; a stopped display applies the new rate at its next START_VIDEO.

Source Code
async def _handle_opcode_fps(self, fps: Any, display_id: str = 'primary') -> None:
    """Live framerate for the shared '_arg_fps' verb (WebRTC-mode parity):
    sanitize against the server range, store, and live-update the display's
    capture; a stopped display applies the new rate at its next START_VIDEO."""
    sanitized = sanitize_client_setting("framerate", fps, self.cli_args, data_logger)
    if sanitized is None:
        return
    if display_id == 'primary':
        # Only the primary controller moves the session default later displays seed from.
        self.app.set_framerate(sanitized)
        data_logger.debug(f"Session default framerate updated to {fps_label(sanitized)} fps for new displays.")
    display_state = self.display_clients.get(display_id)
    if display_state is not None:
        display_state["framerate"] = sanitized
    module = self._opcode_display_module(display_id)
    if module is not None:
        try:
            live = self._capture_fps(display_state) if display_state is not None else float(sanitized)
            module.update_framerate(live)
            self._track_capture_settings(display_id, target_fps=live)
            data_logger.info(f"Applied framerate live via '_arg_fps': {fps_label(sanitized)} fps for '{display_id}'")
        except Exception as e:
            data_logger.warning(f"Live framerate update failed for '{display_id}' ({e}).")
    await self._refresh_display_mode()
paramfpsAny
paramdisplay_idstr
= 'primary'

Returns

None
func_refresh_display_mode() -> None

Keep the display's refresh at the rule its resizes follow, after a frame rate changed without one: never below the fastest display of the layout (display_utils.refresh_output_mode, no capture restarts).

Source Code
async def _refresh_display_mode(self) -> None:
    """Keep the display's refresh at the rule its resizes follow, after a
    frame rate changed without one: never below the fastest display of the
    layout (`display_utils.refresh_output_mode`, no capture restarts)."""
    if IS_WAYLAND or not self.display_layouts:
        return
    await refresh_output_mode(max(
        float((self.display_clients.get(did) or {}).get('framerate') or self.app.framerate)
        for did in self.display_layouts))

Returns

None
func_handle_opcode_video_bitrate(bitrate, display_id='primary') -> None

Live video bitrate (kbps) for the 'vb' verb, sanitized exactly like the SETTINGS path so locked server ranges cannot be bypassed.

Source Code
async def _handle_opcode_video_bitrate(self, bitrate: Any, display_id: str = "primary") -> None:
    """Live video bitrate (kbps) for the 'vb' verb, sanitized exactly like
    the SETTINGS path so locked server ranges cannot be bypassed."""
    sanitized = sanitize_client_setting("video_bitrate", bitrate, self.cli_args, data_logger)
    if sanitized is None:
        return
    display_state = self.display_clients.get(display_id)
    if display_state is not None:
        display_state["video_bitrate"] = sanitized
    if display_id == 'primary':
        self._initial_video_bitrate = sanitized
        data_logger.debug(f"Session default video_bitrate updated to {int(sanitized)} kbps for new displays.")
    module = self._opcode_display_module(display_id)
    if module is not None:
        kbps = int(round(self._video_bitrate_kbps(display_state) if display_state else float(sanitized)))
        try:
            module.update_video_bitrate(kbps)
            self._track_capture_settings(display_id, video_bitrate_kbps=kbps)
            data_logger.info(f"Applied video bitrate live via 'vb': {kbps} kbps for '{display_id}'")
        except Exception as e:
            data_logger.warning(f"Live bitrate update failed for '{display_id}' ({e}).")
parambitrateAny
paramdisplay_idstr
= 'primary'

Returns

None
func_handle_opcode_audio_bitrate(bitrate) -> None

Live Opus bitrate (bps) for the 'ab' verb; same live-retarget with restart fallback as the SETTINGS path.

Source Code
async def _handle_opcode_audio_bitrate(self, bitrate: Any) -> None:
    """Live Opus bitrate (bps) for the 'ab' verb; same live-retarget with
    restart fallback as the SETTINGS path."""
    sanitized = sanitize_client_setting("audio_bitrate", bitrate, self.cli_args, data_logger)
    if sanitized is None:
        return
    self.app.audio_bitrate = sanitized
    for display_state in self.display_clients.values():
        display_state["audio_bitrate"] = self.app.audio_bitrate
    if self.is_pcmflux_capturing and self.pcmflux_module:
        try:
            self.pcmflux_module.update_audio_bitrate(int(self.app.audio_bitrate))
            data_logger.info(f"Applied audio bitrate live: {self.app.audio_bitrate} bps")
        except Exception as e:
            data_logger.warning(f"Live audio bitrate update failed ({e}); restarting audio pipeline.")
            # Under the audio lock like every audio start/stop, and re-checked
            # there: a concurrent one must not orphan a second AudioCapture.
            async with self._audio_lock:
                if self.is_pcmflux_capturing:
                    await self._stop_pcmflux_pipeline()
                    await self._start_pcmflux_pipeline()
parambitrateAny

Returns

None
func_handle_opcode_rate_control(mode, display_id='primary') -> None

Rate-control switch for the '_rc' verb: structural like the SETTINGS path (the encoder session must be rebuilt), honoring the server's enable_rate_control lock and a stopped display's start gating.

Source Code
async def _handle_opcode_rate_control(self, mode: Any, display_id: str = 'primary') -> None:
    """Rate-control switch for the '_rc' verb: structural like the SETTINGS
    path (the encoder session must be rebuilt), honoring the server's
    enable_rate_control lock and a stopped display's start gating."""
    enable_rate_control, _ = self.cli_args.enable_rate_control
    if not enable_rate_control:
        data_logger.debug("Server has rate control disabled. Ignoring '_rc' change.")
        return
    # Resolved by value: a duplicate enum class from another module must not
    # leave a stray 'RateControlMode.CBR' repr.
    mode_str = (mode.value if hasattr(mode, "value") else str(mode)).split(".")[-1].lower()
    sanitized = sanitize_client_setting("rate_control_mode", mode_str, self.cli_args, data_logger)
    if sanitized not in ("cbr", "crf"):
        return
    display_state = self.display_clients.get(display_id)
    if display_state is None:
        return
    if display_state.get("rate_control_mode") == sanitized:
        return
    display_state["rate_control_mode"] = sanitized
    if display_id == 'primary':
        self.rc_mode = RateControlMode(sanitized)
        data_logger.debug(f"Session default rate_control_mode updated to {sanitized} for new displays.")
    if not display_state.get('video_active', True):
        return
    layout = self.display_layouts.get(display_id)
    if layout is None:
        return
    restart_ok = False
    async with self._reconfigure_guard():
        if display_state.get('video_active', True):
            data_logger.info(f"Applied rate-control via '_rc': {sanitized} for '{display_id}'. Restarting its capture stream.")
            await self._stop_capture_for_display(display_id)
            await self._start_capture_for_display(
                display_id=display_id,
                width=layout['w'], height=layout['h'],
                x_offset=layout['x'], y_offset=layout['y']
            )
            await self._start_backpressure_task_if_needed(display_id)
            self._schedule_idr_for_display(display_id)
            await self._broadcast_live_server_settings(display_id)
            if IS_WAYLAND:
                await self._sync_wayland_realized_geometry(display_id)
            restart_ok = self._opcode_display_module(display_id) is not None
    if not restart_ok:
        data_logger.warning(f"Rate-control restart failed for '{display_id}'; falling back to full reconfiguration.")
        await self.reconfigure_displays()
parammodeAny
paramdisplay_idstr
= 'primary'

Returns

None
func_handle_opcode_crf(crf, display_id='primary') -> None

Live CRF for the '_crf' verb; rides the tunables path like SETTINGS.

Source Code
async def _handle_opcode_crf(self, crf: Any, display_id: str = 'primary') -> None:
    """Live CRF for the '_crf' verb; rides the tunables path like SETTINGS."""
    sanitized = sanitize_client_setting("video_crf", crf, self.cli_args, data_logger)
    if sanitized is None:
        return
    display_state = self.display_clients.get(display_id)
    if display_state is not None:
        display_state["video_crf"] = sanitized
    module = self._opcode_display_module(display_id)
    layout = self.display_layouts.get(display_id)
    if module is not None and layout is not None:
        try:
            fresh = self._get_capture_settings(
                display_id, layout['w'], layout['h'], layout['x'], layout['y']
            )
            module.update_tunables(fresh)
            self._track_capture_settings(display_id, fresh=fresh)
            data_logger.info(f"Applied CRF live via '_crf': {sanitized} for '{display_id}'")
        except Exception as e:
            data_logger.warning(f"Live CRF update failed for '{display_id}' ({e}).")
paramcrfAny
paramdisplay_idstr
= 'primary'

Returns

None
funcset_client_stream_box(display_id, origin_x, origin_y, scale_x, scale_y) -> None

Record where a display's page draws its stream on the user's desktop.

Rebroadcast with the layout, since a page maps a drag that crossed onto a neighbor through the neighbor's box rather than off its own edge. Only the browser knows those origins, and they are the only thing relating two viewports whose monitors, window chrome, and device pixel ratios all differ. Ignored for an unknown display or an impossible box.

Source Code
async def set_client_stream_box(self, display_id: str, origin_x: float,
                                origin_y: float, scale_x: float,
                                scale_y: float) -> None:
    """Record where a display's page draws its stream on the user's desktop.

    Rebroadcast with the layout, since a page maps a drag that crossed onto
    a neighbor through the neighbor's box rather than off its own edge.
    Only the browser knows those origins, and they are the only thing
    relating two viewports whose monitors, window chrome, and device pixel
    ratios all differ. Ignored for an unknown display or an impossible box.
    """
    display_state = self.display_clients.get(display_id)
    if display_state is None or display_id not in self.display_layouts:
        return
    if not (0.05 <= scale_x <= 100.0 and 0.05 <= scale_y <= 100.0):
        return
    if not (abs(origin_x) <= 100000.0 and abs(origin_y) <= 100000.0):
        return
    box = (origin_x, origin_y, scale_x, scale_y)
    if display_state.get("client_stream_box") == box:
        return
    # One box a page publishes is one broadcast to every client; a page that
    # alternated two would otherwise amplify at whatever rate it sent. The
    # page republishes what the layout comes back missing, so a dropped
    # update is not a lost one.
    now = time.monotonic()
    if now - display_state.get("client_stream_box_at", 0.0) < 0.2:
        return
    display_state["client_stream_box_at"] = now
    display_state["client_stream_box"] = box
    await self.broadcast_display_config()
paramdisplay_idstr
paramorigin_xfloat
paramorigin_yfloat
paramscale_xfloat
paramscale_yfloat

Returns

None
func_display_config_payload() -> dict

DISPLAY_CONFIG_UPDATE body: the display roster, the backend and whether it takes a touchpad's scroll as a finger's, plus each laid-out display's rectangle, its client's reported CSS-to-remote scale, and the desktop box that client draws it in, so a page can map a cross-display drag into its neighbor's region and, on X11, a secondary can follow the primary's density.

Source Code
def _display_config_payload(self) -> dict:
    """DISPLAY_CONFIG_UPDATE body: the display roster, the backend and whether
    it takes a touchpad's scroll as a finger's, plus each laid-out display's
    rectangle, its client's reported CSS-to-remote scale, and the desktop box
    that client draws it in, so a page can map a cross-display drag into its
    neighbor's region and, on X11, a secondary can follow the primary's
    density."""
    payload = {
        "type": "display_config_update",
        "displays": list(self.display_clients.keys()),
        "wayland": IS_WAYLAND,
        "finger_scroll": bool(self.input_handler and self.input_handler.finger_scroll_available()),
    }
    layouts = {}
    for did, rect in (self.display_layouts or {}).items():
        entry = dict(rect)
        client = self.display_clients.get(did) or {}
        scale = client.get("client_scale")
        if scale:
            entry["scale"] = scale
        box = client.get("client_stream_box")
        if box:
            (entry["originX"], entry["originY"],
             entry["scaleX"], entry["scaleY"]) = box
        layouts[did] = entry
    if layouts:
        payload["layouts"] = layouts
    return payload

Returns

dict
funcbroadcast_display_config() -> None

Broadcast the current display roster to all clients.

Source Code
async def broadcast_display_config(self) -> None:
    """Broadcast the current display roster to all clients."""
    if not self.clients:
        return

    payload = self._display_config_payload()
    message_str = f"DISPLAY_CONFIG_UPDATE,{json.dumps(payload)}"

    data_logger.debug(f"Broadcasting display config update: {message_str}")
    # Bounded: callers hold _reconfigure_lock.
    await _broadcast_to_clients(self.clients, message_str, watched=True)

Returns

None
funcrefresh_cursor_cache() -> Optional[dict]

Refresh and return the cached cursor payload for late-joining clients.

Source Code
def refresh_cursor_cache(self) -> Optional[dict]:
    """Refresh and return the cached cursor payload for late-joining clients."""
    if not self.app:
        return None

    cursor_data = None
    if self.input_handler and hasattr(self.input_handler, "get_current_cursor_data"):
        cursor_data = self.input_handler.get_current_cursor_data()

    if cursor_data is not None:
        self.app.last_cursor_sent = cursor_data

    return self.app.last_cursor_sent

Returns

typing.Optional[dict]
funcsend_current_cursor(websocket, raddr) -> None

Send the current cursor image to one client (used at connect/resume).

Source Code
async def send_current_cursor(self, websocket: web.WebSocketResponse, raddr: Any) -> None:
    """Send the current cursor image to one client (used at connect/resume)."""
    cursor_data = self.refresh_cursor_cache()
    if not cursor_data:
        return

    data_logger.debug(f"Sending current cursor to client {raddr}")
    try:
        msg_str = json.dumps(cursor_data)
        await websocket.send_str(f"cursor,{msg_str}")
    except Exception as e:
        data_logger.warning(f"Failed to send current cursor to client {raddr}: {e}")
paramwebsocketweb.WebSocketResponse
paramraddrAny

Returns

None
func_pcmflux_audio_callback(frame) -> None

Queue one encoded audio frame for broadcast.

Called from pcmflux's capture thread with an AudioFrame, so it never touches asyncio state directly: the enqueue is scheduled onto the loop with call_soon_threadsafe, and loop/queue references are snapshotted because teardown can null them concurrently.

Source Code
def _pcmflux_audio_callback(self, frame: Any) -> None:
    """Queue one encoded audio frame for broadcast.

    Called from pcmflux's capture thread with an AudioFrame, so it never
    touches asyncio state directly: the enqueue is scheduled onto the loop
    with call_soon_threadsafe, and loop/queue references are snapshotted
    because teardown can null them concurrently.
    """
    if self.is_pcmflux_capturing and frame is not None and self.pcmflux_audio_queue is not None:
        if len(frame) > 0:
            loop = self.pcmflux_capture_loop
            q = self.pcmflux_audio_queue
            if loop is None or q is None or loop.is_closed():
                return
            # Zero-copy: the AudioFrame owns the buffer (header included) and
            # frees it once the queue item drops.
            item = {'data': memoryview(frame), 'owner': frame}
            def _do_put():
                try:
                    q.put_nowait(item)
                except asyncio.QueueFull:
                    pass
            # The loop can close between the check above and here; the
            # RuntimeError would surface in pcmflux's C thread.
            try:
                loop.call_soon_threadsafe(_do_put)
            except RuntimeError:
                pass
paramframeAny

Returns

None
func_check_pcmflux_health() -> None

Restart the audio pipeline when its pcmflux worker died after start.

pcmflux's start handshake answers while the worker is still starting, so a backend that gives up afterwards (its retry ladder spent, a mid-run reconnect budget exhausted) surfaces only through last_error; the broadcast loop asks here whenever its queue stays silent. The failure is logged once per run, and the restart — the same stop/start the audio toggles use — runs as its own task (the stop cancels the broadcast loop) no more often than the restart floor.

Source Code
def _check_pcmflux_health(self) -> None:
    """Restart the audio pipeline when its pcmflux worker died after start.

    pcmflux's start handshake answers while the worker is still starting,
    so a backend that gives up afterwards (its retry ladder spent, a
    mid-run reconnect budget exhausted) surfaces only through
    `last_error`; the broadcast loop asks here whenever its queue stays
    silent. The failure is logged once per run, and the restart — the same
    stop/start the audio toggles use — runs as its own task (the stop
    cancels the broadcast loop) no more often than the restart floor.
    """
    module = self.pcmflux_module
    if module is None or not self.is_pcmflux_capturing:
        return
    error = getattr(module, "last_error", None)
    if not error:
        return
    failure = (id(module), str(error))
    if self._pcmflux_reported_failure != failure:
        self._pcmflux_reported_failure = failure
        data_logger.error(f"pcmflux audio capture failed after start: {error}")
    now = time.monotonic()
    if now - self._pcmflux_last_restart < PCMFLUX_RESTART_FLOOR_SECONDS:
        return
    self._pcmflux_last_restart = now
    _spawn_background_task(self._restart_failed_pcmflux(module), name="pcmflux-restart")

Returns

None
func_restart_failed_pcmflux(failed_module) -> None

Stop and start the audio pipeline under the audio lock, unless the failed capture was already replaced or stopped meanwhile.

Source Code
async def _restart_failed_pcmflux(self, failed_module: Any) -> None:
    """Stop and start the audio pipeline under the audio lock, unless the
    failed capture was already replaced or stopped meanwhile."""
    async with self._audio_lock:
        if self.pcmflux_module is not failed_module or not self.is_pcmflux_capturing:
            return
        data_logger.info("Restarting the audio pipeline after its capture failed.")
        await self._stop_pcmflux_pipeline()
        await self._start_pcmflux_pipeline()
paramfailed_moduleAny

Returns

None
func_pcmflux_send_audio_chunks() -> None

Broadcast queued Opus audio chunks to the primary-viewer sockets.

Runs as a long-lived task. Secondary-display sockets are excluded (they render video only; audio rides the primary connection), as is a page whose audio is off (_hears_audio), and each socket's send runs on its own (_send_audio_chunk), so a slow or dead socket holds neither the shared stream nor another client's audio. A queue that stays silent past the health interval is the cue to ask pcmflux whether the capture worker died (_check_pcmflux_health).

Source Code
async def _pcmflux_send_audio_chunks(self) -> None:
    """Broadcast queued Opus audio chunks to the primary-viewer sockets.

    Runs as a long-lived task. Secondary-display sockets are excluded (they
    render video only; audio rides the primary connection), as is a page
    whose audio is off (`_hears_audio`), and each
    socket's send runs on its own (`_send_audio_chunk`), so a slow or dead
    socket holds neither the shared stream nor another client's audio. A
    queue that stays silent past the health interval is the cue to ask
    pcmflux whether the capture worker died (_check_pcmflux_health).
    """
    data_logger.debug("pcmflux audio chunk broadcasting task started.")
    try:
        while True:
            try:
                item = await asyncio.wait_for(
                    self.pcmflux_audio_queue.get(), timeout=PCMFLUX_HEALTH_INTERVAL_SECONDS)
            except asyncio.TimeoutError:
                self._check_pcmflux_health()
                continue

            secondary_websockets = {
                client_info.get('ws')
                for did, client_info in self.display_clients.items()
                if did != 'primary' and client_info.get('ws')
            }
            primary_viewers = {ws for ws in self.clients - secondary_websockets if self._hears_audio(ws)}

            if not primary_viewers:
                self.pcmflux_audio_queue.task_done()
                continue

            # A zero-copy view over the AudioFrame, header included; sent as-is.
            message_to_send = item['data']
            for ws in primary_viewers:
                _spawn_background_task(self._send_audio_chunk(ws, message_to_send))

            self.pcmflux_audio_queue.task_done()
    except asyncio.CancelledError:
        data_logger.debug("pcmflux audio chunk broadcasting task canceled.")
    finally:
        data_logger.debug("pcmflux audio chunk broadcasting task finished.")

Returns

None
func_send_audio_chunk(ws, data) -> None

Send one audio chunk to one socket, dropping the client only when its socket stops draining (_send_live).

A send writes its whole frame before it waits on anything, and these tasks start in the order the chunks came, so a socket's chunks go out in order even while an earlier one still waits on its drain.

Source Code
async def _send_audio_chunk(self, ws: web.WebSocketResponse, data: Any) -> None:
    """Send one audio chunk to one socket, dropping the client only when its
    socket stops draining (`_send_live`).

    A send writes its whole frame before it waits on anything, and these
    tasks start in the order the chunks came, so a socket's chunks go out
    in order even while an earlier one still waits on its drain.
    """
    if ws.closed:
        self.clients.discard(ws)
        return
    try:
        await _send_live(ws, data, "Audio")
    except (ConnectionResetError, OSError, RuntimeError):
        self.clients.discard(ws)
paramwsweb.WebSocketResponse
paramdataAny

Returns

None
func_compute_audio_red_distance() -> int

RED distance for the shared audio broadcast.

WS is TCP, but the sender still drops frames under backpressure (pcmflux delivery ring drop-oldest, and this server's audio queue drops on overflow), and RED lets the client recover those within the redundancy distance.

Source Code
def _compute_audio_red_distance(self) -> int:
    """RED distance for the shared audio broadcast.

    WS is TCP, but the sender still drops frames under backpressure
    (pcmflux delivery ring drop-oldest, and this server's audio queue drops
    on overflow), and RED lets the client recover those within the
    redundancy distance.

    Returns:
        The configured distance only when the server allows it AND there is
        at least one client AND every connected client advertised
        audioRedundancy; otherwise 0 (plain frames, which decode
        everywhere) — a single non-capable or legacy (field-absent) client
        falls the whole stream back. A client still settling
        (`_red_unsettled`) is not counted either way yet.
    """
    if not self.audio_redundancy_enabled:
        return 0
    if not self.clients:
        return 0
    for ws in self.clients:
        if ws in self._red_unsettled:
            continue
        if not self.audio_redundancy_by_ws.get(ws):
            return 0
    return getattr(settings, "audio_redundancy_distance", AUDIO_RED_DISTANCE)

Returns

int

The configured distance only when the server allows it AND there is

func_regate_audio_redundancy() -> None

Recompute the RED gate for the shared audio stream and, if it flipped while capturing, restart the pipeline so the new red_distance takes effect. Callers hold _audio_lock, which serializes pipeline start and stop. A missing app means teardown (the last client leaving drops RED to 0, and the disconnect path stops the pipeline itself), so no restart is attempted then.

Source Code
async def _regate_audio_redundancy(self) -> None:
    """Recompute the RED gate for the shared audio stream and, if it flipped
    while capturing, restart the pipeline so the new red_distance takes
    effect. Callers hold `_audio_lock`, which serializes pipeline start and
    stop. A missing app means teardown (the last client leaving drops RED
    to 0, and the disconnect path stops the pipeline itself), so no restart
    is attempted then."""
    desired = self._compute_audio_red_distance()
    if desired == self._active_audio_red_distance:
        return
    if not self.is_pcmflux_capturing:
        return
    if not self.app:
        return
    data_logger.info(
        f"Audio RED gate changed ({self._active_audio_red_distance} -> {desired}); "
        "restarting audio pipeline."
    )
    await self._stop_pcmflux_pipeline()
    await self._start_pcmflux_pipeline()

Returns

None
func_release_held_input(raddr) -> None

Let go of every button and key a departing input holder left down: a tab that dies mid-drag or mid-press never sends the ups.

Source Code
async def _release_held_input(self, raddr: Any) -> None:
    """Let go of every button and key a departing input holder left down:
    a tab that dies mid-drag or mid-press never sends the ups."""
    if not self.input_handler:
        return
    if hasattr(self.input_handler, "release_mouse_buttons"):
        try:
            await self.input_handler.release_mouse_buttons()
        except Exception as e:
            data_logger.warning(f"Mouse button release on disconnect failed: {e}")
    try:
        await self.input_handler.reset_keyboard()
        data_logger.debug(f"Keyboard reset completed ({raddr}) disconnect.")
    except Exception as e_reset:
        data_logger.warning(f"Failed to reset keyboard after client disconnect: {e_reset}")
paramraddrAny

Returns

None
func_settle_red(websocket) -> None

Count a page that sent no SETTINGS within AUDIO_RED_SETTLE_S of joining a running capture as plain-only, and re-gate for it.

Source Code
async def _settle_red(self, websocket: web.WebSocketResponse) -> None:
    """Count a page that sent no SETTINGS within AUDIO_RED_SETTLE_S of
    joining a running capture as plain-only, and re-gate for it."""
    await asyncio.sleep(AUDIO_RED_SETTLE_S)
    if websocket not in self._red_unsettled:
        return
    self._red_unsettled.discard(websocket)
    if websocket in self.clients and self.is_pcmflux_capturing:
        async with self._audio_lock:
            await self._regate_audio_redundancy()
paramwebsocketweb.WebSocketResponse

Returns

None
func_apply_initial_audio_policy(websocket, display_id) -> None

Bring the audio capture in line with the session's start policy once a page's first SETTINGS is in: started for a primary page that starts with audio on, stopped when nobody left listens to a capture that policy keeps off, and otherwise re-gated for the client set that just grew.

Source Code
async def _apply_initial_audio_policy(self, websocket: web.WebSocketResponse,
                                      display_id: str) -> None:
    """Bring the audio capture in line with the session's start policy once a
    page's first SETTINGS is in: started for a primary page that starts with
    audio on, stopped when nobody left listens to a capture that policy
    keeps off, and otherwise re-gated for the client set that just grew."""
    async with self._audio_lock:
        audio_is_active = self.is_pcmflux_capturing
        if not pipeline_starts_on('audio', display_id):
            if audio_is_active and not self._audio_listeners(exclude=websocket):
                data_logger.debug("Initial setup: audio starts off for this session; stopping the idle audio capture.")
                await self._stop_pcmflux_pipeline()
        elif not audio_is_active and PCMFLUX_AVAILABLE and display_id == 'primary':
            data_logger.debug("Initial setup: Primary client connected, audio not active, attempting start.")
            await self._start_pcmflux_pipeline()
        elif not PCMFLUX_AVAILABLE and not audio_is_active:
            data_logger.warning("Initial setup: Audio pipeline (server-to-client) cannot be started (pcmflux not available).")
        else:
            await self._regate_audio_redundancy()
paramwebsocketweb.WebSocketResponse
paramdisplay_idstr

Returns

None
func_start_pcmflux_pipeline() -> bool

Start the pcmflux audio capture and the shared broadcast task.

Resolves the RED distance for the current client set at start, so a gate change while running requires a restart (see _regate_audio_redundancy). Callers hold _audio_lock.

Source Code
async def _start_pcmflux_pipeline(self) -> bool:
    """Start the pcmflux audio capture and the shared broadcast task.

    Resolves the RED distance for the current client set at start, so a
    gate change while running requires a restart (see
    _regate_audio_redundancy). Callers hold `_audio_lock`.

    Returns:
        True when capturing afterwards (already-running counts); False when
        audio is disabled, pcmflux is unavailable, or the start failed (a
        partial start is cleaned up).
    """
    if not settings.audio_enabled[0]:
        data_logger.debug("Audio is disabled by server settings. Not starting pipeline.")
        return False
    if not PCMFLUX_AVAILABLE:
        data_logger.error("Cannot start audio pipeline: pcmflux library not available.")
        return False
    if self.is_pcmflux_capturing:
        data_logger.debug("pcmflux audio pipeline is already capturing.")
        return True
    if self.pcmflux_module is not None:
        # A start canceled between the capture's open and its bookkeeping
        # (its page left) is retired before another module replaces it.
        await self._stop_pcmflux_pipeline()
    if not self.app:
        data_logger.error("Cannot start pcmflux: self.app (SelkiesStreamingApp instance) is not available.")
        return False

    self.pcmflux_capture_loop = self.capture_loop or asyncio.get_running_loop()
    if not self.pcmflux_capture_loop:
        data_logger.error("Cannot start pcmflux: asyncio event loop not found.")
        return False

    await ensure_capture_sink(self.audio_device_name)
    try:
        frame_ms = float(getattr(settings, 'audio_frame_duration_ms', '20') or 20)
        capture_settings = opus_capture_settings(self.audio_device_name, self.app.audio_channels,
                                                 int(self.app.audio_bitrate), frame_ms)
        capture_settings.debug_logging = self.cli_args.debug[0]
        # pcmflux's native [0x01,0x00] header goes on the wire; no Python prepend/copy.
        capture_settings.omit_audio_header = False
        red_distance = self._compute_audio_red_distance()
        capture_settings.red_distance = red_distance
        self._active_audio_red_distance = red_distance
        self.pcmflux_settings = capture_settings

        data_logger.info(f"Starting pcmflux audio pipeline: device '{self.audio_device_name}', "
                         f"{capture_settings.opus_bitrate} bps, {capture_settings.channels} ch, "
                         f"RED distance {red_distance}.")

        self.pcmflux_callback = self._pcmflux_audio_callback
        self.pcmflux_module = AudioCapture()
        self.pcmflux_audio_queue = asyncio.Queue(maxsize=getattr(self, 'BACKPRESSURE_QUEUE_SIZE', 120))

        await self.pcmflux_capture_loop.run_in_executor(
            None, self.pcmflux_module.start_capture, self.pcmflux_settings, self.pcmflux_callback
        )

        # The start handshake answers before the worker is up; a run that
        # already died reports through last_error.
        state = getattr(self.pcmflux_module, "state", "running")
        error = getattr(self.pcmflux_module, "last_error", None)
        if state == "failed" or error:
            raise RuntimeError(f"capture {state}: {error}")
        self.is_pcmflux_capturing = True
        if self.pcmflux_send_task is None or self.pcmflux_send_task.done():
            self.pcmflux_send_task = asyncio.create_task(self._pcmflux_send_audio_chunks())

        data_logger.debug(f"pcmflux audio capture state: {state}.")
        return True
    except Exception as e:
        data_logger.error(f"Failed to start pcmflux audio pipeline: {e}", exc_info=True)
        await self._stop_pcmflux_pipeline()
        return False

Returns

bool

True when capturing afterwards (already-running counts); False when

func_stop_pcmflux_pipeline() -> bool

Stop the audio capture and broadcast task; idempotent.

The capturing flag is cleared first so the capture-thread callback stops queueing chunks before the queue is dropped.

Source Code
async def _stop_pcmflux_pipeline(self) -> bool:
    """Stop the audio capture and broadcast task; idempotent.

    The capturing flag is cleared first so the capture-thread callback
    stops queueing chunks before the queue is dropped.
    """
    if not self.is_pcmflux_capturing and not self.pcmflux_module:
        return True

    data_logger.info("Stopping pcmflux audio pipeline...")
    self.is_pcmflux_capturing = False

    if self.pcmflux_send_task:
        self.pcmflux_send_task.cancel()
        try:
            await self.pcmflux_send_task
        except asyncio.CancelledError:
            pass
        self.pcmflux_send_task = None

    if self.pcmflux_module:
        try:
            if self.pcmflux_capture_loop:
                await self.pcmflux_capture_loop.run_in_executor(
                    None, self.pcmflux_module.stop_capture
                )
        except Exception as e:
            data_logger.error(f"Error during pcmflux stop_capture: {e}")
        finally:
            del self.pcmflux_module
            self.pcmflux_module = None

    self.pcmflux_audio_queue = None
    data_logger.debug("pcmflux audio pipeline stopped.")
    return True

Returns

bool
funcshutdown_pipelines() -> None

Stop all capture pipelines; the ONLY way pipelines are stopped programmatically.

Deadlock-proof by construction: reconfigure_displays() self-acquires the reconfigure lock, so it runs first and outside the guard; the backpressure teardown then runs under the guard and the audio teardown under the audio lock inside it (a disconnect/connect race could otherwise tear down audio a new client just started), and none of the awaited teardowns re-acquire either lock.

Source Code
async def shutdown_pipelines(self) -> None:
    """Stop all capture pipelines; the ONLY way pipelines are stopped programmatically.

    Deadlock-proof by construction: reconfigure_displays() self-acquires
    the reconfigure lock, so it runs first and outside the guard; the
    backpressure teardown then runs under the guard and the audio teardown
    under the audio lock inside it (a disconnect/connect race could
    otherwise tear down audio a new client just started), and none of the
    awaited teardowns re-acquire either lock.
    """
    logger.debug("Initiating unified pipeline shutdown...")
    await self.reconfigure_displays()
    async with self._reconfigure_guard():
        async with self._audio_lock:
            await self._stop_pcmflux_pipeline()
            if self.pcmflux_send_task and not self.pcmflux_send_task.done():
                self.pcmflux_send_task.cancel()
                try:
                    await self.pcmflux_send_task
                except asyncio.CancelledError:
                    pass
        if self.display_clients:
            stop_bp_tasks = [
                self._ensure_backpressure_task_is_stopped(disp_id)
                for disp_id in self.display_clients.keys()
            ]
            await asyncio.gather(*stop_bp_tasks, return_exceptions=True)
    logger.debug("Unified pipeline shutdown complete.")

Returns

None
func_ensure_backpressure_task_is_stopped(display_id, notify=True) -> bool

Cancel and clean up the backpressure task for a specific display.

Source Code
async def _ensure_backpressure_task_is_stopped(self, display_id: str, notify: bool = True) -> bool:
    """Cancel and clean up the backpressure task for a specific display.

    Args:
        display_id: The display whose task to stop.
        notify: When True and a task was actually running, reset the frame
            ids and notify the client(s).

    Returns:
        Whether the pipeline-reset notification was sent, so callers that
        must guarantee a reset (capture stop) can send it exactly once
        themselves when no task was running.
    """
    display_state = self.display_clients.get(display_id)
    if not display_state:
        return False

    task_was_running = False
    task = display_state.get('backpressure_task')
    if task and not task.done():
        data_logger.debug(f"Ensuring frame backpressure task for '{display_id}' is stopped.")
        task.cancel()
        try:
            await task
            task_was_running = True
        except asyncio.CancelledError:
            data_logger.debug(f"Backpressure task for '{display_id}' canceled successfully.")
            task_was_running = True
        except Exception as e_cancel:
            data_logger.error(f"Error awaiting cancellation for '{display_id}' backpressure task: {e_cancel}")
        display_state['backpressure_task'] = None

    display_state['backpressure_enabled'] = True

    if task_was_running and notify:
        data_logger.debug(f"Backpressure task for '{display_id}' was stopped. Resetting its frame IDs.")
        await self._reset_frame_ids_and_notify(display_id)
        return True
    return False
paramdisplay_idstr

The display whose task to stop.

paramnotifybool
= True

When True and a task was actually running, reset the frame ids and notify the client(s).

Returns

bool

Whether the pipeline-reset notification was sent, so callers that

func_reset_frame_ids_and_notify(display_id) -> None

Reset a display's frame-id state and send PIPELINE_RESETTING.

For the primary display the reset is broadcast to ALL clients (shared viewers decode the same stream); a secondary notifies only its own socket. Every id-keyed artifact (send stamps, RTT samples, the fps estimator's baseline) resets with the numbering, since a stale stamp matched by a NEW id of the same value manufactures a giant RTT sample that poisons the smoothed estimate. The notify sends are bounded: this runs under _video_capture_lock, so one stalled client must not wedge every display's start/stop; a timed-out socket is dropped and closed rather than reused, and the id state was already reset either way.

Source Code
async def _reset_frame_ids_and_notify(self, display_id: str) -> None:
    """Reset a display's frame-id state and send PIPELINE_RESETTING.

    For the primary display the reset is broadcast to ALL clients (shared
    viewers decode the same stream); a secondary notifies only its own
    socket. Every id-keyed artifact (send stamps, RTT samples, the fps
    estimator's baseline) resets with the numbering, since a stale stamp
    matched by a NEW id of the same value manufactures a giant RTT sample
    that poisons the smoothed estimate. The notify sends are bounded: this
    runs under _video_capture_lock, so one stalled client must not wedge
    every display's start/stop; a timed-out socket is dropped and closed
    rather than reused, and the id state was already reset either way.
    """
    display_state = self.display_clients.get(display_id)
    if not display_state:
        return

    data_logger.debug(f"Resetting frame IDs for display '{display_id}'.")
    display_state['last_sent_frame_id'] = 0
    display_state['has_sent_any_frame'] = False
    display_state['acknowledged_frame_id'] = -1
    display_state['acked_sent_at'] = None
    sent_ts = display_state.get('sent_timestamps')
    if sent_ts is not None:
        sent_ts.clear()
    rtt_samples = display_state.get('rtt_samples')
    if rtt_samples is not None:
        rtt_samples.clear()
    display_state['smoothed_rtt'] = 0.0
    display_state.pop('_fps_sample_acked', None)
    display_state.pop('_fps_sample_time', None)
    _expect_key_frame(display_state)

    message = f"PIPELINE_RESETTING {display_id}"

    if display_id == 'primary' and self.clients:
        data_logger.debug(f"Broadcasting primary pipeline reset to all {len(self.clients)} clients: {message}")
        await _broadcast_to_clients(self.clients, message, watched=True)
    else:
        websocket = display_state.get('ws')
        if websocket:
            try:
                await _send_live(websocket, message, "Pipeline reset")
            except ConnectionResetError:
                self.clients.discard(websocket)
            except (OSError, RuntimeError):
                data_logger.warning(f"Could not notify client for '{display_id}' of reset; connection closed.")

    display_state['backpressure_enabled'] = True
    display_state['unacked_since'] = None
    display_state['stall_gated_at'] = None
paramdisplay_idstr

Returns

None
func_start_backpressure_task_if_needed(display_id) -> None

Start the backpressure task for a specific display if not already running.

Backend-agnostic: frame ids, ACKs, and RTT flow identically on Wayland. A task restart is not a pipeline death, so it never notifies: the capture (re)start handles stream freshness, and the client reset belongs to the capture-stop path alone.

Source Code
async def _start_backpressure_task_if_needed(self, display_id: str) -> None:
    """Start the backpressure task for a specific display if not already running.

    Backend-agnostic: frame ids, ACKs, and RTT flow identically on Wayland.
    A task restart is not a pipeline death, so it never notifies: the
    capture (re)start handles stream freshness, and the client reset
    belongs to the capture-stop path alone.
    """
    display_state = self.display_clients.get(display_id)
    if not display_state:
        data_logger.error(f"Cannot start backpressure task: display '{display_id}' not found.")
        return

    await self._ensure_backpressure_task_is_stopped(display_id, notify=False)

    task = display_state.get('backpressure_task')
    if not task or task.done():
        new_task = asyncio.create_task(self._run_frame_backpressure_logic(display_id))
        display_state['backpressure_task'] = new_task
        data_logger.debug(f"New frame backpressure task started for display '{display_id}'.")
    else:
        data_logger.warning(f"Backpressure task for '{display_id}' was already running. Not starting a new one.")
paramdisplay_idstr

Returns

None
func_active_primary_consumers(exclude=None) -> set

Sockets still consuming the primary broadcast.

Every client except the secondary displays' owners, minus the paused ones. A paused viewer with a deferred rejoin pending counts as active — it keeps the capture alive under a waking viewer, while genuinely hidden ones let an all-tabs-hidden session stop encoding.

Source Code
def _active_primary_consumers(self, exclude: Optional[web.WebSocketResponse] = None) -> set:
    """Sockets still consuming the primary broadcast.

    Every client except the secondary displays' owners, minus the paused
    ones. A paused viewer with a deferred rejoin pending counts as active —
    it keeps the capture alive under a waking viewer, while genuinely
    hidden ones let an all-tabs-hidden session stop encoding.

    Args:
        exclude: Drops the socket whose STOP_VIDEO is in flight.
    """
    secondary_ws = {
        info.get('ws')
        for did, info in self.display_clients.items()
        if did != 'primary'
    }
    waking = set(self._deferred_viewer_rejoins)
    consumers = self.clients - secondary_ws - (self.video_paused_clients - waking)
    if exclude is not None:
        consumers.discard(exclude)
    return consumers
paramexcludeOptional[web.WebSocketResponse]
= None

Drops the socket whose STOP_VIDEO is in flight.

Returns

set
func_audio_listeners(exclude=None) -> set

Sockets the audio fan-out serves: every client but the secondary displays' owners, minus exclude.

Source Code
def _audio_listeners(self, exclude: Optional[web.WebSocketResponse] = None) -> set:
    """Sockets the audio fan-out serves: every client but the secondary
    displays' owners, minus `exclude`."""
    secondary_ws = {
        info.get('ws')
        for did, info in self.display_clients.items()
        if did != 'primary'
    }
    listeners = self.clients - secondary_ws
    if exclude is not None:
        listeners.discard(exclude)
    return listeners
paramexcludeOptional[web.WebSocketResponse]
= None

Returns

set
func_video_start_state(websocket, display_id) -> bool

The video_active a session owner's fresh page starts with.

The start policy names it. An off state pauses this socket (the STOP_VIDEO rule): it leaves the primary fan-out until its START_VIDEO, so a capture a shared viewer starts meanwhile is not delivered to it, and while viewers consume the capture it keeps running for them.

Source Code
def _video_start_state(self, websocket: web.WebSocketResponse, display_id: str) -> bool:
    """The `video_active` a session owner's fresh page starts with.

    The start policy names it. An off state pauses this socket (the
    STOP_VIDEO rule): it leaves the primary fan-out until its START_VIDEO,
    so a capture a shared viewer starts meanwhile is not delivered to it,
    and while viewers consume the capture it keeps running for them.
    """
    if pipeline_starts_on('video', display_id):
        return True
    if display_id == 'primary':
        self.video_paused_clients.add(websocket)
        if self._active_primary_consumers(exclude=websocket):
            return True
    data_logger.info(f"Display '{display_id}' starts with video off; its capture waits for START_VIDEO.")
    return False
paramwebsocketweb.WebSocketResponse
paramdisplay_idstr

Returns

bool
func_primary_reconnect_pending() -> bool

Whether the primary display entry is being held for a socket that is already gone: the reconnect grace keeps the capture warm so a reloading page resumes on it instead of paying a full pipeline rebuild.

Source Code
def _primary_reconnect_pending(self) -> bool:
    """Whether the primary display entry is being held for a socket that is
    already gone: the reconnect grace keeps the capture warm so a reloading
    page resumes on it instead of paying a full pipeline rebuild."""
    entry = self.display_clients.get('primary')
    return entry is not None and entry.get('ws') not in self.clients

Returns

bool
func_stop_stats_collectors() -> None

Ends the resource monitor with the last client, nulling the ref so a fast reconnect restarts it and never reads a dead one's figures.

Source Code
async def _stop_stats_collectors(self) -> None:
    """Ends the resource monitor with the last client, nulling the ref so
    a fast reconnect restarts it and never reads a dead one's figures."""
    monitor, self._resource_monitor = self._resource_monitor, None
    if monitor is not None:
        await monitor.stop()

Returns

None
func_controller_socket(display_id) -> Optional[web.WebSocketResponse]

The live socket registered for a display, unless a viewer holds it.

Source Code
def _controller_socket(self, display_id: str) -> Optional[web.WebSocketResponse]:
    """The live socket registered for a display, unless a viewer holds it."""
    ws = (self.display_clients.get(display_id) or {}).get('ws')
    if ws is None or ws not in self.clients:
        return None
    if client_permissions.get(ws, {}).get("role") == "viewer":
        return None
    return ws
paramdisplay_idstr

Returns

typing.Optional[aiohttp.web.aiohttp.web.WebSocketResponse]
func_send_stream_message(ws, message) -> None

One stream_info or stream_stats message to one socket; a socket still busy with the last one is skipped rather than queued behind.

Source Code
async def _send_stream_message(self, ws: web.WebSocketResponse, message: Dict[str, Any]) -> None:
    """One `stream_info` or `stream_stats` message to one socket; a socket
    still busy with the last one is skipped rather than queued behind."""
    if ws in self._stats_sending:
        return
    self._stats_sending.add(ws)
    try:
        await asyncio.wait_for(ws.send_str(json.dumps(message)), timeout=2.0)
    except (asyncio.TimeoutError, ConnectionResetError, OSError, RuntimeError):
        pass
    finally:
        self._stats_sending.discard(ws)
paramwsweb.WebSocketResponse
parammessageDict[str, Any]

Returns

None
func_publish_stream_info(display_id, info) -> None

Tell a display's controller what its capture streams and how.

Source Code
async def _publish_stream_info(self, display_id: str, info: Dict[str, Any]) -> None:
    """Tell a display's controller what its capture streams and how."""
    ws = self._controller_socket(display_id)
    if ws is not None:
        await self._send_stream_message(
            ws, {"type": "stream_info", "displayId": display_id, "info": info})
paramdisplay_idstr
paraminfoDict[str, Any]

Returns

None
func_watch_stream(display_id, module) -> None

Follow a fresh capture's description for its display's controller.

Source Code
def _watch_stream(self, display_id: str, module: Any) -> None:
    """Follow a fresh capture's description for its display's controller."""
    watch = self._stream_watches.get(display_id)
    if watch is None:
        watch = self._stream_watches[display_id] = stream_stats.StreamWatch(
            display_id, self._publish_stream_info)
    entry = self.display_clients.get(display_id) or {}
    watch.follow(module, entry.get('encoder') or self.app.encoder, bool(entry.get('use_cpu')))
paramdisplay_idstr
parammoduleAny

Returns

None
func_rush_stream_stats(display_id) -> None

A page just opened its stats: its display's encode is differenced from now, and its first figures follow soon (ResourceMonitor.rush).

Source Code
def _rush_stream_stats(self, display_id: Optional[str]) -> None:
    """A page just opened its stats: its display's encode is differenced from
    now, and its first figures follow soon (`ResourceMonitor.rush`)."""
    watch = self._stream_watches.get(display_id) if display_id else None
    if watch is not None:
        watch.rates()
    if self._resource_monitor is not None:
        asyncio.ensure_future(self._resource_monitor.rush())
paramdisplay_idOptional[str]

Returns

None
func_send_stream_stats(_now) -> None

Resource-monitor tick: one stream_stats to every subscribed controller, with its own display's encode figures, round trip, and throttle state.

Source Code
async def _send_stream_stats(self, _now: float) -> None:
    """Resource-monitor tick: one `stream_stats` to every subscribed controller,
    with its own display's encode figures, round trip, and throttle state."""
    if not self._stats_subscribers:
        return
    host = stream_stats.host_stats(self._resource_monitor)
    for display_id, state in list(self.display_clients.items()):
        ws = self._controller_socket(display_id)
        if ws is None or ws not in self._stats_subscribers:
            continue
        stats = dict(host)
        watch = self._stream_watches.get(display_id)
        if watch is not None:
            stats.update(watch.rates())
        stats["rtt_ms"] = round(state.get('smoothed_rtt', 0.0), 1)
        stats["throttled"] = not state.get('backpressure_enabled', True)
        target = self._cbr_target_kbps(display_id)
        if target:
            stats["target_mbps"] = round(target / 1000, 2)
        asyncio.ensure_future(self._send_stream_message(
            ws, {"type": "stream_stats", "displayId": display_id, "stats": stats}))
param_nowfloat

Returns

None
func_stop_primary_if_unconsumed(reason) -> None

Stop the primary capture once nothing decodes it — the last unpaused consumer hid its tab or disconnected. Hiding and disconnecting take the same verdict here; only a pending reconnect grace keeps the capture warm. A resume restarts it (START_VIDEO from the display owner, or the viewer path's capture ensure).

Source Code
async def _stop_primary_if_unconsumed(self, reason: str) -> None:
    """Stop the primary capture once nothing decodes it — the last unpaused
    consumer hid its tab or disconnected. Hiding and disconnecting take the
    same verdict here; only a pending reconnect grace keeps the capture warm.
    A resume restarts it (START_VIDEO from the display owner, or the viewer
    path's capture ensure)."""
    if 'primary' not in self.capture_instances:
        return
    if self._active_primary_consumers() or self._primary_reconnect_pending():
        return
    data_logger.info(f"{reason} Stopping the 'primary' capture.")
    primary_entry = self.display_clients.get('primary')
    if primary_entry is not None:
        primary_entry['video_active'] = False
    await self._stop_capture_for_display('primary')
paramreasonstr

Returns

None
func_cancel_deferred_rejoin(websocket) -> None

Drop a pending deferred rejoin for this socket. A STOP_VIDEO (or a disconnect) arriving after a throttled resume supersedes it: the rejoin would otherwise un-pause a tab that is hidden again, and the socket would keep counting as a live consumer until it fired.

Source Code
def _cancel_deferred_rejoin(self, websocket: web.WebSocketResponse) -> None:
    """Drop a pending deferred rejoin for this socket. A STOP_VIDEO (or a
    disconnect) arriving after a throttled resume supersedes it: the rejoin
    would otherwise un-pause a tab that is hidden again, and the socket would
    keep counting as a live consumer until it fired."""
    rejoin_task = self._deferred_viewer_rejoins.pop(websocket, None)
    if rejoin_task is not None:
        rejoin_task.cancel()
paramwebsocketweb.WebSocketResponse

Returns

None
func_schedule_deferred_viewer_rejoin(websocket, delay) -> None

Rejoin a rapid-resume-throttled viewer once the resume floor passes. The client already believes it resumed, so a silent discard would leave the socket paused until its stall watchdog; at most one deferred rejoin is pending per socket.

Source Code
def _schedule_deferred_viewer_rejoin(self, websocket: web.WebSocketResponse, delay: float) -> None:
    """Rejoin a rapid-resume-throttled viewer once the resume floor passes.
    The client already believes it resumed, so a silent discard would leave
    the socket paused until its stall watchdog; at most one deferred rejoin
    is pending per socket."""
    if websocket in self._deferred_viewer_rejoins:
        return

    async def _rejoin():
        try:
            await asyncio.sleep(max(0.05, delay))
            if websocket not in self.clients or websocket not in self.video_paused_clients:
                return
            self.last_start_video_request_times[websocket] = time.monotonic()
            self.video_paused_clients.discard(websocket)
            try:
                await websocket.send_str("PIPELINE_RESETTING primary")
            except (ConnectionResetError, OSError, RuntimeError):
                return
            # A controller tab-hide can tear the capture down mid-resume; an IDR
            # request is then a no-op and the reset decoder would wait forever.
            if 'primary' in self.capture_instances:
                self._schedule_idr_for_display('primary')
            else:
                await self._ensure_viewer_capture()
        finally:
            self._deferred_viewer_rejoins.pop(websocket, None)

    self._deferred_viewer_rejoins[websocket] = asyncio.create_task(_rejoin())
paramwebsocketweb.WebSocketResponse
paramdelayfloat

Returns

None
func_video_relay_budget(display_id, fallback) -> int

Skip-ahead byte budget for one client's video relay.

VIDEO_RELAY_BUDGET_SECONDS of stream at the display's CURRENT configured bitrate (1 kbps = 125 B/s), floored so low-bitrate streams keep absorbing transport jitter. Read from the live capture settings at relay creation so in-place restarts (settings changes that reuse the capture callback) are honored.

Source Code
def _video_relay_budget(self, display_id: str, fallback: int) -> int:
    """Skip-ahead byte budget for one client's video relay.

    VIDEO_RELAY_BUDGET_SECONDS of stream at the display's CURRENT
    configured bitrate (1 kbps = 125 B/s), floored so low-bitrate streams
    keep absorbing transport jitter. Read from the live capture settings
    at relay creation so in-place restarts (settings changes that reuse
    the capture callback) are honored.

    Args:
        display_id: The display whose configured bitrate sizes the budget.
        fallback: Covers the start window before capture_instances is
            registered.
    """
    inst = self.capture_instances.get(display_id)
    cs = inst.get('settings') if inst else None
    if cs is None:
        return fallback
    kbps = int(getattr(cs, 'video_bitrate_kbps', 0) or 0)
    return max(VIDEO_RELAY_BUDGET_MIN_BYTES,
               int(kbps * 125 * VIDEO_RELAY_BUDGET_SECONDS))
paramdisplay_idstr

The display whose configured bitrate sizes the budget.

paramfallbackint

Covers the start window before capture_instances is registered.

Returns

int
func_close_video_relays(display_id) -> None

Stop every per-client video relay for this display. Graceful: each relay finishes its in-flight send and its task removes itself.

Source Code
def _close_video_relays(self, display_id: str) -> None:
    """Stop every per-client video relay for this display. Graceful: each
    relay finishes its in-flight send and its task removes itself."""
    group = self.video_relay_groups.pop(display_id, None)
    if group:
        for relay in list(group.values()):
            relay.stop()
    for held in (False, True):
        self.common_frames.pop((display_id, held), None)
paramdisplay_idstr

Returns

None
func_schedule_idr_for_display(display_id) -> None

Ask the encoder for a fresh keyframe on this display.

request_idr_frame is non-blocking in pixelflux (an atomic flag or a channel send) and idempotent, so it runs inline on the event loop.

Source Code
def _schedule_idr_for_display(self, display_id: str) -> None:
    """Ask the encoder for a fresh keyframe on this display.

    request_idr_frame is non-blocking in pixelflux (an atomic flag or a
    channel send) and idempotent, so it runs inline on the event loop.
    """
    module = self._opcode_display_module(display_id)
    if module:
        try:
            module.request_idr_frame()
        except Exception:
            pass
paramdisplay_idstr

Returns

None
func_relay_lost(websocket, display_id, frame_id, reach) -> bool

Tell the encoder a client's relay left frame_id and the frames after it out (_VideoRelay), as the client's own LOST_FRAME would: the encoder predicts past them and the client resumes without a key frame. The relay paces these itself; a run past its reach, which may cost the shared stream a key frame, is taken as a key-frame request is (_repair_taken). False when refused; the relay asks again on its next held frame.

Source Code
def _relay_lost(self, websocket: Any, display_id: str, frame_id: int, reach: bool) -> bool:
    """Tell the encoder a client's relay left `frame_id` and the frames after it out
    (`_VideoRelay`), as the client's own LOST_FRAME would: the encoder predicts past
    them and the client resumes without a key frame. The relay paces these itself; a
    run past its `reach`, which may cost the shared stream a key frame, is taken as a
    key-frame request is (`_repair_taken`). False when refused; the relay asks again
    on its next held frame."""
    if not reach and not self._repair_taken(websocket, display_id, "keyframe"):
        return False
    self._schedule_invalidation(display_id, frame_id, withheld=True)
    return True
paramwebsocketAny
paramdisplay_idstr
paramframe_idint
paramreachbool

Returns

bool
funccommon_frames_for(display_id, held=True) -> CommonFrames

The frames every client of the display holds, or where not held was handed (CommonFrames).

Source Code
def common_frames_for(self, display_id: str, held: bool = True) -> CommonFrames:
    """The frames every client of the display holds, or where not `held` was
    handed (`CommonFrames`)."""
    common = self.common_frames.get((display_id, held))
    if common is None:
        common = self.common_frames[(display_id, held)] = CommonFrames(
            functools.partial(self._acknowledge_frame, display_id, held=held))
    return common
paramdisplay_idstr
paramheldbool
= True

Returns

selkies.display_utils.CommonFrames
func_acknowledge_frame(display_id, frame_id, held=True) -> None

Tell the display's encoder every client holds frame_id, or where not held was handed it (CommonFrames).

Source Code
def _acknowledge_frame(self, display_id: str, frame_id: int, held: bool = True) -> None:
    """Tell the display's encoder every client holds `frame_id`, or where not
    `held` was handed it (`CommonFrames`)."""
    module = self._opcode_display_module(display_id)
    if not module:
        return
    try:
        module.acknowledge_reference(frame_id & 0xFFFF, held=held)
    except Exception:
        return
paramdisplay_idstr
paramframe_idint
paramheldbool
= True

Returns

None
func_schedule_invalidation(display_id, frame_id, withheld=False) -> None

Tell the display's encoder a client lost frame_id, or a relay withheld it (withheld), so the frames after it stop predicting from it. Non-blocking in pixelflux, like the keyframe request; logged once per display per five seconds with the count of the rest.

Source Code
def _schedule_invalidation(self, display_id: str, frame_id: int, withheld: bool = False) -> None:
    """Tell the display's encoder a client lost `frame_id`, or a relay withheld it
    (`withheld`), so the frames after it stop predicting from it. Non-blocking in
    pixelflux, like the keyframe request; logged once per display per five seconds
    with the count of the rest."""
    module = self._opcode_display_module(display_id)
    if not module:
        return
    try:
        try:
            module.invalidate_reference(frame_id & 0xFFFF, withheld=withheld)
        except TypeError:
            # A pixelflux that has no withheld report takes it as a loss.
            module.invalidate_reference(frame_id & 0xFFFF)
    except Exception:
        return
    now = time.monotonic()
    last, more = self._invalidation_log.get(display_id, (0.0, 0))
    if now - last >= 5.0:
        suffix = f" (+{more} more in the last 5 s)" if more else ""
        data_logger.info(f"Display '{display_id}': frame {frame_id} lost by a client; the encoder predicts past it.{suffix}")
        self._invalidation_log[display_id] = (now, 0)
    else:
        self._invalidation_log[display_id] = (last, more + 1)
paramdisplay_idstr
paramframe_idint
paramwithheldbool
= False

Returns

None
func_second_screen_availability() -> tuple[bool, str]

Whether this session can actually attach a second display.

The admin flag gates first. Past it X11 mints a RandR monitor on demand; host capture is bounded by the host compositor's real output count (unknown until the first capture start establishes the host session); and the self-composited Wayland backend rides the input handler's session-screen ladder: the session compositor's control socket grows a screen on demand, a spare screen the session already opened is arranged instead without one, and a session running directly on the capture compositor needs neither.

Source Code
def _second_screen_availability(self) -> tuple[bool, str]:
    """Whether this session can actually attach a second display.

    The admin flag gates first. Past it X11 mints a RandR monitor on
    demand; host capture is bounded by the host compositor's real output
    count (unknown until the first capture start establishes the host
    session); and the self-composited Wayland backend rides the
    input handler's session-screen ladder: the session compositor's
    control socket grows a screen on demand, a spare screen the session
    already opened is arranged instead without one, and a session running
    directly on the capture compositor needs neither.

    Returns:
        `(available, reason)`; the reason is empty when available.
    """
    enabled, _ = self.cli_args.second_screen
    if not enabled:
        return False, "Second screens are disabled on this server."
    if not IS_WAYLAND:
        return True, ""
    if (self.cli_args.wayland_host_display or '').strip():
        capacity = self._host_output_capacity
        if capacity is None or capacity < 0:
            return False, "The host compositor's outputs are not known yet."
        if capacity < 2:
            return False, "The host compositor has a single output, so a second display has nothing to capture."
        return True, ""
    if self.input_handler is None:
        return False, "The input system is not up yet."
    return self.input_handler.session_screen_capability()

Returns

tuple

(available, reason); the reason is empty when available.

func_refresh_second_screen_capacity() -> bool

Re-read what bounds a second display on this backend.

Host capture re-reads how many outputs the host exposes; the nested Wayland backend re-probes the session compositor's control socket. X11 has no bound.

Source Code
async def _refresh_second_screen_capacity(self) -> bool:
    """Re-read what bounds a second display on this backend.

    Host capture re-reads how many outputs the host exposes; the nested
    Wayland backend re-probes the session compositor's control socket.
    X11 has no bound.

    Returns:
        True when the answer changed, i.e. the second-screen availability
        that clients were told may have flipped.
    """
    if not IS_WAYLAND:
        return False
    if not (self.cli_args.wayland_host_display or '').strip():
        if self.input_handler is None:
            return False
        before = self.input_handler.session_screen_capability()[0]
        fresh = await self.input_handler.probe_session_screen_capability()
        return fresh[0] != before
    module = self._wayland_control_module()
    if module is None:
        return False
    try:
        capacity = int(await asyncio.to_thread(module.output_capacity))
    except Exception as e:
        data_logger.warning(f"Wayland output capacity query failed: {e}")
        return False
    changed = capacity != self._host_output_capacity
    self._host_output_capacity = capacity
    return changed

Returns

bool

True when the answer changed, i.e. the second-screen availability

func_settings_payload_for_display(display_id) -> dict

Client settings snapshot as it applies to one display.

build_client_settings_payload() publishes boot config, so the stream settings are patched to what this display streams with (with_live_stream_settings): clients key their wire-format demux off its encoder (its stored pick, else the session default a fresh capture would use) and drop every chunk of any other format, and a page with no pick of its own shows and keeps the display's values. Also carried: ws_max_message_bytes (transport capacity, so the client sizes multipart chunks to the whole frame), and second_screen and ui_sidebar_show_apps as effective availability — the admin flag and what the backend can actually do — so dashboards never offer a display the server would immediately kill, nor an apps panel whose every button would fail; and apps_installed, the set the runner reports, which no browser's own storage can answer for a session opened somewhere else — absent until the runner has answered, because a client told nothing is installed clears its own record.

Source Code
def _settings_payload_for_display(self, display_id: str) -> dict:
    """Client settings snapshot as it applies to one display.

    build_client_settings_payload() publishes boot config, so the stream
    settings are patched to what this display streams with
    (`with_live_stream_settings`): clients key their wire-format demux off
    its encoder (its stored pick, else the session default a fresh capture
    would use) and drop every chunk of any other format, and a page with no
    pick of its own shows and keeps the display's values. Also carried: `ws_max_message_bytes` (transport capacity, so
    the client sizes multipart chunks to the whole frame), and
    `second_screen` and `ui_sidebar_show_apps` as effective
    availability — the admin flag and what the backend can actually do — so
    dashboards never offer a display the server would immediately kill, nor
    an apps panel whose every button would fail; and `apps_installed`, the
    set the runner reports, which no browser's own storage can answer for a
    session opened somewhere else — absent until the runner has answered,
    because a client told nothing is installed clears its own record.
    """
    live = self._display_settings(display_id)
    if not live.get('encoder') and self.app.encoder:
        live['encoder'] = self.app.encoder
    payload = with_live_stream_settings(build_client_settings_payload(), live)
    payload['ws_max_message_bytes'] = {"value": WS_MAX_MESSAGE_BYTES}
    available, _ = self._second_screen_availability()
    entry = payload.get('second_screen')
    if isinstance(entry, dict) and entry.get('value') and not available:
        payload['second_screen'] = dict(entry, value=False)
    apps = payload.get('ui_sidebar_show_apps')
    if (isinstance(apps, dict) and apps.get('value')
            and self.input_handler and not self.input_handler.apps_available()):
        payload['ui_sidebar_show_apps'] = dict(apps, value=False)
    installed = self.input_handler.installed_apps() if self.input_handler else None
    if installed is not None:
        payload['apps_installed'] = {"value": installed}
    return payload
paramdisplay_idstr

Returns

dict
func_broadcast_live_server_settings(display_id) -> None

Re-announce server settings after the given display changed its live encoder.

The handshake payload holds boot config only, so every connected client — shared viewers included — must re-key its wire-format demux or it drops the new mode's chunks forever. Routed like broadcast_stream_resolution: each display's own socket gets its own encoder and every remaining socket gets the primary's, since shared viewers render the primary stream and one display's encoder applied on another page keys that page to a format its own stream never sends.

Source Code
async def _broadcast_live_server_settings(self, display_id: str) -> None:
    """Re-announce server settings after the given display changed its live encoder.

    The handshake payload holds boot config only, so every connected client —
    shared viewers included — must re-key its wire-format demux or it drops
    the new mode's chunks forever. Routed like broadcast_stream_resolution:
    each display's own socket gets its own encoder and every remaining socket
    gets the primary's, since shared viewers render the primary stream and one
    display's encoder applied on another page keys that page to a format its
    own stream never sends.
    """
    try:
        messages = {}

        def message_for(did):
            if did not in messages:
                messages[did] = json.dumps({
                    "type": "server_settings",
                    "displayId": did,
                    "settings": self._settings_payload_for_display(did),
                })
            return messages[did]

        per_socket = {}
        for did, client in self.display_clients.items():
            ws = client.get('ws')
            if ws is not None:
                per_socket[ws] = message_for(did)
        primary_message = message_for('primary')
    except Exception as e:
        data_logger.warning(f"Could not build live server settings broadcast: {e}")
        return
    groups = {}
    for ws in self.clients:
        groups.setdefault(per_socket.get(ws) or primary_message, set()).add(ws)
    data_logger.debug(
        f"Re-announcing live server settings after the '{display_id}' capture restart "
        f"to {len(self.clients)} client(s)."
    )
    for message_str, sockets in groups.items():
        # Bounded: runs under _reconfigure_lock; a frozen client is dropped, not waited on.
        dropped = await _broadcast_to_clients(sockets, message_str, watched=True)
        # The fan-out ran over a computed set; mirror the drop into the registry.
        for ws in dropped:
            self.clients.discard(ws)
paramdisplay_idstr

Returns

None
func_set_backpressure_enabled(display_id, display_state, enabled, resync=False) -> None

Update the backpressure flag, requesting an IDR when it lifts.

While backpressure was active, delta frames were dropped, so on the False->True (LIFTED) transition the client needs a keyframe to resync; otherwise it decodes deltas against a reference it never received. A client whose acks caught up (resync) on a stream naming each frame's reference resumes instead on the frame predicting past the ones dropped (_VideoRelay.ungate); a re-probed one still gets the keyframe. The deltas encoded before that keyframe still reach the client's relay first and are dropped there, and a request of the relay's own landing after the encoder took this one would cost a second keyframe, so the relay is told one is on its way (_VideoRelay.hold_sync).

Source Code
def _set_backpressure_enabled(self, display_id: str, display_state: dict, enabled: bool,
                              resync: bool = False) -> None:
    """Update the backpressure flag, requesting an IDR when it lifts.

    While backpressure was active, delta frames were dropped, so on the
    False->True (LIFTED) transition the client needs a keyframe to resync;
    otherwise it decodes deltas against a reference it never received. A
    client whose acks caught up (`resync`) on a stream naming each frame's
    reference resumes instead on the frame predicting past the ones dropped
    (`_VideoRelay.ungate`); a re-probed one still gets the keyframe. The
    deltas encoded before that keyframe still reach the client's relay
    first and are dropped there, and a request of the relay's own landing
    after the encoder took this one would cost a second keyframe, so the
    relay is told one is on its way (`_VideoRelay.hold_sync`).
    """
    prev_enabled = display_state.get('backpressure_enabled', True)
    display_state['backpressure_enabled'] = enabled
    if enabled != prev_enabled:
        display_state['gate_moved_at'] = time.monotonic()
    if enabled and not prev_enabled:
        relay = self.video_relay_groups.get(display_id, {}).get(display_state.get('ws'))
        if relay is not None and relay.ungate(resync):
            return
        self._schedule_idr_for_display(display_id)
        _expect_key_frame(display_state)
        if relay is not None:
            relay.hold_sync()
paramdisplay_idstr
paramdisplay_statedict
paramenabledbool
paramresyncbool
= False

Returns

None
func_run_frame_backpressure_logic(display_id) -> None

The core backpressure and latency calculation loop for a single display.

Every BACKPRESSURE_CHECK_INTERVAL_S it counts the frames sent after the one the client last acked, sized by the client's measured consumption rate, and flips the display's backpressure flag when more than BACKPRESSURE_ALLOWED_DESYNC_MS of them stand past the path's own round trip, its floor (_note_round_trip): a stalled or lagging client stops receiving delta frames, and the lift requests an IDR resync. The frames in flight over the floor are forgiven, the queue standing behind them is not: a queue the gate lets grow is latency the viewer sees, however long the path. Where congestion control steers the display (_steer_bitrate_to_link, which backs the rate off on the first window standing past the floor), the queue has to stand past the allowance at two checks in a row before the gate shuts: a path that holds the stream a moment (a lost segment's retransmission, a Wi-Fi hop's jitter) releases what it held within one check, and a gate shut on that moment would freeze the stream and resume it on a key frame, while a queue is still there at the next. Where nothing else bounds the queue on the path, the first check shuts it while the client's acks move on (the path delivering, behind a queue) and leaves it to the next when they stood still for BACKPRESSURE_ACK_HOLD_S (the path holding the stream). A hold longer than a check (no ack moving for a whole check) is waited for until the queue has stood over the allowance for PATH_HOLD_MAX_S where the path holds the stream (a ping written behind the frames when the queue went over still unanswered: a long path's retransmission, a radio's pause) or the page does (it has sent nothing at all for a check: its thread stalled): what it held then arrives, where the gate would drop those frames and have the encoder predict past them from whatever it still holds, at a low frame rate an anchor seconds old. Behind a queue the acks keep moving, and a client that stopped acking what it was handed (a decoder waiting for a key frame) answers the ping and keeps its heartbeat, so both are judged as before. A stream resuming after a still screen (a capture that produced nothing for STILL_SCREEN_GAP_SECONDS) is left unjudged for STILL_RESUME_GRACE_SECONDS: every frame it sends counts against the client until the client's first ack of them comes back, which after an idle spell can take a quarter of a second, and the gate would answer that with a freeze and a key frame on every resume. A queue a slow path builds under motion that continues has no such pause and is judged throughout; the gate's own pauses stop the sends, not the capture, so they grant no such grace. Also feeds the Prometheus fps/latency gauges for the primary display.

What a lift does grant is the time its key frame takes to cross. The client can ack nothing after that key frame until the whole of it has arrived, and on a slow path a large one outlasts the allowance, so the frames sent behind it would read as a lagging client, close the gate again, and cost another key frame at the next lift, over and over. After a lift, a new page, or a reset (_expect_key_frame) the desync branch therefore waits for that key frame to cross and for the queue it put on the path to drain, for as long as that queue took to build, twice over (_key_frame_pending). A stream the path cannot carry deepens the queue past that instead and is judged at once.

A stall is a frame that has gone unanswered by any ack for STALLED_CLIENT_TIMEOUT_SECONDS, timed from the first send after the newest ack (unacked_since, stamped by the relay and cleared by every ack). It is not measured from the last ack: a damage-gated capture sends nothing while the screen is still, and silence with nothing outstanding is an idle client, not a dead one. The client repeats an unchanged id as a heartbeat, so a client that is alive but behind is the desync branch's case rather than this one. A stalled gate is sent nothing, so it cannot be lifted by the ack it waits for; after STALLED_CLIENT_REPROBE_SECONDS it reopens on an IDR (the lift's resync) and the stall timer restarts from that send, which a client that is still gone trips again and a returned one answers.

A desync gate can hold the same way. Its client's acks keep coming but stop short of what it was sent (a presenter that stalled, a video decoder waiting for a key frame), and a gated client is sent nothing newer to ack, so the count that closed the gate never falls while the screen keeps changing. So a desync gate reopens on an IDR as well once the client's acks have not moved for STALLED_CLIENT_REPROBE_SECONDS after everything sent before the gate closed reached it, with those frames forgiven: the count restarts from that send, which a client still stuck trips again, for a key frame per re-probe rather than a stream, and a returned one answers. Arrival is read end to end, from the pong to a ping written behind the last frame (socket_gauge), so a key frame still crossing a slow path, where the acks stand still too, is waited for rather than answered with another; a path that answers no ping is taken as delivered after SEND_STALL_SECONDS. Only a client whose acks resumed is probed this way; one that went silent is the stall branch's.

Source Code
async def _run_frame_backpressure_logic(self, display_id: str) -> None:
    """The core backpressure and latency calculation loop for a single display.

    Every BACKPRESSURE_CHECK_INTERVAL_S it counts the frames sent after
    the one the client last acked, sized by the client's measured
    consumption rate, and flips the display's backpressure flag when more
    than BACKPRESSURE_ALLOWED_DESYNC_MS of them stand past the path's own
    round trip, its floor (`_note_round_trip`): a stalled or lagging
    client stops receiving delta frames, and the lift requests an IDR
    resync. The frames in flight over the floor are forgiven, the queue
    standing behind them is not: a queue the gate lets grow is latency the
    viewer sees, however long the path. Where congestion control steers
    the display (`_steer_bitrate_to_link`, which backs the rate off on the
    first window standing past the floor), the queue has to stand past the
    allowance at two checks in a row before the gate shuts: a path that
    holds the stream a moment (a lost segment's retransmission, a Wi-Fi
    hop's jitter) releases what it held within one check, and a gate shut
    on that moment would freeze the stream and resume it on a key frame,
    while a queue is still there at the next. Where nothing else bounds
    the queue on the path, the first check shuts it while the client's
    acks move on (the path delivering, behind a queue) and leaves it to
    the next when they stood still for BACKPRESSURE_ACK_HOLD_S (the path
    holding the stream). A hold longer than a check (no ack moving for a
    whole check) is waited for until the queue has stood over the
    allowance for PATH_HOLD_MAX_S where the path holds the stream (a ping
    written behind the frames when the queue went over still unanswered:
    a long path's retransmission, a radio's pause) or the page does (it
    has sent nothing at all for a check: its thread stalled): what it
    held then arrives, where the gate would drop those frames and have the
    encoder predict past them from whatever it still holds, at a low frame
    rate an anchor seconds old. Behind a queue the acks keep moving, and a
    client that stopped acking what it was handed (a decoder waiting for a
    key frame) answers the ping and keeps its heartbeat, so both are
    judged as before. A stream resuming after a still screen (a
    capture that produced nothing for STILL_SCREEN_GAP_SECONDS) is left
    unjudged for STILL_RESUME_GRACE_SECONDS: every frame it sends
    counts against the client until the client's first ack of them comes
    back, which after an idle spell can take a quarter of a second, and
    the gate would answer that with a freeze and a key frame on every
    resume. A queue a slow path builds under motion that continues has no
    such pause and is judged throughout; the gate's own pauses stop the
    sends, not the capture, so they grant no such grace. Also feeds the
    Prometheus fps/latency gauges for the primary display.

    What a lift does grant is the time its key frame takes to cross. The
    client can ack nothing after that key frame until the whole of it has
    arrived, and on a slow path a large one outlasts the allowance, so the
    frames sent behind it would read as a lagging client, close the gate
    again, and cost another key frame at the next lift, over and over.
    After a lift, a new page, or a reset (`_expect_key_frame`) the desync
    branch therefore waits for that key frame to cross and for the queue
    it put on the path to drain, for as long as that queue took to build,
    twice over (`_key_frame_pending`). A stream the path cannot carry
    deepens the queue past that instead and is judged at once.

    A stall is a frame that has gone unanswered by any ack for
    STALLED_CLIENT_TIMEOUT_SECONDS, timed from the first send after the
    newest ack (`unacked_since`, stamped by the relay and cleared by every
    ack). It is not measured from the last ack: a damage-gated capture
    sends nothing while the screen is still, and silence with nothing
    outstanding is an idle client, not a dead one. The client repeats an
    unchanged id as a heartbeat, so a client that is alive but behind is
    the desync branch's case rather than this one. A stalled gate is sent
    nothing, so it cannot be lifted by the ack it waits for; after
    STALLED_CLIENT_REPROBE_SECONDS it reopens on an IDR (the lift's
    resync) and the stall timer restarts from that send, which a client
    that is still gone trips again and a returned one answers.

    A desync gate can hold the same way. Its client's acks keep coming but
    stop short of what it was sent (a presenter that stalled, a video
    decoder waiting for a key frame), and a gated client is sent nothing
    newer to ack, so the count that closed the gate never falls while the
    screen keeps changing. So a desync gate reopens on an IDR as well once
    the client's acks have not moved for STALLED_CLIENT_REPROBE_SECONDS
    after everything sent before the gate closed reached it, with those
    frames forgiven: the count restarts from that send, which a client
    still stuck trips again, for a key frame per re-probe rather than a
    stream, and a returned one answers. Arrival is read end to end, from
    the pong to a ping written behind the last frame (`socket_gauge`), so a
    key frame still crossing a slow path, where the acks stand still too,
    is waited for rather than answered with another; a path that answers
    no ping is taken as delivered after SEND_STALL_SECONDS. Only a client
    whose acks resumed is probed this way; one that went silent is the
    stall branch's.
    """
    data_logger.debug(f"Frame-based backpressure logic task started for display '{display_id}'.")
    display_state = None
    try:
        if self.client_settings_received:
            await self.client_settings_received.wait()
        data_logger.debug(f"Client settings received, proceeding with backpressure loop for '{display_id}'.")
        started = self.display_clients.get(display_id)
        if started is not None:
            _start_link_window(started, time.monotonic())

        while True:
            slept_at = time.monotonic()
            await asyncio.sleep(self.backpressure_check_interval_s)
            # How late the server's own event loop woke: delay it adds to every round trip it times.
            late_ms = max((time.monotonic() - slept_at - self.backpressure_check_interval_s) * 1000.0, 0.0)

            display_state = self.display_clients.get(display_id)
            if not display_state:
                data_logger.warning(f"Backpressure task for '{display_id}' exiting: display no longer exists.")
                break
            display_state['loop_late_ms'] = late_ms

            if display_id not in self.capture_instances:
                if not display_state.get('backpressure_enabled', True):
                    data_logger.debug(f"Backpressure LIFTED for '{display_id}' (video pipeline is not active).")
                self._set_backpressure_enabled(display_id, display_state, True)
                continue

            current_server_frame_id = display_state.get('last_sent_frame_id', 0)
            last_client_acked_frame_id = display_state.get('acknowledged_frame_id', -1)

            if last_client_acked_frame_id == -1:
                if not display_state.get('backpressure_enabled', True):
                     data_logger.debug(f"Backpressure LIFTED for '{display_id}' (client ACK is -1).")
                self._set_backpressure_enabled(display_id, display_state, True)
                display_state['unacked_since'] = None
                display_state['stall_gated_at'] = None
                _start_link_window(display_state, time.monotonic())
                continue

            configured_fps = self._capture_fps(display_state)
            if configured_fps <= 0:
                configured_fps = 60
            client_fps = self._estimate_client_fps(
                display_state, last_client_acked_frame_id, configured_fps, time.monotonic()
            )
            if display_id == 'primary' and getattr(self, 'metrics', None) is not None:
                self.metrics.set_fps(client_fps)
                self.metrics.set_latency(display_state.get('smoothed_rtt', 0.0))

            server_id, client_id = current_server_frame_id, last_client_acked_frame_id

            # Circular distance, so the suspicious-gap test is not tripped at the uint16 wrap.
            wrapped = (server_id - client_id) % (MAX_UINT16_FRAME_ID + 1)

            if wrapped > FRAME_ID_SUSPICIOUS_GAP_THRESHOLD:
                self._set_backpressure_enabled(display_id, display_state, True)
                display_state['unacked_since'] = None
                display_state['stall_gated_at'] = None
                continue

            # Distinguish 'no frame sent yet' from the counter legitimately wrapping to 0.
            if not display_state.get('has_sent_any_frame', False):
                continue

            # Ids run at the capture cadence and a still screen sends none
            # of them, so the client is behind by the frames sent after the
            # one it acked, not by the id distance.
            acked_sent_at = display_state.get('acked_sent_at')
            sent_ts = display_state.get('sent_timestamps') or {}
            frame_desync = (wrapped if acked_sent_at is None
                            else sum(1 for t, _ in sent_ts.values() if t > acked_sent_at))
            allowed_desync_frames = (self.allowed_desync_ms / 1000.0) * client_fps
            # The path's own round trip is forgiven, never the queue this
            # loop bounds: a round trip measured through that queue would
            # loosen its own trigger as the queue grew.
            floor_ms = display_state.get('rtt_floor_ms') or 0.0
            effective_desync_frames = frame_desync - (floor_ms / 1000.0) * client_fps

            now = time.monotonic()
            unacked_since = display_state.get('unacked_since')
            unanswered_for = (now - unacked_since) if unacked_since is not None else 0.0
            steered = (self.cli_args.congestion_control[0] and display_state.get(
                'rate_control_mode', self.rc_mode.value) == RateControlMode.CBR.value)
            over = (not _key_frame_pending(display_state, now)
                    and effective_desync_frames > allowed_desync_frames
                    and now - display_state.get('resumed_at', 0.0) >= STILL_RESUME_GRACE_SECONDS)
            over_at = display_state.get('queue_over_at')
            display_state['queue_over_at'] = now if over else None
            over_since = (display_state.get('queue_over_since') or now) if over_at is not None else now
            display_state['queue_over_since'] = over_since if over else None
            acked_at = display_state.get('acked_at', 0.0)
            delivering = now - acked_at <= BACKPRESSURE_ACK_HOLD_S
            # A path holding the stream holds a ping written behind it too, and a page whose
            # thread stalls sends nothing at all, where a client that stopped acking what it was
            # handed (a decoder waiting for a key frame) answers the ping and keeps its heartbeat.
            ws = display_state.get('ws')
            if over and over_at is None and ws is not None:
                display_state['hold_ping'] = _uplink_session_state(ws)['next_ping']
                _spawn_background_task(ping_behind(ws))
            hold_ping = display_state.get('hold_ping')
            uplink = _uplink_session_state(ws) if ws is not None else None
            ping_out = (uplink is not None and hold_ping is not None
                        and (uplink['next_ping'] <= hold_ping
                             or hold_ping.to_bytes(8, 'big') in uplink['pending']))
            heard_at = getattr(self, '_heard_at', {}).get(ws, now)
            page_silent = now - heard_at >= self.backpressure_check_interval_s
            holding = (now - acked_at >= self.backpressure_check_interval_s and (ping_out or page_silent)
                       and now - over_since < PATH_HOLD_MAX_S)
            standing = over and (not display_state.get('backpressure_enabled', True)
                                 or (not holding
                                     and ((not steered and delivering)
                                          or (over_at is not None
                                              and now - over_at <= 1.5 * self.backpressure_check_interval_s))))

            if unanswered_for > STALLED_CLIENT_TIMEOUT_SECONDS:
                display_state['desync_gated'] = None
                gated_at = display_state.get('stall_gated_at')
                if display_state.get('backpressure_enabled', True) or gated_at is None:
                    if display_state.get('backpressure_enabled', True):
                        data_logger.warning(f"Client stall for '{display_id}': no ACK in {unanswered_for:.1f}s since the last frame sent. Forcing backpressure.")
                    display_state['stall_gated_at'] = now
                    self._set_backpressure_enabled(display_id, display_state, False)
                elif now - gated_at >= STALLED_CLIENT_REPROBE_SECONDS:
                    data_logger.info(f"Re-probing stalled client for '{display_id}': reopening on an IDR.")
                    display_state['stall_gated_at'] = None
                    display_state['unacked_since'] = None
                    self._set_backpressure_enabled(display_id, display_state, True)
            elif standing:
                display_state['stall_gated_at'] = None
                gate = display_state.get('desync_gated')
                if display_state.get('backpressure_enabled', True) or gate is None:
                    if display_state.get('backpressure_enabled', True):
                        data_logger.warning(
                            f"Backpressure TRIGGERED for '{display_id}'. S:{server_id}, C:{client_id} "
                            f"(EffDesync:{effective_desync_frames:.1f}f > Allowed:{allowed_desync_frames:.1f}f; "
                            f"path {'holding' if ping_out else 'delivered'}, page heard {now - heard_at:.1f} s ago).")
                    # The pong to a ping written behind the last frame says it all arrived.
                    gate = {'acked': acked_sent_at, 'since': now, 'pinged': now, 'delivered': None}
                    display_state['desync_gated'] = gate
                    ws = display_state.get('ws')
                    if ws is not None:
                        _spawn_background_task(socket_gauge(ws).sample())
                elif gate['acked'] != acked_sent_at:
                    gate['acked'], gate['since'] = acked_sent_at, now
                if gate['delivered'] is None and (
                        now - gate['pinged'] >= SEND_STALL_SECONDS
                        or _uplink_session_state(display_state.get('ws')).get('answered', 0.0) >= gate['pinged']):
                    gate['delivered'] = now
                if (unacked_since is None and gate['delivered'] is not None
                        and now - max(gate['since'], gate['delivered']) >= STALLED_CLIENT_REPROBE_SECONDS):
                    data_logger.info(f"Re-probing desynced client for '{display_id}': no ack past {client_id} in {now - gate['since']:.1f}s; reopening on an IDR.")
                    display_state['desync_gated'] = None
                    sent_ts.clear()
                    display_state['acked_sent_at'] = now
                    self._set_backpressure_enabled(display_id, display_state, True)
                else:
                    self._set_backpressure_enabled(display_id, display_state, False)
            else:
                display_state['stall_gated_at'] = None
                display_state['desync_gated'] = None
                if not display_state.get('backpressure_enabled', True):
                    data_logger.info(f"Backpressure LIFTED for '{display_id}'. S:{server_id}, C:{client_id} (EffDesync:{effective_desync_frames:.1f}f <= Allowed:{allowed_desync_frames:.1f}f).")
                self._set_backpressure_enabled(display_id, display_state, True, resync=True)
            if steered:
                self._steer_bitrate_to_link(display_id, display_state, now)

    except asyncio.CancelledError:
        data_logger.debug(f"Backpressure logic task for '{display_id}' canceled.")
    finally:
        if display_state:
            display_state['backpressure_enabled'] = True
        data_logger.debug(f"Backpressure logic task for '{display_id}' finished.")
paramdisplay_idstr

Returns

None
func_cbr_target_kbps(display_id) -> int

The rate a display's running capture encodes at, as last applied to it, or 0 for a capture that holds a quality rather than a rate.

Source Code
def _cbr_target_kbps(self, display_id: str) -> int:
    """The rate a display's running capture encodes at, as last applied to it,
    or 0 for a capture that holds a quality rather than a rate."""
    inst = self.capture_instances.get(display_id)
    cs = inst.get('settings') if inst else None
    if cs is None or not getattr(cs, 'video_cbr_mode', False):
        return 0
    return int(getattr(cs, 'video_bitrate_kbps', 0) or 0)
paramdisplay_idstr

Returns

int
func_video_bitrate_kbps(display_state) -> float

The CBR rate a display's encoder runs at: its target, held down to what its path carries while congestion control steers it.

Source Code
def _video_bitrate_kbps(self, display_state: dict) -> float:
    """The CBR rate a display's encoder runs at: its target, held down to
    what its path carries while congestion control steers it."""
    target = float(display_state.get('video_bitrate', self._initial_video_bitrate) or 0)
    link = display_state.get('link_kbps')
    return min(target, link) if link else target
paramdisplay_statedict

Returns

float
func_steer_bitrate_to_link(display_id, display_state, now) -> None

Hold a CBR display to the rate its path carries (congestion_control over WebSockets, where no receiver estimate exists), once per backpressure check.

The frames the client acked since the last check are the window, each round trip less the time its own bytes took to cross the path (_queued_round_trips). A queue on the path shows as the least round trip among them standing LINK_QUEUE_MS past the floor, the least round trip of the last ten minutes (_note_round_trip), so a queue that stands a while is not taken for the path itself, unless the rate cuts it answers leave it standing: delay that holds through windows sent well under what the path delivered is a longer path's, or other traffic's, and becomes the floor (_settle_path_floor). The least rather than the mean: a key frame's burst delays the frames behind it for a moment on any link, while a queue the rate has outgrown delays every one of them. A queue still building shows sooner, as the last LINK_RISE_ACKS round trips each longer than the one before and past LINK_QUEUE_MS; the frames behind a key frame's burst arrive ever sooner, so it never reads that way, and one closing the row ends none (LINK_RISE_LONE): the acks before it must rise themselves. A path that jitters asks for more: a Wi-Fi hop, or a lossy one whose retransmissions hold a stream back, spreads round trips over tens of milliseconds with no queue at all, which puts four acks in a rising row once in 24 windows and now and then lifts even the least of a window's ten. Its jitter is the mean change between successive round trips less the change they share, which a queue building or draining adds to every one (_round_trip_jitter), taken from the first acks and then averaged over the windows that read no queue. Both verdicts then stand half that jitter higher, and a building queue rises through one more ack per LINK_RISE_JITTER_MS of it: four jittered acks rise in a row once in 24 windows and ten once in 3.6 million, while a path that does not jitter keeps the four and reads a queue as soon as it can. Before a session has that many acks, the row it has counts; the late round trips a lossy path's stalls leave count toward its jitter, so they lengthen the row rather than end one. A window of fewer than eight acks, a caret blinking on a still screen, is judged with the acks before it, since the least of two round trips says little. Nor is a window whose round trips fell while it delivered more than the rate in force: its frames were held back a moment (a lost segment's retransmission, the gate's pause) and are arriving together, which a queue the rate outgrew never does; an encoder running over its target keeps its round trips up.

The queue's depth is read from the newest round trip, which a growing queue has grown into. The window's delivery rate, the bytes of the frames it acked over the time they took to be acked, is the path's capacity while that queue stands, or the rate the window before it delivered where that is higher: a path that stalls for a moment acks a window's frames late and together, which reads as a queue over a slow path, and a path carries at least what it just delivered unless it is losing capacity, which the next window then shows. Both go to the transports' shared CongestionSteer, which backs off on the first such window, with what the display sent over the tick, so a still screen's trickle is neither taken for what the path carries nor raises the rate past it; a tick the gate held any of goes without, since the path, not the stream, set what it sent, and raises the rate no further either. A display the backpressure gate holds is judged by the frames still acked from before the gate shut, like any window, since a moment's delay trips the gate without a queue behind it; over a path slower than the rate they keep arriving as its queue drains. A window with nothing acked moves nothing: a still screen sends no frames, a verdict from a round trip measured before it would steer an idle stream on stale evidence, and a gate shut on a path that holds the whole stream, or a page that holds its acks, has no queue behind it.

Every display behind one bottleneck sees the same queue and settles on a share of it, where the backpressure gate alone pauses whichever falls behind first while the other keeps its whole rate, and the paused one resumes on a key frame its share cannot carry.

Source Code
def _steer_bitrate_to_link(self, display_id: str, display_state: dict, now: float) -> None:
    """Hold a CBR display to the rate its path carries (`congestion_control`
    over WebSockets, where no receiver estimate exists), once per
    backpressure check.

    The frames the client acked since the last check are the window, each
    round trip less the time its own bytes took to cross the path
    (`_queued_round_trips`). A queue on the path shows as the least round
    trip among them standing `LINK_QUEUE_MS` past the floor, the least round trip of the last ten
    minutes (`_note_round_trip`), so a queue that stands a while is not
    taken for the path itself, unless the rate cuts it answers leave it
    standing: delay that holds through windows sent well under what the
    path delivered is a longer path's, or other traffic's, and becomes the
    floor (`_settle_path_floor`). The least rather than the mean: a key
    frame's burst delays the frames behind it for a moment on any link,
    while a queue the rate has outgrown delays every one of them. A queue
    still building shows sooner, as the last `LINK_RISE_ACKS` round trips
    each longer than the one before and past `LINK_QUEUE_MS`; the frames
    behind a key frame's burst arrive ever sooner, so it never reads that
    way, and one closing the row ends none (`LINK_RISE_LONE`): the acks
    before it must rise themselves. A path that jitters asks for more: a
    Wi-Fi hop, or a lossy one whose retransmissions hold a stream back,
    spreads round trips over tens of milliseconds with no queue at all,
    which puts four acks in a rising row once in 24 windows and now and
    then lifts even the least of a window's ten. Its jitter is the mean
    change between successive round trips less the change they share,
    which a queue building or draining adds to every one
    (`_round_trip_jitter`), taken from the first acks and then averaged
    over the windows that read no queue. Both verdicts then stand half
    that jitter higher, and a building queue rises through one more ack
    per `LINK_RISE_JITTER_MS` of it: four jittered acks rise in a row once
    in 24 windows and ten once in 3.6 million, while a path that does not
    jitter keeps the four and reads a queue as soon as it can. Before a
    session has that many acks, the row it has counts; the late round
    trips a lossy path's stalls leave count toward its jitter, so they
    lengthen the row rather than end one. A window of fewer than eight
    acks, a caret blinking on a still screen, is judged with the acks
    before it, since the least of two round trips says little. Nor is a
    window whose round trips fell while it delivered more than the rate in
    force: its frames were held back a moment (a lost segment's
    retransmission, the gate's pause) and are arriving together, which a
    queue the rate outgrew never does; an encoder running over its target
    keeps its round trips up.

    The queue's depth is read from the newest round trip, which a growing
    queue has grown into. The window's delivery rate, the bytes of the
    frames it acked over the time they took to be acked, is the path's
    capacity while that queue stands, or the rate the window before it
    delivered where that is higher: a path that stalls for a moment acks a
    window's frames late and together, which reads as a queue over a slow
    path, and a path carries at least what it just delivered unless it is
    losing capacity, which the next window then shows. Both go to the
    transports' shared `CongestionSteer`, which backs off on the first such
    window, with what the display sent over the tick, so a still screen's
    trickle is neither taken for what the path carries nor raises the rate
    past it; a tick the gate held any of goes without, since the path, not
    the stream, set what it sent, and raises the rate no further either.
    A display the backpressure gate holds is judged by the frames
    still acked from before the gate shut, like any window, since a
    moment's delay trips the gate without a queue behind it; over a path
    slower than the rate they keep arriving as its queue drains. A window
    with nothing acked moves nothing: a still screen sends no frames, a
    verdict from a round trip measured before it would steer an idle stream
    on stale evidence, and a gate shut on a path that holds the whole
    stream, or a page that holds its acks, has no queue behind it.

    Every display behind one bottleneck sees the same queue and settles on a
    share of it, where the backpressure gate alone pauses whichever falls
    behind first while the other keeps its whole rate, and the paused one
    resumes on a key frame its share cannot carry.
    """
    last_tick = display_state.get('link_tick_at', 0.0)
    display_state['link_tick_at'] = now
    sent = display_state.get('sent_bytes', 0)
    sent_then = display_state.get('link_tick_sent', sent)
    display_state['link_tick_sent'] = sent
    window = [a for a in display_state.get('link_acks', ()) if a[0] > last_tick]
    gated = not display_state.get('backpressure_enabled', True)
    if not window and (not gated or display_state.get('link_carried', True)):
        # A screen that sends nothing acks nothing; with nothing in flight its path is
        # idle, which a cut target may pad to test (`_probe_path`).
        steer = display_state.get('link_steer')
        if steer is not None and not gated and display_state.get('unacked_since') is None:
            self._probe_path(display_id, display_state, now, last_tick, steer,
                             float(display_state.get('video_bitrate') or 0),
                             self._video_bitrate_kbps(display_state), 0.0,
                             (sent - sent_then) * 8 / (now - last_tick) if last_tick else None)
        return
    target = float(display_state.get('video_bitrate') or 0)
    module = self.capture_instances.get(display_id, {}).get('module')
    if target <= 0 or module is None:
        return
    floor_ms = display_state.get('rtt_floor_ms') or 0.0
    path_now = _path_rate(display_state.get('link_acks', ()), floor_ms)
    told = display_state.setdefault('link_allowance', LinkAllowance()).note(
        path_now if window else None, app_settings.video_bitrate[1])
    if told is not None and hasattr(module, 'update_link_rate'):
        module.update_link_rate(told)
    queued_ms = _queued_round_trips(display_state.get('link_acks', ()), path_now)
    stand = queued_ms[-max(len(window), 2 * LINK_RISE_ACKS):]
    least_ms = min(stand, default=0.0) if window else 0.0
    held = gated or display_state.get('gate_moved_at', 0.0) > last_tick
    offered_bps = (sent - sent_then) * 8 / (now - last_tick) if last_tick and not held else None
    acked_offered_bps = None
    capacity_bps = None
    if not window:
        delivered_bps, queue_s = 0.0, LINK_QUEUE_MS / 1000.0
    else:
        span = window[-1][0] - window[0][0]
        delivered_bps = (window[-1][2] - window[0][2]) * 8 / span if span > 0 else 0.0
        measured_bps = delivered_bps if span > 0 else None
        # The same frames' send span: each acked at its send plus its round trip.
        sent_span = span - (window[-1][1] - window[0][1]) / 1000.0
        if sent_span > 0 and span > 0:
            acked_offered_bps = (window[-1][2] - window[0][2]) * 8 / sent_span
        jitter_ms = display_state.get('link_jitter_ms')
        if jitter_ms is None and len(stand) >= LINK_RISE_ACKS:
            jitter_ms = display_state['link_jitter_ms'] = _round_trip_jitter(stand)
        allowed_ms = LINK_QUEUE_MS + (jitter_ms or 0.0) / 2
        catching_up = (delivered_bps > self._video_bitrate_kbps(display_state) * 1000
                       and window[-1][1] < window[0][1])
        raw_least_ms = min(a[1] for a in list(display_state['link_acks'])[-len(stand):])
        settled_ms = _settle_path_floor(display_state, least_ms, raw_least_ms, allowed_ms, delivered_bps,
                                        offered_bps, len(window) >= 2 * LINK_RISE_ACKS and not catching_up,
                                        now)
        if settled_ms != floor_ms:
            data_logger.info(
                f"Congestion control[{display_id}]: round trip floor {floor_ms:.0f} -> {settled_ms:.0f} ms "
                f"(the rate cuts left it standing)")
            floor_ms = settled_ms
            path_now = _path_rate(display_state['link_acks'], floor_ms)
            queued_ms = _queued_round_trips(display_state['link_acks'], path_now)
            stand = queued_ms[-max(len(window), 2 * LINK_RISE_ACKS):]
            least_ms = min(stand)
        newest_ms = queued_ms[-1] - floor_ms
        run = LINK_RISE_ACKS + round((jitter_ms or 0.0) / LINK_RISE_JITTER_MS)
        tail = list(display_state['link_acks'])[-run - 1:]
        sizes = [max(a[2] - b[2], 0) for b, a in zip(tail, tail[1:])]
        lone = (len(sizes) >= 2 and sizes[-1] >= LINK_MEASURE_BYTES
                and sizes[-1] >= LINK_RISE_LONE * max(sizes[:-1]))
        row = queued_ms[-run - 1:-1] if lone else queued_ms[-run:]
        rising = (len(row) >= LINK_RISE_ACKS and all(b > a for a, b in zip(row, row[1:]))
                  and row[-1] - floor_ms > allowed_ms)
        standing = least_ms - floor_ms > allowed_ms
        queued = (standing or rising) and not catching_up
        if rising and not standing:
            # A queue that only builds stood over the row's acks, not the window's: what the
            # path delivered over them is its capacity, where the window's rate is mostly the
            # trickle before the burst that built it.
            acks = list(display_state['link_acks'])
            burst = acks[-run - 2:-1] if lone else acks[-run - 1:]
            burst_span = burst[-1][0] - burst[0][0]
            if burst_span > 0:
                capacity_bps = (burst[-1][2] - burst[0][2]) * 8 / burst_span
        if not queued and not catching_up and jitter_ms is not None:
            display_state['link_jitter_ms'] = jitter_ms + LINK_JITTER_GAIN * (
                _round_trip_jitter(stand) - jitter_ms)
        queue_s = max(newest_ms, LINK_QUEUE_MS) / 1000.0 if queued else 0.0
        previous_bps = display_state.get('link_delivered_bps', 0.0)
        display_state['link_delivered_bps'] = delivered_bps
        if queued:
            delivered_bps = max(delivered_bps, previous_bps)
    lo_kbps, _ = app_settings.video_bitrate
    current = self._video_bitrate_kbps(display_state)
    if offered_bps is not None and window and measured_bps is not None:
        display_state['link_carried'] = measured_bps >= LINK_CARRIED_SHARE * offered_bps
    steer = display_state.setdefault('link_steer', CongestionSteer())
    probe = display_state.get('link_probe')
    rate = round(steer.target(current, target, float(lo_kbps), delivered_bps, 0.0, now, queue_s,
                              offered_bps, acked_offered_bps, capacity_bps,
                              probed=probe is not None and probe.padding))
    display_state['link_kbps'] = rate
    self._probe_path(display_id, display_state, now, last_tick, steer, target, rate, queue_s, offered_bps)
    held_kbps = display_state.setdefault('link_hold', RateHold()).note(rate, now)
    ws = display_state.get('ws')
    if held_kbps is not None and ws is not None:
        _spawn_background_task(_broadcast_to_clients(
            self.clients, f"CC_RATE {held_kbps}", watched=True, only=id(ws)))
    if rate != round(current):
        (data_logger.info if rate < current or steer.restored else data_logger.debug)(
            f"Congestion control[{display_id}]: video bitrate {current:.0f} -> {rate} kbps "
            + ("(round trips back at the floor after a stall: the rate before it)" if steer.restored else
               f"(round trip {least_ms:.0f} ms over a {floor_ms:.0f} ms floor, "
               f"{delivered_bps / 1000:.0f} kbps delivered, the server's loop "
               f"{display_state.get('loop_late_ms', 0.0):.0f} ms late)"))
        try:
            module.update_video_bitrate(rate)
            self._track_capture_settings(display_id, video_bitrate_kbps=rate)
        except Exception as e:
            data_logger.warning(f"Congestion control could not retarget '{display_id}' ({e}).")
paramdisplay_idstr
paramdisplay_statedict
paramnowfloat

Returns

None
func_probe_path(display_id, display_state, now, last_tick, steer, ceiling, rate, queue_s, offered_bps) -> None

Pad a display's stream toward its owner through the next tick where its PathProbe asks it to, a page that announced _pad,1 (WS_OPCODE_PADDING).

What the display sent over the tick, offered_bps (None where the gate held any of it), is taken without the padding the relay wrote through it, so the probe weighs the stream's own.

Source Code
def _probe_path(self, display_id: str, display_state: dict, now: float, last_tick: float,
                steer: CongestionSteer, ceiling: float, rate: float, queue_s: Optional[float],
                offered_bps: Optional[float]) -> None:
    """Pad a display's stream toward its owner through the next tick where its
    `PathProbe` asks it to, a page that announced `_pad,1` (`WS_OPCODE_PADDING`).

    What the display sent over the tick, `offered_bps` (None where the gate held
    any of it), is taken without the padding the relay wrote through it, so the
    probe weighs the stream's own.
    """
    pad_sent = display_state.get('pad_bytes', 0)
    pad_then = display_state.get('link_tick_pad', pad_sent)
    display_state['link_tick_pad'] = pad_sent
    span = now - last_tick if last_tick else 0.0
    content_bps = None
    if offered_bps is not None and span > 0:
        content_bps = max(0.0, offered_bps - (pad_sent - pad_then) * 8 / span)
    ws = display_state.get('ws')
    if ws is None or not getattr(ws, '_ws_pad', False):
        return
    pad = display_state.setdefault('link_probe', PathProbe()).rate_bps(
        rate, ceiling, content_bps, queue_s, now < steer.hold_until, now)
    if not display_state.get('video_active', True) or ws in getattr(self, 'video_paused_clients', ()):
        pad = 0.0
    if (pad > 0) != (display_state.get('link_padding', 0.0) > 0):
        data_logger.debug(f"Congestion control[{display_id}]: " + (
            f"probing the path at {rate:.0f} kbps (a still screen under a cut target)" if pad > 0 else
            f"probe ended at {rate:.0f} kbps" + (" (a queue)" if queue_s else "")))
    display_state['link_padding'] = pad
    relay = self.video_relay_groups.get(display_id, {}).get(ws)
    if relay is not None:
        relay.set_padding(pad, now + 2 * BACKPRESSURE_CHECK_INTERVAL_S)
paramdisplay_idstr
paramdisplay_statedict
paramnowfloat
paramlast_tickfloat
paramsteerCongestionSteer
paramceilingfloat
paramratefloat
paramqueue_sOptional[float]
paramoffered_bpsOptional[float]

Returns

None
func_estimate_client_fps(display_state, acked_id, configured_fps, now) -> float

Measured client FPS from acked-frame cadence, clamped to [1.0, configured_fps].

Sizes the backpressure window so a client rendering below the configured rate gets a correctly scaled one. The estimate updates only from healthy (unthrottled) intervals with forward progress and holds otherwise: during active backpressure the ack rate reflects the throttling, not the client, and following it would latch low fps -> tighter window -> stuck backpressure. now is passed in so the estimator is deterministic to test.

Source Code
def _estimate_client_fps(self, display_state: dict, acked_id: int,
                         configured_fps: Union[int, float], now: float) -> float:
    """Measured client FPS from acked-frame cadence, clamped to `[1.0, configured_fps]`.

    Sizes the backpressure window so a client rendering below the
    configured rate gets a correctly scaled one. The estimate updates only
    from healthy (unthrottled) intervals with forward progress and holds
    otherwise: during active backpressure the ack rate reflects the
    throttling, not the client, and following it would latch low fps ->
    tighter window -> stuck backpressure. `now` is passed in so the
    estimator is deterministic to test.
    """
    prev_id = display_state.get('_fps_sample_acked')
    prev_t = display_state.get('_fps_sample_time')
    est = display_state.get('_measured_client_fps', float(configured_fps))
    sending = display_state.get('backpressure_enabled', True)
    if prev_id is None or prev_t is None:
        display_state['_fps_sample_acked'] = acked_id
        display_state['_fps_sample_time'] = now
        display_state['_measured_client_fps'] = float(configured_fps)
        return float(configured_fps)
    dt = now - prev_t
    if dt >= 0.25:
        # Circular forward distance over the uint16 ack space.
        delta = (acked_id - prev_id) % (MAX_UINT16_FRAME_ID + 1)
        display_state['_fps_sample_acked'] = acked_id
        display_state['_fps_sample_time'] = now
        if sending and 0 < delta <= FRAME_ID_SUSPICIOUS_GAP_THRESHOLD:
            inst = delta / dt
            est = 0.4 * inst + 0.6 * est
    est = max(1.0, min(est, float(configured_fps)))
    display_state['_measured_client_fps'] = est
    return est
paramdisplay_statedict
paramacked_idint
paramconfigured_fpsUnion[int, float]
paramnowfloat

Returns

float
func_audit_session_end(perms) -> None

Record the end of a page's connection, for one recorded as connected.

Source Code
@staticmethod
def _audit_session_end(perms: Optional[dict]) -> None:
    """Record the end of a page's connection, for one recorded as connected."""
    started = (perms or {}).get("connected_at")
    if started:
        audit.emit("session.disconnect", transport="websockets", role=perms.get("role"),
                   slot=perms.get("slot"), duration_s=round(time.time() - started, 3))
parampermsOptional[dict]

Returns

None
funcsessions() -> List[Dict[str, Any]]

The pages on this transport, each with the round trip measured now: one ping per socket through the uplink gauge's clock, answered by the socket's own message loop within the moment given.

Source Code
async def sessions(self) -> List[Dict[str, Any]]:
    """The pages on this transport, each with the round trip measured now:
    one ping per socket through the uplink gauge's clock, answered by the
    socket's own message loop within the moment given."""
    sockets = list(self.clients)
    before = {ws: _uplink_session_state(ws)["seq"] for ws in sockets}
    for ws in sockets:
        await socket_gauge(ws).sample()
    deadline = time.monotonic() + 1.0
    while time.monotonic() < deadline and any(
            _uplink_session_state(ws)["seq"] == before[ws] for ws in sockets if not ws.closed):
        await asyncio.sleep(0.02)
    by_socket = {c.get('ws'): did for did, c in self.display_clients.items()}
    out = []
    for ws in sockets:
        perms = client_permissions.get(ws) or {}
        out.append({"id": perms.get("id"), "transport": "websockets", "role": perms.get("role"),
                    "slot": perms.get("slot"), "display": by_socket.get(ws, "primary"),
                    "connected_at": audit.rfc3339(perms["connected_at"]) if perms.get("connected_at") else None,
                    "rtt_ms": uplink_rtt_ms(ws)})
    return out

Returns

typing.List[typing.Dict[str, typing.Any]]
funcdisconnect_session(session_id) -> bool

Close the page session_id names; its handler then cleans up.

Source Code
async def disconnect_session(self, session_id: str) -> bool:
    """Close the page `session_id` names; its handler then cleans up."""
    for ws, perms in list(client_permissions.items()):
        if perms.get("id") == session_id and ws in self.clients:
            await ws.close(code=WSCloseCode.GOING_AWAY, message=b"Disconnected by the operator")
            return True
    return False
paramsession_idstr

Returns

bool
funcannounce_print_document(name, size) -> None

Tell every controller page a printed document waits in the spool.

Source Code
async def announce_print_document(self, name: str, size: int) -> None:
    """Tell every controller page a printed document waits in the spool."""
    secondary = {c.get('ws') for did, c in self.display_clients.items() if did != 'primary'}
    controllers = {ws for ws in self.clients if ws not in secondary
                   and client_permissions.get(ws, {}).get("role") != "viewer"}
    await self._send_print_documents(controllers, [(name, size)])
paramnamestr
paramsizeint

Returns

None
func_send_print_documents(sockets, documents) -> None
Source Code
async def _send_print_documents(self, sockets: set, documents: list) -> None:
    for name, size in documents:
        message = json.dumps({"type": "print_document", "name": name, "size_bytes": size})
        # Bounded like every control fan-out; the set is a computed one, so
        # the drop is mirrored into the registry.
        for ws in await _broadcast_to_clients(sockets, message, watched=True):
            self.clients.discard(ws)
paramsocketsset
paramdocumentslist

Returns

None
funccapture_candidates() -> List[Any]

The pages that may capture a device, in connection order: controllers on the primary display. A shared viewer never captures, whatever webcam_uplink_allowed would let a collaborator feed.

Source Code
def capture_candidates(self) -> List[Any]:
    """The pages that may capture a device, in connection order: controllers on the primary
    display. A shared viewer never captures, whatever `webcam_uplink_allowed` would let a
    collaborator feed."""
    secondary = {c.get('ws') for did, c in self.display_clients.items() if did != 'primary'}
    return [ws for ws, perms in client_permissions.items()
            if ws in self.clients and ws not in secondary
            and perms.get("role", "viewer") != "viewer"]

Returns

typing.List[typing.Any]
functell_capture(websocket, subject, wanted) -> bool

Sends one capture demand to one page; False where it could not be delivered.

Source Code
async def tell_capture(self, websocket: Any, subject: str, wanted: bool) -> bool:
    """Sends one capture demand to one page; False where it could not be delivered."""
    try:
        await asyncio.wait_for(
            websocket.send_str(f"{capture_demand.MSG_CAPTURE_DEMAND} {subject} {int(wanted)}"),
            timeout=2.0)
        return True
    except (ConnectionResetError, OSError, RuntimeError, asyncio.TimeoutError):
        return False
paramwebsocketAny
paramsubjectstr
paramwantedbool

Returns

bool
funcbroadcast_stream_resolution() -> None

Send each display's realized resolution to the socket rendering that display, and the primary's to every remaining socket (shared viewers render the primary stream). The payload names its display: applying the primary's resolution on a secondary page rescales that page's canvas and input mapping, so clicks land at primary-scaled coordinates.

Source Code
async def broadcast_stream_resolution(self) -> None:
    """Send each display's realized resolution to the socket rendering that
    display, and the primary's to every remaining socket (shared viewers
    render the primary stream). The payload names its display: applying the
    primary's resolution on a secondary page rescales that page's canvas and
    input mapping, so clicks land at primary-scaled coordinates."""
    per_socket = {}
    for did, client in self.display_clients.items():
        ws = client.get('ws')
        width, height = client.get('width', 0), client.get('height', 0)
        if ws is not None and width > 0 and height > 0:
            per_socket[ws] = json.dumps({
                "type": "stream_resolution",
                "width": width,
                "height": height,
                "displayId": did,
            })
    primary_client = self.display_clients.get('primary')
    primary_message = per_socket.get(primary_client.get('ws')) if primary_client else None
    if not per_socket and not primary_message:
        data_logger.warning("Cannot broadcast stream resolution: no display has realized dimensions.")
        return

    groups = {}
    for ws in self.clients:
        message_str = per_socket.get(ws) or primary_message
        if message_str:
            groups.setdefault(message_str, set()).add(ws)
    for message_str, sockets in groups.items():
        data_logger.debug(f"Broadcasting stream resolution to {len(sockets)} client(s): {message_str}")
        # Bounded: runs under _reconfigure_lock; a frozen client is dropped, not waited on.
        dropped = await _broadcast_to_clients(sockets, message_str, watched=True)
        # The fan-out ran over a computed set; mirror the drop into the registry.
        for ws in dropped:
            self.clients.discard(ws)

Returns

None
func_sync_wayland_realized_geometry(display_id, broadcast=True) -> None

Reconcile a display's state with the compositor's realized geometry.

Reads back what the pixelflux compositor actually realized on this display's output (it may even-mask dimensions or keep the old mode on a GBM allocation failure), folds it into display state/layouts and broadcasts stream_resolution so the client reconciles its canvas and input mapping — the Wayland counterpart of the X11 reconfigure path's realized clamp + broadcast. The read also acts as a barrier: the compositor answers it only after any queued capture (re)start finished.

Source Code
async def _sync_wayland_realized_geometry(self, display_id: str, broadcast: bool = True) -> None:
    """Reconcile a display's state with the compositor's realized geometry.

    Reads back what the pixelflux compositor actually realized on this
    display's output (it may even-mask dimensions or keep the old mode on a
    GBM allocation failure), folds it into display state/layouts and
    broadcasts stream_resolution so the client reconciles its canvas and
    input mapping — the Wayland counterpart of the X11 reconfigure path's
    realized clamp + broadcast. The read also acts as a barrier: the
    compositor answers it only after any queued capture (re)start finished.

    Args:
        display_id: The display to reconcile.
        broadcast: False defers the fan-out to a caller that broadcasts
            once for every display (the reconfigure pass).
    """
    if not IS_WAYLAND:
        return
    inst = self.capture_instances.get(display_id)
    module = inst.get('module') if inst else None
    if module is None:
        return
    try:
        geom = await asyncio.to_thread(
            module.get_realized_geometry, wayland_output_id(display_id))
    except Exception as e:
        data_logger.warning(f"Wayland realized-geometry read failed for '{display_id}': {e}")
        return
    if geom is None:
        # A timeout is unknown geometry, not zero: the prior state stays.
        data_logger.warning(
            f"Wayland realized-geometry read for '{display_id}' timed out; state left unreconciled.")
        return
    w, h, scale = geom
    if w <= 0 or h <= 0:
        return
    client = self.display_clients.get(display_id)
    if client is not None:
        client['width'], client['height'] = w, h
        if scale > 0:
            client['scale'] = scale
    layout = getattr(self, 'display_layouts', {}).get(display_id)
    if layout is not None:
        layout['w'], layout['h'] = w, h
    if display_id == 'primary' and self.app is not None:
        self.app.display_width = w
        self.app.display_height = h
    data_logger.info(
        f"Wayland realized geometry for '{display_id}': {w}x{h} @ scale {scale}")
    if broadcast:
        await self.broadcast_stream_resolution()
paramdisplay_idstr

The display to reconcile.

parambroadcastbool
= True

False defers the fan-out to a caller that broadcasts once for every display (the reconfigure pass).

Returns

None
func_current_primary_geometry() -> Optional[tuple]

The primary display's size as the server realizes it right now.

What a connection that may not resize the desktop streams: the primary's rectangle of an extended layout while a secondary display is connected (the X root then spans every display), else the root window (RandR) on X11 or the primary's screen on Wayland — read live, so a desktop resized between connections (selkies resize) is streamed at its new size rather than the last connection's.

Source Code
async def _current_primary_geometry(self) -> Optional[tuple]:
    """The primary display's size as the server realizes it right now.

    What a connection that may not resize the desktop streams: the
    primary's rectangle of an extended layout while a secondary display is
    connected (the X root then spans every display), else the root window
    (RandR) on X11 or the primary's screen on Wayland — read live, so a
    desktop resized between connections (selkies resize) is streamed at
    its new size rather than the last connection's.

    Returns:
        `(width, height)`, or None when the geometry cannot be read.
    """
    layout = getattr(self, 'display_layouts', {}).get('primary')
    if (layout and layout.get('w', 0) > 0 and layout.get('h', 0) > 0
            and any(did != 'primary' for did in self.display_clients)):
        return layout['w'], layout['h']
    if IS_WAYLAND:
        module = self._wayland_control_module()
        if module is None:
            return None
        try:
            geom = await asyncio.to_thread(
                module.get_realized_geometry, wayland_output_id('primary'))
        except Exception as e:
            data_logger.warning(f"Wayland primary geometry read failed: {e}")
            return None
        if geom is None:
            data_logger.warning("Wayland primary geometry read timed out; size unknown.")
            return None
        w, h, _scale = geom
    else:
        w, h = await read_realized_root((0, 0))
    return (w, h) if w > 0 and h > 0 else None

Returns

typing.Optional

(width, height), or None when the geometry cannot be read.

func_apply_wayland_cursor_size(dpi) -> None

Wayland counterpart of the X11 per-DPI cursor resize: the compositor reloads its theme cursor (composited overlay and named-cursor delivery both re-render) at the DPI-scaled size, live, no capture restart.

Source Code
async def _apply_wayland_cursor_size(self, dpi: Union[int, float]) -> None:
    """Wayland counterpart of the X11 per-DPI cursor resize: the compositor
    reloads its theme cursor (composited overlay and named-cursor delivery
    both re-render) at the DPI-scaled size, live, no capture restart."""
    if CURSOR_SIZE is None:
        return
    module = self._wayland_control_module()
    if module is None:
        return
    size = cursor_size_for_dpi(dpi, CURSOR_SIZE)
    try:
        if await asyncio.to_thread(module.set_cursor_size, size):
            data_logger.debug(f"Wayland cursor size set to {size} (DPI {dpi}).")
        else:
            data_logger.warning(f"Wayland compositor refused cursor size {size}.")
    except Exception as e:
        data_logger.warning(f"Wayland cursor resize failed: {e}")
paramdpiUnion[int, float]

Returns

None
func_update_cursor_cap(dpi) -> None

Scale the remote-cursor delivery cap with a new DPI, on both backends.

Tracks the DPI on the input handler and re-derives its cap from the DPI-scaled maximum sprite size (the connect-time seed downscales shapes past it; the desktop cursor itself was just resized for the same DPI). Running captures take the cap live through pixelflux's tunables path, so the sprite its cursor monitor delivers follows without a capture restart; later (re)starts thread it through CaptureSettings. On Wayland the compositor's composited cursor follows the output scale on its own (set_cursor_size re-derives its theme pixel size on DPI changes).

Source Code
def _update_cursor_cap(self, dpi: Union[int, float]) -> None:
    """Scale the remote-cursor delivery cap with a new DPI, on both backends.

    Tracks the DPI on the input handler and re-derives its cap from the
    DPI-scaled maximum sprite size (the connect-time seed downscales shapes
    past it; the desktop cursor itself was just resized for the same DPI).
    Running captures take the cap live through pixelflux's tunables path,
    so the sprite its cursor monitor delivers follows without a capture
    restart; later (re)starts thread it through CaptureSettings. On Wayland
    the compositor's composited cursor follows the output scale on its own
    (set_cursor_size re-derives its theme pixel size on DPI changes).
    """
    ih = self.input_handler
    if ih is None:
        return
    try:
        ih.system_dpi = float(dpi)
        ih.cursor_size_cap = int(ih.max_cursor_size * float(dpi) / 96.0)
    except Exception as e:
        data_logger.debug(f"cursor cap update skipped: {e}")
        return
    updated = 0
    for display_id, inst in list(self.capture_instances.items()):
        module, cs = inst.get('module'), inst.get('settings')
        if module is None or cs is None:
            continue
        try:
            cs.cursor_size_cap = int(ih.cursor_size_cap)
            module.update_tunables(cs)
            updated += 1
        except Exception as e:
            data_logger.debug(f"Live cursor cap update skipped for '{display_id}': {e}")
    data_logger.debug(
        f"Cursor size cap {ih.cursor_size_cap}px for DPI {dpi} "
        f"({updated} live capture(s) updated).")
paramdpiUnion[int, float]

Returns

None
func_settings_applied_summary(raddr, display_id) -> str

The line that closes a page's first SETTINGS: what its display streams as.

Source Code
def _settings_applied_summary(self, raddr: Any, display_id: str) -> str:
    """The line that closes a page's first SETTINGS: what its display streams as."""
    state = self.display_clients.get(display_id) or {}
    rc = state.get('rate_control_mode', self.rc_mode.value)
    rate = (f"{state.get('video_bitrate')} kbps" if rc == RateControlMode.CBR.value
            else f"crf {state.get('video_crf')}")
    return (f"Client {raddr} settings applied for '{display_id}': "
            f"{state.get('width')}x{state.get('height')}, {state.get('encoder')} "
            f"{rate}, {fps_label(state.get('framerate') or self.app.framerate)} fps"
            + (", software encoding" if state.get('use_cpu') else "") + ".")
paramraddrAny
paramdisplay_idstr

Returns

str
func_parse_settings_payload(payload_str) -> dict

Parse a SETTINGS JSON payload into typed values (absent keys become None).

audioRedundancy advertises Opus+RED de-RED capability for the audio path; keyboardLayout is an optional xkb layout hint (de, ch(fr)) that becomes the compositor's base layout on Wayland and is informational on X11; encoderFallback marks an encoder the page fell back to on its own rather than one its user picked; tabId names the browser tab the page runs in; ccStartKbps is the rate congestion control last held the display at for this page (RateHold); picked lists the keys its user just picked, which is what applies from a page beside the display's owner (_take_pick_beside_owner).

Source Code
def _parse_settings_payload(self, payload_str: str) -> dict:
    """Parse a SETTINGS JSON payload into typed values (absent keys become None).

    `audioRedundancy` advertises Opus+RED de-RED capability for the audio
    path; `keyboardLayout` is an optional xkb layout hint (`de`, `ch(fr)`)
    that becomes the compositor's base layout on Wayland and is
    informational on X11; `encoderFallback` marks an `encoder` the page
    fell back to on its own rather than one its user picked; `tabId` names
    the browser tab the page runs in; `ccStartKbps` is the rate congestion
    control last held the display at for this page (`RateHold`); `picked`
    lists the keys its user just picked, which is what applies from a page
    beside the display's owner (`_take_pick_beside_owner`).

    Raises:
        json.JSONDecodeError: When the payload is not valid JSON.
    """
    settings_data = json.loads(payload_str)
    parsed: dict[str, Any] = {}

    def get_int(k):
        v = settings_data.get(k)
        if v is None:
            return None
        # A float-yielding value ("29.7") truncates rather than failing the whole payload.
        return int(float(v))

    def get_number(k):
        v = settings_data.get(k)
        if v is None:
            return None
        value = float(v)
        return int(value) if value.is_integer() else value

    def get_bool(k):
        v = settings_data.get(k)
        return str(v).lower() == "true" if v is not None else None

    def get_str(k):
        v = settings_data.get(k)
        return str(v) if v is not None else None
    parsed["framerate"] = get_number("framerate")
    parsed["video_crf"] = get_int("video_crf")
    parsed["encoder"] = get_str("encoder")
    parsed["video_fullcolor"] = get_bool("video_fullcolor")
    parsed["video_10bit"] = get_bool("video_10bit")
    parsed["video_streaming_mode"] = get_bool("video_streaming_mode")
    parsed["manual_resolution"] = get_bool(
        "manual_resolution"
    )
    parsed["manual_width"] = get_int(
        "manual_width"
    )
    parsed["manual_height"] = get_int(
        "manual_height"
    )
    parsed["audio_bitrate"] = get_int("audio_bitrate")
    parsed["initialClientWidth"] = get_int(
        "initialClientWidth"
    )
    parsed["initialClientHeight"] = get_int(
        "initialClientHeight"
    )
    parsed["jpeg_quality"] = get_int("jpeg_quality")
    parsed["paint_over_jpeg_quality"] = get_int(
        "paint_over_jpeg_quality"
    )
    parsed["use_cpu"] = get_bool("use_cpu")
    parsed["cpu_encode_threading"] = get_bool("cpu_encode_threading")
    parsed["video_paintover_crf"] = get_int("video_paintover_crf")
    parsed["video_paintover_burst_frames"] = get_int("video_paintover_burst_frames")
    parsed["use_paint_over_quality"] = get_bool("use_paint_over_quality")
    parsed["scaling_dpi"] = get_int("scaling_dpi")
    parsed["enable_binary_clipboard"] = get_bool("enable_binary_clipboard")
    parsed["displayId"] = get_str("displayId") or "primary"
    parsed["displayPosition"] = get_str("displayPosition")
    parsed["displayScale"] = get_number("displayScale")
    parsed["rate_control_mode"] = get_str("rate_control_mode")
    parsed["video_bitrate"] = get_number("video_bitrate")
    parsed["force_aligned_resolution"] = get_bool("force_aligned_resolution")
    parsed["audioRedundancy"] = get_bool("audioRedundancy")
    # The page's tab, which tells its own reload from another page (`co_controllers`).
    parsed["tabId"] = (get_str("tabId") or "")[:64] or None
    parsed["keyboardLayout"] = get_str("keyboardLayout")
    parsed["encoderFallback"] = get_bool("encoderFallback")
    picked = settings_data.get("picked")
    parsed["picked"] = [k for k in picked if isinstance(k, str)][:64] if isinstance(picked, list) else []
    parsed["ccStartKbps"] = settings_data.get("ccStartKbps")
    data_logger.debug(f"Parsed client settings: {parsed}")
    return parsed
parampayload_strstr

Returns

dict
func_apply_client_settings(websocket_obj, settings, is_initial_settings, client_role='controller') -> None

Sanitize and apply one client's SETTINGS payload to its display.

Controller-only (a viewer's payload is ignored). Under _reconfigure_lock it resolves the target geometry (server-forced manual; with dynamic resizing disabled, the primary's current size whatever manual resolution, window size, or alignment the page asks for; else client manual or the initial client size), stores sanitized per-display tunables (primary updates also become session seeds for later displays, save an encoder the page fell back to, which stays that page's), applies DPI/cursor/keyboard-layout side effects, and applies video changes live where possible — only structural switches (encoder, use_cpu, fullcolor, rate-control, Wayland capture scale) restart the display's capture. Dimensional or initial changes trigger a full reconfigure AFTER the lock is released (reconfigure_displays self-acquires it).

Source Code
async def _apply_client_settings(
    self,
    websocket_obj: web.WebSocketResponse,
    settings: dict,
    is_initial_settings: bool,
    client_role: str = "controller",
) -> None:
    """Sanitize and apply one client's SETTINGS payload to its display.

    Controller-only (a viewer's payload is ignored). Under
    _reconfigure_lock it resolves the target geometry (server-forced
    manual; with dynamic resizing disabled, the primary's current size
    whatever manual resolution, window size, or alignment the page asks
    for; else client manual or the initial client size), stores sanitized
    per-display tunables (primary updates also become session seeds for
    later displays, save an encoder the page fell back to, which stays that
    page's), applies DPI/cursor/keyboard-layout side effects, and
    applies video changes live where possible — only structural switches
    (encoder, use_cpu, fullcolor, rate-control, Wayland capture scale)
    restart the display's capture. Dimensional or initial changes trigger a
    full reconfigure AFTER the lock is released (reconfigure_displays
    self-acquires it).

    Args:
        websocket_obj: The sending socket (used only for logging identity).
        settings: The parsed payload from _parse_settings_payload.
        is_initial_settings: True for the connection's first SETTINGS,
            which sizes the display and always reconfigures.
        client_role: "controller" or "viewer".
    """
    if client_role == "viewer":
        _viewer_raddr = client_permissions.get(websocket_obj, {}).get("remote_address", "unknown")
        data_logger.debug(f"Ignoring SETTINGS payload from viewer {_viewer_raddr}.")
        return

    display_id = settings.get("displayId", "primary")
    if display_id not in self.display_clients:
        data_logger.error(f"Cannot apply settings for unknown display_id '{display_id}'")
        return
    display_state = self.display_clients[display_id]
    data_logger.debug(
        f"Applying and sanitizing client settings for '{display_id}' (initial={is_initial_settings})"
    )
    def sanitize_value(name, client_value):
        """One-transport wrapper over the shared sanitizer (settings.py)."""
        return sanitize_client_setting(name, client_value, self.cli_args, data_logger)
    fallback_reset = False
    try:
        async with self._reconfigure_lock:
            # A controller arriving without an encoder of its own is not left on
            # the one another page fell back to.
            if (is_initial_settings and settings.get("encoder") is None
                    and display_state.get("encoder_fallback")):
                fallback_reset = True
                settings = dict(settings, encoder=self.app.encoder)
            old_settings = display_state.copy()
            old_display_width = display_state.get("width", 0)
            old_display_height = display_state.get("height", 0)
            old_position = display_state.get('position', 'right')
            new_position = settings.get("displayPosition", "right")
            target_w = None
            target_h = None
            keeps_current_geometry = False
            server_is_manual, _ = self.cli_args.manual_resolution
            client_wants_manual = sanitize_value("manual_resolution", settings.get("manual_resolution"))
            if server_is_manual:
                data_logger.debug(f"Server override is active. Forcing manual resolution from server configuration for display '{display_id}'.")
                try:
                    w_val = self.cli_args.manual_width
                    h_val = self.cli_args.manual_height
                    target_w = int(w_val[0] if isinstance(w_val, (list, tuple)) else w_val)
                    target_h = int(h_val[0] if isinstance(h_val, (list, tuple)) else h_val)
                    data_logger.info(f"Server override: Applying manual resolution {target_w}x{target_h}.")
                except (ValueError, TypeError, IndexError) as e:
                    data_logger.error(f"Server override failed: Could not parse manual resolution from server config. Error: {e}. Falling back.")
                    target_w = 1024
                    target_h = 768
            elif display_id == 'primary' and not getattr(
                    self.app, 'server_enable_resize', True):
                # The page's window or manual size is a resize like any r,
                # message; the initial reconfigure's stream_resolution
                # broadcast tells the client to fit.
                keeps_current_geometry = True
                asked = (f"manual resolution {settings.get('manual_width')}x{settings.get('manual_height')}"
                         if client_wants_manual else
                         f"initial size {settings.get('initialClientWidth')}x{settings.get('initialClientHeight')}")
                if is_initial_settings:
                    current = await self._current_primary_geometry()
                    if current is not None:
                        target_w, target_h = current
                    kept = f"{current[0]}x{current[1]}" if current else "its current size"
                    data_logger.info(
                        f"Primary {asked} ignored: dynamic resizing disabled; keeping the desktop at {kept}.")
                elif client_wants_manual:
                    # A page in manual mode repeats its size in every SETTINGS.
                    data_logger.debug(f"Primary {asked} ignored: dynamic resizing disabled.")
            elif client_wants_manual:
                data_logger.info(f"Client has requested manual resolution mode for display '{display_id}'.")
                target_w = sanitize_value("manual_width", settings.get("manual_width"))
                target_h = sanitize_value("manual_height", settings.get("manual_height"))
            elif is_initial_settings:
                target_w = settings.get("initialClientWidth")
                target_h = settings.get("initialClientHeight")
                # Client dimensions must not reach xrandr --fb unbounded.
                if isinstance(target_w, int):
                    target_w = max(1, min(target_w, 7680))
                if isinstance(target_h, int):
                    target_h = max(1, min(target_h, 4320))
            if not isinstance(target_w, int) or target_w <= 0:
                target_w = old_display_width if old_display_width > 0 else 1024
            if not isinstance(target_h, int) or target_h <= 0:
                target_h = old_display_height if old_display_height > 0 else 768
            if target_w % 2 != 0: target_w -= 1
            if target_h % 2 != 0: target_h -= 1
            if settings.get("force_aligned_resolution") is not None:
                display_state["force_aligned_resolution"] = sanitize_value(
                    "force_aligned_resolution", settings.get("force_aligned_resolution")
                )
            if server_is_manual:
                # A server-forced resolution follows the server's own toggle only.
                apply_alignment = self.cli_args.force_aligned_resolution[0]
            elif keeps_current_geometry:
                # Aligning the desktop's own size would resize it.
                apply_alignment = False
            else:
                apply_alignment = display_state["force_aligned_resolution"]
            if apply_alignment:
                aligned_w, aligned_h = align_dims_16(target_w, target_h)
                if aligned_w != target_w or aligned_h != target_h:
                    data_logger.debug(
                        f"Aligning resolution for '{display_id}' from {target_w}x{target_h} to {aligned_w}x{aligned_h} (16-pixel alignment)."
                    )
                target_w, target_h = aligned_w, aligned_h
            resolution_actually_changed = (target_w != old_display_width or target_h != old_display_height)
            position_actually_changed = (new_position != old_position)
            if resolution_actually_changed or position_actually_changed:
                display_state['width'] = target_w
                display_state['height'] = target_h
                display_state['position'] = new_position
                if display_id == 'primary':
                    self.app.display_width = target_w
                    self.app.display_height = target_h
            # The page's CSS-to-remote scale, rebroadcast with the layout so
            # a neighboring display can scale a cross-display drag over it.
            client_scale_changed = False
            if settings.get("displayScale") is not None:
                try:
                    client_scale = float(settings.get("displayScale"))
                except (TypeError, ValueError):
                    client_scale = 0.0
                if 0.05 <= client_scale <= 100.0 and \
                        display_state.get("client_scale") != client_scale:
                    display_state["client_scale"] = client_scale
                    client_scale_changed = True
            # Only keys the payload carries: sanitizing an absent (None) key
            # would reset the stored choice to the server default on every partial update.
            for key in ("encoder", "framerate", "video_crf", "video_fullcolor", "video_10bit",
                        "video_streaming_mode", "jpeg_quality", "paint_over_jpeg_quality",
                        "use_paint_over_quality", "video_paintover_crf",
                        "video_paintover_burst_frames", "video_bitrate"):
                if settings.get(key) is not None:
                    display_state[key] = sanitize_value(key, settings.get(key))
            if settings.get("encoder") is not None:
                display_state["encoder_fallback"] = bool(settings.get("encoderFallback"))
            if settings.get("use_cpu") is not None or settings.get("encoder") is not None:
                # The request is stored apart from the effective flag, so a spell on a
                # CPU-only encoder does not pin the display to software afterwards.
                if settings.get("use_cpu") is not None:
                    display_state["use_cpu_requested"] = sanitize_value(
                        "use_cpu", settings.get("use_cpu"))
                was_use_cpu = display_state["use_cpu"]
                display_state["use_cpu"] = effective_use_cpu(
                    display_state["encoder"],
                    display_state.get("use_cpu_requested"),
                    self._initial_use_cpu)
                if display_state["use_cpu"] != was_use_cpu:
                    data_logger.info(
                        f"Software encoding {'enabled' if display_state['use_cpu'] else 'disabled'} "
                        f"for encoder '{display_state['encoder']}'")
            if settings.get("cpu_encode_threading") is not None or settings.get("encoder") is not None:
                # As for use_cpu, the request is kept apart from what the encoder runs with,
                # which follows the encoder where neither the client nor the operator chose.
                if settings.get("cpu_encode_threading") is not None:
                    display_state["cpu_encode_threading_requested"] = sanitize_value(
                        "cpu_encode_threading", settings.get("cpu_encode_threading"))
                display_state["cpu_encode_threading"] = self._cpu_encode_threading_for(
                    display_state["encoder"], display_state.get("cpu_encode_threading_requested"))
            if settings.get("audio_bitrate") is not None:
                self.app.audio_bitrate = sanitize_value("audio_bitrate", settings.get("audio_bitrate"))
                display_state["audio_bitrate"] = self.app.audio_bitrate
            enable_rate_control, _ = self.cli_args.enable_rate_control
            if enable_rate_control and settings.get("rate_control_mode") is not None:
                display_state["rate_control_mode"] = sanitize_value("rate_control_mode", settings.get("rate_control_mode"))

            if display_id == 'primary':
                session_seeds = {
                    'encoder': ('app_encoder',),
                    'framerate': ('app_framerate',),
                    'video_crf': ('video_crf', '_initial_video_crf'),
                    'video_bitrate': ('video_bitrate', '_initial_video_bitrate'),
                    'video_fullcolor': ('video_fullcolor', '_initial_video_fullcolor'),
                    'video_10bit': ('video_10bit', '_initial_video_10bit'),
                    'video_streaming_mode': ('video_streaming_mode', '_initial_video_streaming_mode'),
                    'jpeg_quality': ('jpeg_quality', '_initial_jpeg_quality'),
                    'paint_over_jpeg_quality': ('paint_over_jpeg_quality', '_initial_paint_over_jpeg_quality'),
                    'use_cpu': ('use_cpu', '_initial_use_cpu'),
                    'cpu_encode_threading': ('cpu_encode_threading', '_initial_cpu_encode_threading'),
                    'use_paint_over_quality': ('use_paint_over_quality', '_initial_use_paint_over_quality'),
                    'video_paintover_crf': ('video_paintover_crf', '_initial_video_paintover_crf'),
                    'video_paintover_burst_frames': ('video_paintover_burst_frames', '_initial_video_paintover_burst_frames'),
                }
                # The use_cpu seed is the client's request: seeding the effective flag
                # would pin every later display to software after one CPU-only encoder.
                seed_sources = {'use_cpu': 'use_cpu_requested',
                                'cpu_encode_threading': 'cpu_encode_threading_requested'}
                for key, targets in session_seeds.items():
                    if settings.get(key) is None:
                        continue
                    if key == 'encoder' and (fallback_reset or display_state.get("encoder_fallback")):
                        continue
                    value = display_state.get(seed_sources.get(key, key))
                    if value is None:
                        continue
                    for attr in targets:
                        if attr == 'app_framerate':
                            self.app.set_framerate(value)
                        elif attr == 'app_encoder':
                            self.app.encoder = value
                            # Written through: transport services re-seed from the
                            # settings singleton on a mode switch.
                            app_settings.encoder = value
                            app_settings._encoder_client_set = True
                        else:
                            setattr(self, attr, value)
                    data_logger.debug(f"Session default {key} updated to {value} for new displays.")
                if enable_rate_control and settings.get('rate_control_mode') is not None:
                    self.rc_mode = RateControlMode(display_state['rate_control_mode'])
                    data_logger.debug(
                        f"Session default rate_control_mode updated to {self.rc_mode.value} for new displays."
                    )

            if self.input_handler and settings.get("enable_binary_clipboard") is not None:
                self.enable_binary_clipboard = sanitize_value("enable_binary_clipboard", settings.get("enable_binary_clipboard"))
                await self.input_handler.update_binary_clipboard_setting(self.enable_binary_clipboard)
            if self.input_handler:
                kb_layout = settings.get("keyboardLayout")
                if kb_layout:
                    await self.input_handler.apply_client_keyboard_layout(kb_layout)
            if settings.get("scaling_dpi") is not None:
                new_dpi = sanitize_value("scaling_dpi", settings.get("scaling_dpi"))
            else:
                # Partial SETTINGS keeps the display's current DPI.
                new_dpi = old_settings.get("scaling_dpi")
            if app_settings._overridden.get("scaling_dpi", False):
                # An operator-set DPI (CLI/env) governs the desktop.
                if new_dpi is not None and new_dpi != old_settings.get("scaling_dpi"):
                    data_logger.info("Ignoring client DPI sync: scaling_dpi is operator-overridden.")
                new_dpi = old_settings.get("scaling_dpi")
            elif (not IS_WAYLAND and display_id != 'primary'
                  and new_dpi != old_settings.get("scaling_dpi")):
                # X11 has one DPI, and every page derives its own from the
                # screen it is shown on: the primary's page owns it.
                data_logger.info(
                    f"Ignoring DPI {new_dpi} from '{display_id}': the desktop DPI follows the primary display."
                )
                new_dpi = old_settings.get("scaling_dpi")
            if new_dpi is not None and new_dpi != old_settings.get("scaling_dpi"):
                data_logger.info(f"DPI changed from {old_settings.get('scaling_dpi')} to {new_dpi}. Applying system-level change.")
                if not IS_WAYLAND:
                    await set_dpi(new_dpi)
                    if CURSOR_SIZE is not None:
                        new_cursor_size = cursor_size_for_dpi(new_dpi, CURSOR_SIZE)
                        await set_cursor_size(new_cursor_size)
                    self._update_cursor_cap(new_dpi)
                elif display_id == 'primary' or display_id in (self.display_layouts or {}):
                    # Each display scales its own screen. Only what the session
                    # compositor leaves becomes the capture scale, which the
                    # 'scale' restart trigger below reads. A secondary without
                    # an output yet is scaled by the layout pass that grows it.
                    display_state['scale'] = (
                        await self.input_handler.realize_wayland_dpi(
                            new_dpi, display_id,
                            (display_state.get('width'), display_state.get('height')))
                        if self.input_handler else float(new_dpi) / 96.0)
                if IS_WAYLAND and display_id == 'primary':
                    self._update_cursor_cap(new_dpi)
                    await self._apply_wayland_cursor_size(new_dpi)

            display_state["scaling_dpi"] = new_dpi
            dimensional_change = resolution_actually_changed or position_actually_changed

            video_params_list = [
                'encoder', 'framerate', 'video_crf', 'video_fullcolor', 'video_10bit', 'video_streaming_mode',
                'jpeg_quality', 'paint_over_jpeg_quality', 'use_cpu', 'video_paintover_crf',
                'video_paintover_burst_frames', 'use_paint_over_quality', 'rate_control_mode', 'video_bitrate',
                'cpu_encode_threading',
            ]
            if IS_WAYLAND:
                video_params_list.append('scale')

            video_params_changed = any(
                display_state.get(key) != old_settings.get(key)
                for key in video_params_list
            )
            audio_bitrate_changed = self.app.audio_bitrate != old_settings.get('audio_bitrate')
            if audio_bitrate_changed and self.is_pcmflux_capturing:
                # Atomic in pcmflux; the pipeline keeps running.
                try:
                    self.pcmflux_module.update_audio_bitrate(int(self.app.audio_bitrate))
                    data_logger.info(f"Applied audio bitrate live: {self.app.audio_bitrate} bps")
                except Exception as e:
                    data_logger.warning(f"Live audio bitrate update failed ({e}); restarting audio pipeline.")
                    async with self._audio_lock:
                        if self.is_pcmflux_capturing:
                            await self._stop_pcmflux_pipeline()
                            await self._start_pcmflux_pipeline()
            needs_fallback_reconfigure = False
            if not (is_initial_settings or dimensional_change) and video_params_changed:
                restart_video_params = ['encoder', 'use_cpu', 'cpu_encode_threading', 'video_fullcolor', 'video_10bit',
                                        'rate_control_mode']
                if IS_WAYLAND:
                    # A capture scale change reconfigures the output, which the
                    # live-tunables path cannot apply.
                    restart_video_params.append('scale')
                video_restart_needed = any(
                    display_state.get(k) != old_settings.get(k) for k in restart_video_params
                )
                module = self.capture_instances.get(display_id, {}).get('module')
                if not video_restart_needed and module is not None:
                    data_logger.info(f"Applying video settings for '{display_id}' live (no restart).")
                    try:
                        layout = self.display_layouts.get(display_id) or {
                            'w': display_state.get('width', 0), 'h': display_state.get('height', 0),
                            'x': 0, 'y': 0,
                        }
                        fresh = self._get_capture_settings(
                            display_id, layout['w'], layout['h'], layout['x'], layout['y']
                        )
                        module.update_framerate(self._capture_fps(display_state))
                        module.update_video_bitrate(int(round(self._video_bitrate_kbps(display_state))))
                        module.update_tunables(fresh)
                        self._track_capture_settings(display_id, fresh=fresh)
                    except Exception as e:
                        data_logger.warning(
                            f"Live video settings update failed for '{display_id}' ({e}); restarting its capture."
                        )
                        video_restart_needed = True
                if video_restart_needed or module is None:
                    # A STOP_VIDEO'd display stays stopped; the next START_VIDEO
                    # builds its capture from the stored values.
                    if not display_state.get('video_active', True):
                        data_logger.info(
                            f"Video parameters changed for '{display_id}' while its stream "
                            "is stopped; deferring the restart to the next START_VIDEO."
                        )
                    elif display_id in self.display_layouts:
                        data_logger.info(
                            f"Video parameters changed for '{display_id}'. "
                            "Restarting its capture stream without reconfiguring displays."
                        )
                        layout = self.display_layouts[display_id]
                        await self._stop_capture_for_display(display_id)
                        await self._start_capture_for_display(
                            display_id=display_id,
                            width=layout['w'], height=layout['h'],
                            x_offset=layout['x'], y_offset=layout['y']
                        )
                        await self._start_backpressure_task_if_needed(display_id)
                        # A static screen must still repaint (the Wayland damage tracker
                        # stays warm across a stop/start) and clients must relearn the encoder.
                        self._schedule_idr_for_display(display_id)
                        await self._broadcast_live_server_settings(display_id)
                        if IS_WAYLAND:
                            await self._sync_wayland_realized_geometry(display_id)
                    else:
                        data_logger.warning(
                            f"Cannot restart capture for '{display_id}': no layout found. "
                            "Triggering full reconfiguration as a fallback."
                        )
                        needs_fallback_reconfigure = True
                if display_state.get('framerate') != old_settings.get('framerate'):
                    data_logger.info(f"Frame rate for '{display_id}' is now {fps_label(display_state.get('framerate'))} fps.")
                    await self._refresh_display_mode()
    except BaseException:
        # A raise skips the pending re-check below; a reconfigure coalesced
        # during the hold must not be stranded.
        if self._reconfigure_pending:
            await self.reconfigure_displays()
        raise
    if is_initial_settings or dimensional_change:
        data_logger.debug(
            f"Initial setup or dimensional change detected for '{display_id}'. "
            "Performing full display reconfiguration."
        )
        await self.reconfigure_displays()
    elif needs_fallback_reconfigure or self._reconfigure_pending:
        await self.reconfigure_displays()
    elif client_scale_changed:
        # No reconfigure ran to carry the new scale; announce it alone.
        await self.broadcast_display_config()
    if fallback_reset:
        # The page keyed its demux to the fallback it was told of on connecting.
        await self._broadcast_live_server_settings(display_id)
    if is_initial_settings and self.client_settings_received and not self.client_settings_received.is_set():
        self.client_settings_received.set()
paramwebsocket_objweb.WebSocketResponse

The sending socket (used only for logging identity).

paramsettingsdict

The parsed payload from _parse_settings_payload.

paramis_initial_settingsbool

True for the connection's first SETTINGS, which sizes the display and always reconfigures.

paramclient_rolestr
= 'controller'

"controller" or "viewer".

Returns

None
func_report_client_presence() -> None

Tell the supervisor whether any client is connected (idle shutdown gate).

Source Code
def _report_client_presence(self) -> None:
    """Tell the supervisor whether any client is connected (idle shutdown gate)."""
    if self.supervisor:
        self.supervisor.set_clients_present(bool(self.clients))

Returns

None
func_holds_input_authority(websocket, perms=None) -> bool

Whether this socket may drive keyboard/mouse input. perms supplies the entry for a socket already removed from client_permissions.

Source Code
def _holds_input_authority(self, websocket: web.WebSocketResponse,
                           perms: Optional[dict] = None) -> bool:
    """Whether this socket may drive keyboard/mouse input. `perms` supplies the
    entry for a socket already removed from client_permissions."""
    if perms is None:
        perms = client_permissions.get(websocket)
    return sessions._perms_hold_input_authority(perms)
paramwebsocketweb.WebSocketResponse
parampermsOptional[dict]
= None

Returns

bool
funcws_handler(websocket, remote_address, token='', query_role='', query_slot=None) -> None

Run one data-WebSocket connection from handshake to cleanup.

The connection's whole lifecycle lives here: auth (token in secure mode, query role/slot in legacy mode), reconnect rate-limiting, the handshake pushes (MODE, the secure-mode MK_ACCESS verdict, display roster, cursor, server settings), the message dispatch loop (SETTINGS, ACKs, video/audio start/stop, resize, DPI, mic PCM, and the shared input protocol), and the finally-block teardown: input-state release gated on departing input authority, RED re-gate, deferred display teardown behind the reconnect grace, and last-client pipeline/collector shutdown.

Held keys, modifiers, and pointer buttons are one global desktop state, so a departing socket force-releases them only if it could drive input AND its state is now unowned: the primary display's owner always qualifies, anything else only as the last input-capable client — a shared viewer or a second display's window leaving must not drop the keys or the in-progress drag of a client that is still connected. Keys the gate leaves alone belong to a connected client, and a crashed client's are healed by the input handler's heartbeat stale-sweep.

Source Code
async def ws_handler(
    self,
    websocket: web.WebSocketResponse,
    remote_address: tuple,
    token: str = "",
    query_role: str = "",
    query_slot: Optional[str] = None,
) -> None:
    """Run one data-WebSocket connection from handshake to cleanup.

    The connection's whole lifecycle lives here: auth (token in secure
    mode, query role/slot in legacy mode), reconnect rate-limiting, the
    handshake pushes (MODE, the secure-mode MK_ACCESS verdict, display
    roster, cursor, server settings), the message dispatch loop (SETTINGS,
    ACKs, video/audio start/stop, resize, DPI, mic PCM, and the shared
    input protocol), and the finally-block teardown: input-state release
    gated on departing input authority, RED re-gate, deferred display
    teardown behind the reconnect grace, and last-client
    pipeline/collector shutdown.

    Held keys, modifiers, and pointer buttons are one global desktop state,
    so a departing socket force-releases them only if it could drive input
    AND its state is now unowned: the primary display's owner always
    qualifies, anything else only as the last input-capable client — a
    shared viewer or a second display's window leaving must not drop the
    keys or the in-progress drag of a client that is still connected. Keys
    the gate leaves alone belong to a connected client, and a crashed
    client's are healed by the input handler's heartbeat stale-sweep.

    Args:
        websocket: The prepared WebSocket.
        remote_address: `(ip, port)` of the peer.
        token: Auth token (secure mode only).
        query_role: Legacy-mode role request ("viewer" caps the role).
        query_slot: Legacy-mode gamepad slot request ("2".."4").
    """
    if self.is_secure_mode:
        await self.config_gate.wait()
        permissions = sessions._lookup_session_token(token)
        if permissions is None:
            data_logger.warning(f"Rejecting connection from {remote_address}: Missing or invalid token.")
            await websocket.close(code=4001, message=b"Invalid authentication token")
            return

        role = sessions.token_role(permissions)
        client_permissions[websocket] = {
            "token": token,
            "role": role,
            "slot": permissions.get("slot"),
            "remote_address": remote_address,
            "data_server": self,
            "id": secrets.token_hex(4),
            "connected_at": time.time(),
        }
        data_logger.debug(f"Client {remote_address} authenticated with token. Role: {role}, Slot: {permissions.get('slot')}")
        auth_success_payload = json.dumps({
            "role": role,
            "slot": permissions.get("slot"),
        })
        await websocket.send_str(f"AUTH_SUCCESS,{auth_success_payload}")
    else:
        role = "controller"
        slot = None
        if query_role == "viewer":
            role = "viewer"
        if query_slot is not None:
            try:
                slot_num = int(query_slot)
                if 2 <= slot_num <= 4:
                    slot = slot_num
            except (ValueError, TypeError):
                pass
        # Enforcement, not link visibility: the WebRTC signaling server refuses
        # these outright, so a disabled shared/player page is refused here too.
        refusal = None
        if role == "viewer" and slot is None and not getattr(self.cli_args, 'enable_shared', (True,))[0]:
            refusal = "Strict shared clients are not enabled."
        elif slot is not None and not getattr(self.cli_args, f'enable_player{slot}', (True,))[0]:
            refusal = f"Player slot {slot} is not enabled."
        if refusal:
            data_logger.warning(f"Refusing legacy client {remote_address}: {refusal}")
            try:
                await websocket.send_str(f"KILL {refusal}")
                await websocket.close(code=1008, message=refusal.encode())
            except (ConnectionResetError, OSError, RuntimeError):
                pass
            return
        client_permissions[websocket] = {"token": None, "role": role, "slot": slot, "remote_address": remote_address,
                                         "id": secrets.token_hex(4), "connected_at": time.time()}
        data_logger.debug(f"Legacy client {remote_address} connected. Role: {role}, Slot: {slot}")

    global TARGET_FRAMERATE
    current_time = time.monotonic()
    ip_address, _ = remote_address
    last_time = self.last_connection_times.get(ip_address)
    if last_time:
        elapsed_ms = (current_time - last_time) * 1000
        if elapsed_ms < self.RECONNECT_DEBOUNCE_MS:
            data_logger.warning(
                f"Client {ip_address} reconnecting too quickly ({elapsed_ms:.1f}ms). Rejecting connection."
            )
            client_permissions.pop(websocket, None)
            await websocket.close(code=4029, message=b"Rate limited: reconnecting too quickly")
            return
    self.last_connection_times[ip_address] = current_time
    if len(self.last_connection_times) > self.MAX_RECENT_CLIENTS:
        self.last_connection_times.popitem(last=False)
    raddr = remote_address
    self.clients.add(websocket)
    perms = client_permissions.get(websocket) or {}
    data_logger.info(
        f"Client {raddr} connected ({'token' if self.is_secure_mode else 'legacy'}, "
        f"role {perms.get('role')}, slot {perms.get('slot')}).")
    audit.emit("session.connect", transport="websockets", role=perms.get("role"), slot=perms.get("slot"))
    self._report_client_presence()
    self.data_ws = (
        websocket 
    )
    self.capture_loop = self.capture_loop or asyncio.get_running_loop()
    initial_settings_processed = False
    visibility_asked = False

    client_display_id = None
    tab_id = None

    try:
        await websocket.send_str(f"MODE {self.mode}")
    except (ConnectionResetError, OSError, RuntimeError):
        self.clients.discard(websocket)
        self._audit_session_end(client_permissions.pop(websocket, None))
        if self.data_ws is websocket:
            self.data_ws = None
        return

    if self.is_secure_mode:
        # After MODE, which makes the page build the input context this verdict
        # applies to (a viewer holding the mk token attaches on 1, an outranked
        # controller detaches on 0).
        granted = sessions._mk_access_verdict(client_permissions.get(websocket))
        try:
            await websocket.send_str("MK_ACCESS,1" if granted else "MK_ACCESS,0")
        except (ConnectionResetError, OSError, RuntimeError):
            pass

    # A page joining after a secondary attached must learn the roster now, not
    # at the next reconfigure.
    try:
        await websocket.send_str(
            f"DISPLAY_CONFIG_UPDATE,{json.dumps(self._display_config_payload())}"
        )
    except (ConnectionResetError, OSError, RuntimeError):
        pass

    await self.send_current_cursor(websocket, raddr)

    # Which display this socket renders is only known from its first SETTINGS;
    # the primary's live encoder is what a viewer renders and a later display seeds from.
    await self._refresh_second_screen_capacity()
    server_settings_payload = {
        "type": "server_settings",
        "settings": self._settings_payload_for_display('primary'),
    }
    try:
        await websocket.send_str(json.dumps(server_settings_payload))
    except (ConnectionResetError, OSError, RuntimeError):
        self.clients.discard(websocket)
        self._audit_session_end(client_permissions.pop(websocket, None))
        if self.data_ws is websocket:
            self.data_ws = None
        return
    if self.supervisor and client_permissions.get(websocket, {}).get("role") != "viewer":
        await self._send_print_documents({websocket}, self.supervisor.pending_print_documents())
    await capture_demand.sync(self)

    self._last_adjustment_time = self._last_time_client_ok = time.monotonic()
    self._active_pipeline_last_sent_frame_id = 0
    self._client_acknowledged_frame_id = -1
    self._last_client_acknowledged_frame_id_update_time = time.monotonic()
    self._previous_ack_id_for_stall_check = -1
    self._previous_sent_id_for_stall_check = -1
    self._last_client_stable_report_time = time.monotonic()
    # Per-connection sender over the instance-wide singleton collectors.
    # Blocks on client_settings_received, which may never be set: canceled
    # with the connection.
    start_audio_task_ws = None
    initial_audio_task_ws = None

    mic_setup_done = False
    # Mic chunks arrive tens of times a second and each setup retry is a batch
    # of sound-server operations.
    mic_setup_retry_at = 0.0
    mic_disabled_sent = False
    mic_error = False
    webcam_disabled_sent = False
    pa_module_index = None
    # Only the loader of module-virtual-source unloads it; a reused source is
    # left for the other transport.
    pa_module_owned = False
    # Per connection, so module ownership and teardown follow the socket.
    mic_control: Optional[AudioControl] = None

    # pcmflux AudioPlayback: a GIL-released, non-blocking enqueue into a
    # stream on its own thread.
    mic_playback = None

    if not self.input_handler:
        logger.error(
            f"Data WS handler for {raddr}: Critical - self.input_handler (global) is not set. Input processing will fail."
        )

    gpu_id_for_stats = getattr(self.app, "gpu_id", GPU_ID_DEFAULT)
    # Stats must describe the GPU the pipeline captures/encodes on.
    dri_node_for_stats = resource_stats.gpu_node(
        _EXPLICIT_GPU_ID, str(getattr(self.cli_args, "encode_dri", "") or ""))

    try:
        # This socket is in the audio fan-out before its SETTINGS (a viewer never
        # sends one). It leaves the gate alone until its SETTINGS says what it
        # decodes, or AUDIO_RED_SETTLE_S passes: a page reconnecting in place
        # would otherwise restart the capture twice, down to plain Opus and back.
        if self.is_pcmflux_capturing:
            self._red_unsettled.add(websocket)
            _spawn_background_task(self._settle_red(websocket))

        if self._resource_monitor is None:
            self._resource_monitor = resource_stats.ResourceMonitor(
                gpu_id=gpu_id_for_stats, dri_node=dri_node_for_stats,
                metrics=getattr(self, 'metrics', None))
            self._resource_monitor.watched = lambda: bool(self._stats_subscribers)
            self._resource_monitor.on_tick = self._send_stream_stats
            self._resource_monitor.start()

        # An unlocked default-off microphone only sets the client toggle: a
        # runtime enable must not need a reconnect, so setup still runs.
        _mic_on, _mic_locked = settings.microphone_enabled
        if not settings.audio_enabled[0] or (not _mic_on and _mic_locked):
            data_logger.debug("Audio/microphone disabled in settings. Skipping PulseAudio setup.")
        else:
            # The bounded connect keeps a missing sound server from stalling the
            # handshake before the client can claim its display.
            mic_control = AudioControl("selkies-mic-handler")
            if await mic_control.open():
                data_logger.info(
                    f"Sound server control ready for the microphone ({mic_control.backend}).")
            else:
                data_logger.error("Sound server control unavailable; microphone forwarding disabled.")
                mic_error = True

        async for msg in websocket:
            # autoping is off: answer PING here, feed PONG to the uplink gauge.
            if msg.type == WSMsgType.PING:
                await websocket.pong(msg.data)
                continue
            if msg.type == WSMsgType.PONG:
                note_pong(websocket, msg.data)
                continue
            self._heard_at[websocket] = time.monotonic()
            # A 0x05 frame is gzip-wrapped control text: inflated into a TEXT
            # message so the dispatch below (permission checks included) sees it as such.
            if (msg.type == WSMsgType.BINARY and msg.data
                    and msg.data[0] == 0x05):
                try:
                    _text = inflate_gz_bounded(msg.data[1:])
                except ValueError as e:
                    data_logger.warning(f"Dropping client gzip frame: {e}")
                    continue
                except Exception:
                    data_logger.warning("Dropping undecodable client gzip frame.")
                    continue
                msg = SimpleNamespace(type=WSMsgType.TEXT, data=_text)

            if msg.type == WSMsgType.BINARY:
                if not msg.data:
                    continue
                data = msg.data
                msg_type = data[0]
                # A webcam frame is handed over whole with an offset, never
                # sliced into a copy.
                payload = data[1:] if msg_type != WS_OPCODE_WEBCAM else b""
                # Opcode 0x02 carries mic PCM.
                if msg_type == 0x02:
                    # Mirrors the text-input gate, collab escape hatch included,
                    # so both transports gate the mixer alike.
                    mic_perms = client_permissions.get(websocket) or {}
                    mic_ok = mic_perms.get("role") != "viewer" or (
                        settings.enable_collab[0]
                        and sessions.active_mk_token is not None
                        and mic_perms.get("token") == sessions.active_mk_token
                    )
                    if not mic_ok:
                        if not mic_disabled_sent:
                            mic_disabled_sent = True
                            data_logger.info(
                                f"Dropping microphone data from view-only client {remote_address}.")
                            try:
                                await websocket.send_str("MICROPHONE_DISABLED")
                            except (ConnectionResetError, OSError, RuntimeError):
                                pass
                        continue
                    # Only a locked-off microphone refuses data: an unlocked
                    # default-off is the client toggle, and data means it is on.
                    if mic_error or not settings.audio_enabled[0] or (
                            not settings.microphone_enabled[0] and settings.microphone_enabled[1]):
                        if not mic_disabled_sent:
                            mic_disabled_sent = True
                            data_logger.info("Microphone is disabled/errored. Sending MICROPHONE_DISABLED to client.")
                            try:
                                await websocket.send_str("MICROPHONE_DISABLED")
                            except (ConnectionResetError, OSError, RuntimeError):
                                pass
                        continue
                    if mic_control is None:
                        if len(payload) > 0:
                            data_logger.warning(
                                "Sound server control not connected. Skipping microphone data."
                            )
                        continue

                    if not mic_setup_done:
                        if time.monotonic() < mic_setup_retry_at:
                            continue
                        data_logger.debug(
                            "Performing PulseAudio/PipeWire virtual microphone setup check..."
                        )
                        pa_module_index, pa_module_owned = await mic_control.ensure_virtual_microphone(
                            self.audio_device_name, self.is_pcmflux_capturing
                        )
                        mic_setup_done = pa_module_index is not None
                        if not mic_setup_done:
                            mic_setup_retry_at = time.monotonic() + 5.0

                    if not mic_setup_done or not payload:
                        if not mic_setup_done and len(payload) > 0:
                            data_logger.warning(
                                "Mic setup not complete, skipping mic data."
                            )
                        continue

                    if not PCMFLUX_PLAYBACK_AVAILABLE:
                        if not mic_error:
                            mic_error = True
                            data_logger.error(
                                "pcmflux AudioPlayback unavailable; microphone forwarding disabled."
                            )
                        continue

                    # The stream is created once (blocking connect, offloaded); each
                    # chunk is a GIL-released, non-blocking write that drops oldest inside.
                    try:
                        if mic_playback is None:
                            _pb = AudioPlayback()
                            ps = AudioPlaybackSettings()
                            ps.device_name = b"input"
                            ps.sample_rate = 24000
                            ps.channels = 1
                            ps.latency_ms = 40
                            await asyncio.to_thread(_pb.start, ps)
                            # Published only after a successful start, so a failed
                            # one is retried on the next chunk.
                            mic_playback = _pb
                        mic_playback.write(payload)
                    except Exception as e_rust_mic:
                        data_logger.error(
                            f"Rust mic playback error: {e_rust_mic}", exc_info=False
                        )
                        # Torn down so the next chunk reopens a fresh stream.
                        if mic_playback is not None:
                            _dead = mic_playback
                            mic_playback = None
                            try:
                                await asyncio.to_thread(_dead.stop)
                            except Exception:
                                pass

                elif msg_type == WS_OPCODE_WEBCAM:
                    # One encoded webcam frame, [opcode][codec][flags][payload]
                    # (webcam.py), gated like the microphone; the whole message
                    # goes to pixelflux with the payload offset, never copied.
                    cam_perms = client_permissions.get(websocket) or {}
                    cam_collab = (
                        settings.enable_collab[0]
                        and sessions.active_mk_token is not None
                        and cam_perms.get("token") == sessions.active_mk_token
                    )
                    if not webcam_uplink_allowed(cam_perms.get("role") == "viewer", cam_collab):
                        if not webcam_disabled_sent:
                            webcam_disabled_sent = True
                            try:
                                await websocket.send_str(MSG_WEBCAM_DISABLED)
                            except (ConnectionResetError, OSError, RuntimeError):
                                pass
                        continue
                    if len(data) <= WS_HEADER_LEN:
                        continue
                    cam = get_shared_webcam()
                    if cam.needs_ensure(data[1]) and await cam.ensure(data[1]) is None:
                        continue
                    cam_rotation, cam_flip = orientation_from_flags(data[2])
                    flags = cam.push(data, data[1], bool(data[2] & WS_FLAG_KEYFRAME),
                                     WS_HEADER_LEN, cam_rotation, cam_flip)
                    if cam.keyframe_wanted(flags):
                        try:
                            await websocket.send_str(MSG_WEBCAM_KEYFRAME)
                        except (ConnectionResetError, OSError, RuntimeError):
                            pass

            elif msg.type == WSMsgType.TEXT:
                message = msg.data
                if message == "_gz,1":
                    # Echoed so the client gzips its own large sends too.
                    websocket._ws_gz = True
                    try:
                        await websocket.send_str("_gz,1")
                    except Exception:
                        pass
                    continue
                if message == "_pad,1":
                    # The page drops WS_OPCODE_PADDING frames unread: its stream may be padded.
                    websocket._ws_pad = True
                    continue
                perms = client_permissions.get(websocket)
                if perms and perms.get("role") == "viewer":
                    # Authority lists shared with the WebRTC gate: the collab extras
                    # need enable_collab on, even for a viewer holding the mk token.
                    allowed_viewer_prefixes: tuple[str, ...] = VIEWER_ALLOWED_PREFIXES
                    if settings.enable_collab[0] and sessions.active_mk_token and perms.get("token") == sessions.active_mk_token:
                        allowed_viewer_prefixes = allowed_viewer_prefixes + VIEWER_COLLAB_EXTRA_PREFIXES
                    if not message.startswith(allowed_viewer_prefixes):
                        # A viewer's blur/visibility noise (kr would clobber the
                        # controller's held modifiers) is refused silently: a warning
                        # per blur floods the log.
                        if not message.startswith(VIEWER_SILENT_DROP_PREFIXES):
                            data_logger.warning(f"DENIED unauthorized message from viewer {remote_address}: {message[:100]}...")
                        continue

                if message.startswith("SETTINGS,"):
                    try:
                        _, payload_str = message.split(",", 1)
                        parsed_settings = self._parse_settings_payload(payload_str)
                        display_id = parsed_settings.get("displayId", "primary")
                        self.audio_redundancy_by_ws[websocket] = bool(
                            parsed_settings.get("audioRedundancy")
                        )
                        self._red_unsettled.discard(websocket)

                        client_perms = client_permissions.get(websocket)
                        client_role = client_perms.get("role") if client_perms else "controller"

                        if client_role == 'viewer':
                            data_logger.info(f"Viewer {remote_address} joins the 'primary' stream.")
                            if not initial_settings_processed:
                                initial_settings_processed = True

                            if 'primary' not in self.capture_instances:
                                await self._ensure_viewer_capture()

                            await self.broadcast_stream_resolution()

                            # Only the joining viewer is reset; the IDR opens its keyframe
                            # gate now, since an infinite GOP schedules none.
                            data_logger.debug("Sending PIPELINE_RESETTING to the new viewer and requesting an IDR.")
                            try:
                                await websocket.send_str("PIPELINE_RESETTING primary")
                            except (ConnectionResetError, OSError, RuntimeError):
                                pass
                            self._schedule_idr_for_display('primary')

                            continue

                        if display_id != 'primary':
                            # The published setting can lag a host-side change; re-read first.
                            await self._refresh_second_screen_capacity()
                            available, reason = self._second_screen_availability()
                            if not available:
                                data_logger.warning(
                                    f"Client from {remote_address} attempted to connect as secondary display ('{display_id}'), "
                                    f"but it is unavailable: {reason} Rejecting connection."
                                )
                                try:
                                    await websocket.send_str(f"KILL {reason}")
                                    await websocket.close(code=1008, message=b"Second screen unavailable")
                                except (ConnectionResetError, OSError, RuntimeError):
                                    pass
                                return
                        client_display_id = display_id
                        tab_id = parsed_settings.get("tabId")
                        if display_id == 'primary' and not visibility_asked:
                            # Its tab hidden may hand the display to a page beside it
                            # (`_settle_display_owner`); an older page ignores the ask.
                            visibility_asked = True
                            try:
                                await websocket.send_str("PAGE_VISIBILITY")
                            except (ConnectionResetError, OSError, RuntimeError):
                                pass
                        if display_id == 'primary' and self._joins_beside_owner(websocket, tab_id):
                            # Streamed as a viewer is, with its input taken as a
                            # controller's; the owner keeps the display, and the page
                            # starts on what it streams with.
                            joiners = self.co_controllers.setdefault('primary', OrderedDict())
                            if websocket not in joiners:
                                joiners[websocket] = tab_id
                                owner_tab = (self.display_clients.get('primary') or {}).get('tab_id')
                                data_logger.info(
                                    f"Controller {remote_address} joins 'primary' beside its owner "
                                    f"(tab {(tab_id or 'none')[:8]}, the owner's {(owner_tab or 'none')[:8]}).")
                                if 'primary' not in self.capture_instances:
                                    self._capture_for_page_beside(websocket)
                                await self.broadcast_stream_resolution()
                                try:
                                    await websocket.send_str("PIPELINE_RESETTING primary")
                                except (ConnectionResetError, OSError, RuntimeError):
                                    pass
                                self._schedule_idr_for_display('primary')
                                await self._tell_display_settings('primary', {websocket})
                            else:
                                await self._take_pick_beside_owner(websocket, parsed_settings, client_role)
                            continue
                        if (display_id == 'primary' and tab_id
                                and (self.display_clients.get('primary') or {}).get('ws') is not websocket):
                            # The page that takes the primary is in use (`_take_display_in_use`).
                            self._tab_used_at[tab_id] = time.monotonic()
                        if display_id in ['primary', 'display2']:
                            existing_client_info = self.display_clients.get(display_id)
                            if existing_client_info:
                                old_ws = existing_client_info.get('ws')
                                if old_ws and old_ws is not websocket and not old_ws.closed:
                                    kill_reason = f"a new {display_id} client connected connection killed"
                                    old_ws_raddr = client_permissions.get(old_ws, {}).get("remote_address", "unknown")
                                    old_tab = existing_client_info.get('tab_id')
                                    data_logger.warning(
                                        f"Killing old client for '{display_id}' at {old_ws_raddr}. Reason: {kill_reason} "
                                        f"(tab {(old_tab or 'none')[:8]}, the new page's {(tab_id or 'none')[:8]})"
                                    )
                                    # Handed over before the close yields: the superseded
                                    # handler only tears down an entry its socket still owns,
                                    # and must not stop the capture being taken over.
                                    existing_client_info['ws'] = websocket
                                    self._apply_decode_pace(display_id, existing_client_info, None)
                                    try:
                                        # The superseded socket is the one most likely frozen;
                                        # unbounded, the takeover would hang here.
                                        await asyncio.wait_for(old_ws.send_str(f"KILL {kill_reason}"), timeout=2.0)
                                        await asyncio.wait_for(
                                            old_ws.close(code=1000, message=b"Superseded by new client"),
                                            timeout=2.0,
                                        )
                                    except asyncio.TimeoutError:
                                        _close_abandoned_ws(old_ws)
                                    except (ConnectionResetError, OSError, RuntimeError):
                                        data_logger.debug(f"Old client for '{display_id}' was already disconnected.")
                                    except Exception as e:
                                        data_logger.error(f"Error while killing old client for '{display_id}': {e}")
                        if display_id != 'primary':
                            old_secondary_id = None
                            for existing_id, client_data in self.display_clients.items():
                                if existing_id != 'primary' and client_data.get('ws') is not websocket:
                                    old_secondary_id = existing_id
                                    break

                            if old_secondary_id:
                                data_logger.warning(
                                    f"New secondary display '{display_id}' connected. "
                                    f"Deactivating old secondary '{old_secondary_id}'."
                                )
                                old_secondary_client = self.display_clients.get(old_secondary_id)
                                if old_secondary_client:
                                    await self._stop_capture_for_display(old_secondary_id)
                                    old_secondary_client['video_active'] = False
                                    old_ws = old_secondary_client.get('ws')
                                    if old_ws:
                                        try:
                                            await asyncio.wait_for(old_ws.send_str("VIDEO_STOPPED"), timeout=2.0)
                                        except asyncio.TimeoutError:
                                            _close_abandoned_ws(old_ws)
                                        except (ConnectionResetError, OSError, RuntimeError):
                                            pass
                        if display_id not in self.display_clients:
                            data_logger.debug(f"Registering new client for display: {display_id}")
                            self.display_clients[display_id] = {
                                'ws': websocket, 
                                'tab_id': tab_id,
                                'decode_pace': None,
                                'width': 0, 'height': 0, 'position': 'right',
                                'acknowledged_frame_id': -1,
                                'acked_sent_at': None,
                                'last_sent_frame_id': 0,
                                'has_sent_any_frame': False,
                                'sent_timestamps': OrderedDict(),
                                'rtt_samples': deque(maxlen=RTT_SMOOTHING_SAMPLES),
                                'smoothed_rtt': 0.0,
                                'backpressure_enabled': True,
                                'backpressure_task': None,
                                'last_ack_update_time': time.monotonic(),
                                'unacked_since': None,
                                'stall_gated_at': None,
                                'video_active': self._video_start_state(websocket, display_id),
                                'encoder': self.app.encoder,
                                'framerate': self.app.framerate,
                                'video_crf': self._initial_video_crf,
                                'video_fullcolor': self._initial_video_fullcolor,
                                'video_10bit': self._initial_video_10bit,
                                'video_streaming_mode': self._initial_video_streaming_mode,
                                'jpeg_quality': self._initial_jpeg_quality,
                                'paint_over_jpeg_quality': self._initial_paint_over_jpeg_quality,
                                'use_cpu': effective_use_cpu(
                                    self.app.encoder, None, self._initial_use_cpu),
                                'cpu_encode_threading': self._cpu_encode_threading_for(self.app.encoder, None),
                                'video_paintover_crf': self._initial_video_paintover_crf,
                                'video_paintover_burst_frames': self._initial_video_paintover_burst_frames,
                                'use_paint_over_quality': self._initial_use_paint_over_quality,
                                 'rate_control_mode': self.rc_mode.value,
                                 'video_bitrate': self._initial_video_bitrate,
                                 'force_aligned_resolution': self.cli_args.force_aligned_resolution[0],
                                 # The density the desktop has, which the last page of any
                                 # session gave it, in the sanitizer's normalized form (an
                                 # enum, so str): a str-vs-int mismatch would read the first
                                 # SETTINGS as a DPI change.
                                 'scaling_dpi': str(applied_dpi() or int(float(getattr(app_settings, "scaling_dpi", "96") or 96))),
                                 # Replaced below on Wayland; the X11 capture has no scale.
                                 'scale': 1.0,
                            }
                            _expect_key_frame(self.display_clients[display_id])
                            # A steered display starts at the rate its path last carried
                            # for this page, not at the configured one.
                            if self.cli_args.congestion_control[0] and self.rc_mode == RateControlMode.CBR:
                                lo_kbps, hi_kbps = app_settings.video_bitrate
                                seeded = start_kbps(parsed_settings.get("ccStartKbps"),
                                                    float(lo_kbps), float(hi_kbps))
                                if seeded is not None and seeded < float(self._initial_video_bitrate):
                                    self.display_clients[display_id]['link_kbps'] = seeded
                                    data_logger.info(
                                        f"Congestion control[{display_id}]: starting at {seeded:.0f} kbps, "
                                        f"from the rate its page last held")
                            # The page stops being a capture candidate with its socket still open.
                            await capture_demand.sync(self)
                            if IS_WAYLAND and self.input_handler is not None:
                                # The ladder runs from the configured DPI before any client
                                # sync, so the first capture starts at the intended scale.
                                self.display_clients[display_id]['scale'] = (
                                    await self.input_handler.realize_wayland_dpi(
                                        getattr(app_settings, "scaling_dpi", "96") or 96,
                                        display_id))
                        else:
                            data_logger.debug(f"Client is taking over existing display '{display_id}'. Updating state for new connection.")
                            display_state = self.display_clients[display_id]
                            self._seat_display_page(display_id, display_state, websocket, tab_id)
                            # Only a page's first SETTINGS reactivates video; a later one
                            # must not resurrect a stream stopped with STOP_VIDEO.
                            if not initial_settings_processed:
                                display_state['video_active'] = self._video_start_state(websocket, display_id)
                                _forget_path(display_state)
                            # A warm takeover keeps the capture; no reconfigure runs when
                            # the dimensions are unchanged, so the reset and IDR go here.
                            try:
                                await websocket.send_str(f"PIPELINE_RESETTING {display_id}")
                            except (ConnectionResetError, OSError, RuntimeError):
                                pass
                            self._schedule_idr_for_display(display_id)

                        if display_id == 'primary' and websocket in self._beside_audio:
                            # Owning the display, its own audio is the session's now.
                            self._session_audio = self._beside_audio.pop(websocket)
                        if initial_settings_processed:
                            applied = self._settings_changed_by(websocket, parsed_settings)
                        else:
                            applied = parsed_settings
                            self._page_settings[websocket] = parsed_settings
                        await self._apply_client_settings(
                            websocket,
                            applied,
                            not initial_settings_processed,
                            client_role
                        )
                        await self._tell_display_settings(display_id, set(self.co_controllers.get(display_id, ())))
                        if not initial_settings_processed:
                            initial_settings_processed = True
                            data_logger.info(self._settings_applied_summary(remote_address, display_id))
                            settled = getattr(self._stream_watches.get(display_id), 'info', None)
                            if settled:
                                await self._publish_stream_info(display_id, settled)
                            video_wanted = self.display_clients.get(display_id, {}).get('video_active', False)
                            if video_wanted and display_id not in self.capture_instances:
                                data_logger.error("FATAL: Initial reconfiguration completed, but video pipeline did not start.")
                            # Its own task: the start asks the sound server for the
                            # capture sink, and one that accepts and never answers would
                            # otherwise hold every input frame this loop has yet to read
                            # behind its timeouts.
                            initial_audio_task_ws = asyncio.create_task(
                                self._apply_initial_audio_policy(websocket, display_id))

                    except json.JSONDecodeError:
                        data_logger.error(f"SETTINGS JSON decode error: {message}")
                    except Exception as e_set:
                        data_logger.error(
                            f"Error processing SETTINGS: {e_set}", exc_info=True
                        )

                elif stream_stats.stats_request(message) is not None:
                    if not stream_stats.stats_request(message):
                        self._stats_subscribers.discard(websocket)
                    elif websocket not in self._stats_subscribers:
                        self._stats_subscribers.add(websocket)
                        self._rush_stream_stats(client_display_id)

                elif message.startswith("CLIENT_FRAME_ACK"):
                    try:
                        parts = message.split(" ")
                        acked_frame_id = -1
                        target_display_id = client_display_id
                        if not target_display_id:
                            continue
                        if len(parts) >= 2:
                            acked_frame_id = int(parts[1])
                        else:
                            raise ValueError("ACK message has too few parts.")
                        # Optional: how long the client held the id before its
                        # ack tick fired. A backgrounded tab's timers clamp to a
                        # second, and that second is the client's, not the link's.
                        held_ms = 0.0
                        if len(parts) >= 3:
                            held_ms = max(0.0, float(parts[2]))
                        # The -1 sentinel is server-internal: accepted from the wire it
                        # would disable backpressure and the stall detector.
                        if not (0 <= acked_frame_id <= MAX_UINT16_FRAME_ID):
                            raise ValueError("ACK frame id outside uint16 wire space.")

                        # Only the registered client acks the frames the relay stamped;
                        # a viewer's ack would throttle the controller against a stream
                        # it never got.
                        display_state = self.display_clients.get(target_display_id)
                        if display_state and display_state.get('ws') is websocket:
                            _note_ack(display_state, acked_frame_id, held_ms)
                    except (IndexError, ValueError):
                        data_logger.warning(f"Malformed CLIENT_FRAME_ACK from {raddr}: {message}")

                elif message == "START_VIDEO":
                    was_paused = websocket in self.video_paused_clients
                    perms = client_permissions.get(websocket)
                    # A controller beside the display's owner pauses and resumes its
                    # own feed as a viewer does; the owner's stream goes on.
                    beside = websocket in self.co_controllers.get(client_display_id or 'primary', ())
                    if beside or (perms and perms.get("role") == "viewer"):
                        # Monotonic: a clock jump must not wedge the floor or the throttle.
                        now = time.monotonic()
                        if was_paused:
                            # A resume (a real state change) bypasses the throttle but
                            # keeps the IDR floor; throttled, it stays paused this cycle.
                            last_req_time = self.last_start_video_request_times.get(websocket, 0)
                            if now - last_req_time < VIEWER_RESUME_MIN_INTERVAL_S:
                                data_logger.warning(f"Throttled rapid resume from viewer {remote_address}; deferring its rejoin.")
                                self._schedule_deferred_viewer_rejoin(
                                    websocket,
                                    VIEWER_RESUME_MIN_INTERVAL_S - (now - last_req_time),
                                )
                                continue
                            self.last_start_video_request_times[websocket] = now
                        else:
                            # Short: a stalled viewer re-requests via its watchdog and
                            # must not wait long for a resync.
                            last_req_time = self.last_start_video_request_times.get(websocket, 0)
                            if now - last_req_time < 5.0:
                                data_logger.warning(f"Throttled START_VIDEO request from viewer {remote_address}. Ignoring.")
                                continue
                            self.last_start_video_request_times[websocket] = now

                    # After the throttle decision, so a throttled resume stays paused;
                    # role-agnostic, or a paused collaborator never rejoins.
                    if was_paused:
                        self.video_paused_clients.discard(websocket)
                        data_logger.info(f"START_VIDEO from resuming client ({remote_address}): rejoining its video feed.")

                    display_entry = (self.display_clients.get(client_display_id)
                                     if client_display_id and not beside else None)
                    if display_entry is not None and display_entry.get('ws') is not websocket:
                        # A superseded connection (reload overlap) must not drive its
                        # successor's stream.
                        data_logger.debug(f"Ignoring START_VIDEO for '{client_display_id}' from a superseded connection.")
                    elif display_entry is not None:
                        data_logger.info(f"Received START_VIDEO for '{client_display_id}'. Starting its stream.")
                        display_state = display_entry
                        # Landing on a capture that kept running continues mid-GOP: the
                        # socket needs the reset + IDR regardless of pause state.
                        resumed_onto_live_capture = (
                            client_display_id in self.capture_instances
                        )
                        # No await between this write and the capture start below: the
                        # flag and the lock-serialized start stay atomic vs a reconfigure.
                        display_state['video_active'] = True
                        if hasattr(self, 'display_layouts') and client_display_id in self.display_layouts:
                            layout = self.display_layouts[client_display_id]
                            data_logger.debug(f"Found existing layout for '{client_display_id}'. Starting capture with: {layout}")
                            try:
                                started = await self._start_capture_for_display(
                                    display_id=client_display_id,
                                    width=layout['w'], height=layout['h'],
                                    x_offset=layout['x'], y_offset=layout['y']
                                )
                                if not started:
                                    # A full reconfigure instead of a false VIDEO_STARTED.
                                    data_logger.warning(f"Capture start failed for '{client_display_id}'; reconfiguring.")
                                    await self.reconfigure_displays()
                                else:
                                    await self._start_backpressure_task_if_needed(client_display_id)
                                    if resumed_onto_live_capture:
                                        try:
                                            await websocket.send_str(f"PIPELINE_RESETTING {client_display_id}")
                                        except (ConnectionResetError, OSError, RuntimeError):
                                            pass
                                    await websocket.send_str("VIDEO_STARTED")
                                    # The client clears its cursor canvas on tab hide.
                                    await self.send_current_cursor(websocket, remote_address)
                            except Exception as e:
                                data_logger.error(f"Failed to restart individual stream for '{client_display_id}': {e}", exc_info=True)
                                await self.reconfigure_displays()
                        else:
                            data_logger.warning(f"No layout found for '{client_display_id}' on START_VIDEO. Performing full reconfiguration.")
                            await self.reconfigure_displays()
                            # VIDEO_STARTED only for a live capture; the client would
                            # otherwise believe a stream runs with no pipeline behind it.
                            started = False
                            inst = self.capture_instances.get(client_display_id)
                            module = inst.get('module') if inst else None
                            if module is not None:
                                try:
                                    started = bool(module.is_capturing)
                                except Exception:
                                    started = False
                            if started:
                                await websocket.send_str("VIDEO_STARTED")
                                await self.send_current_cursor(websocket, remote_address)
                            else:
                                data_logger.warning(f"Reconfigure did not start a live capture for '{client_display_id}'; not acking VIDEO_STARTED.")
                    else:
                        # A shared client needs a decode entry point (its own reset plus
                        # an IDR), not a pipeline rebuild, unless nothing runs.
                        if 'primary' in self.capture_instances:
                            data_logger.debug(f"START_VIDEO from shared client ({remote_address}): sending reset + IDR.")
                            try:
                                await websocket.send_str("PIPELINE_RESETTING primary")
                            except (ConnectionResetError, OSError, RuntimeError):
                                pass
                            self._schedule_idr_for_display('primary')
                            # The client clears its cursor canvas on tab hide.
                            await self.send_current_cursor(websocket, remote_address)
                        else:
                            data_logger.info(f"START_VIDEO from shared client ({remote_address}) with no active capture. Starting primary capture.")
                            if await self._ensure_viewer_capture():
                                try:
                                    await websocket.send_str("PIPELINE_RESETTING primary")
                                except (ConnectionResetError, OSError, RuntimeError):
                                    pass
                                self._schedule_idr_for_display('primary')
                                await self.send_current_cursor(websocket, remote_address)
                            else:
                                # A no-op with zero display clients.
                                await self.reconfigure_displays()

                elif message in ("PAGE_HIDDEN", "PAGE_SHOWN"):
                    # A controller page's tab, as PAGE_VISIBILITY asked of it.
                    if message == "PAGE_SHOWN":
                        self._page_hidden_at[websocket] = None
                        self._page_shown_at[websocket] = time.monotonic()
                    elif self._page_hidden_at.get(websocket) is None:
                        self._page_hidden_at[websocket] = time.monotonic()
                    await self._settle_display_owner()

                elif message == "STOP_VIDEO":
                    beside = websocket in self.co_controllers.get(client_display_id or 'primary', ())
                    stop_entry = (self.display_clients.get(client_display_id)
                                  if client_display_id and not beside else None)
                    if stop_entry is not None and stop_entry.get('ws') is not websocket:
                        # A dying page's tab-hide STOP_VIDEO can arrive after the reloaded
                        # page already owns the display.
                        data_logger.debug(f"Ignoring STOP_VIDEO for '{client_display_id}' from a superseded connection.")
                        try:
                            await websocket.send_str("VIDEO_STOPPED")
                        except (ConnectionResetError, OSError, RuntimeError):
                            pass
                    elif stop_entry is not None:
                        self._cancel_deferred_rejoin(websocket)
                        # The controller hiding its tab must not stop an encoder shared
                        # viewers still consume; only its own socket pauses then.
                        remaining_viewers = (
                            self._active_primary_consumers(exclude=websocket)
                            if client_display_id == 'primary' else set()
                        )
                        if remaining_viewers:
                            data_logger.info(
                                f"STOP_VIDEO for 'primary' with {len(remaining_viewers)} shared "
                                "viewer(s) attached: pausing the controller, keeping the capture."
                            )
                            self.video_paused_clients.add(websocket)
                        else:
                            data_logger.info(f"Received STOP_VIDEO for '{client_display_id}'. Stopping stream.")
                            stop_entry['video_active'] = False
                            await self._stop_capture_for_display(client_display_id)
                        try:
                            await websocket.send_str("VIDEO_STOPPED")
                        except (ConnectionResetError, OSError, RuntimeError):
                            pass
                    else:
                        self._cancel_deferred_rejoin(websocket)
                        self.video_paused_clients.add(websocket)
                        data_logger.info(f"STOP_VIDEO from shared client ({remote_address}): pausing its video feed.")
                        await self._stop_primary_if_unconsumed(
                            "Last unpaused consumer of 'primary' hid its tab."
                        )
                        try:
                            await websocket.send_str("VIDEO_STOPPED")
                        except (ConnectionResetError, OSError, RuntimeError):
                            pass

                elif message.startswith("DECODE_PACE "):
                    # The rate this client's decoder keeps up with, 0 for any: the
                    # display it owns captures no faster. A viewer's is its own
                    # gate's to answer, since the capture is everyone's.
                    try:
                        pace = float(message.split(" ", 1)[1])
                    except ValueError:
                        continue
                    target_display_id = client_display_id or 'primary'
                    entry = self.display_clients.get(target_display_id)
                    if entry is None or entry.get('ws') is not websocket:
                        continue
                    if pace > 0:
                        pace = sanitize_client_setting("framerate", pace, self.cli_args, data_logger)
                    self._apply_decode_pace(target_display_id, entry, float(pace) if pace else None)

                elif message.startswith("LOST_FRAME "):
                    # The client's decoder dropped a frame it could not keep up with:
                    # the encoder predicts past it, so the client resumes on the next
                    # frame instead of waiting for a keyframe. One report per display
                    # per few milliseconds is all a burst of clients can add.
                    try:
                        lost_frame_id = int(message.split(" ", 1)[1])
                    except ValueError:
                        continue
                    target_display_id = client_display_id or 'primary'
                    if not self._repair_taken(websocket, target_display_id, "lost"):
                        continue
                    now = time.monotonic()
                    if now - self._last_lost_frame.get(target_display_id, 0.0) >= 0.005:
                        self._last_lost_frame[target_display_id] = now
                        self._schedule_invalidation(target_display_id, lost_frame_id)

                elif message == "REQUEST_KEYFRAME":
                    if not self._repair_taken(websocket, client_display_id, "keyframe"):
                        continue
                    target_display_id = client_display_id or 'primary'
                    instance = self.capture_instances.get(target_display_id)
                    module = instance.get('module') if instance else None
                    if module:
                        now = time.monotonic()
                        if now - self._last_keyframe_request.get(target_display_id, 0.0) >= 0.25:
                            self._last_keyframe_request[target_display_id] = now
                            # The log line is throttled harder than the request: a
                            # decode-resync loop would fill the journal at 4 lines/s.
                            if now - self._last_keyframe_log.get(target_display_id, 0.0) >= 5.0:
                                suppressed = self._keyframe_log_suppressed.get(target_display_id, 0)
                                suffix = f" (+{suppressed} further requests suppressed)" if suppressed else ""
                                self._keyframe_log_suppressed[target_display_id] = 0
                                self._last_keyframe_log[target_display_id] = now
                                data_logger.debug(f"Keyframe requested by {remote_address} for '{target_display_id}'.{suffix}")
                            else:
                                self._keyframe_log_suppressed[target_display_id] = \
                                    self._keyframe_log_suppressed.get(target_display_id, 0) + 1
                            # Non-blocking in pixelflux (atomic flag / channel send).
                            module.request_idr_frame()

                elif message == "START_AUDIO":
                    async def _handle_start_audio_request():
                        await self.client_settings_received.wait()
                        async with self._audio_lock:
                            data_logger.debug(
                                "Received START_AUDIO command from client for server-to-client audio."
                            )
                            if not settings.audio_enabled[0]:
                                data_logger.debug("START_AUDIO: Audio is disabled by server settings. Sending AUDIO_DISABLED.")
                                # Its own task: a departed requester must end it quietly.
                                try:
                                    await websocket.send_str("AUDIO_DISABLED")
                                except (ConnectionResetError, OSError, RuntimeError):
                                    pass
                                return
                            if PCMFLUX_AVAILABLE:
                                started = False
                                if not self.is_pcmflux_capturing:
                                    data_logger.debug("START_AUDIO: Starting pcmflux audio pipeline.")
                                    started = await self._start_pcmflux_pipeline()
                                else:
                                    started = True
                                    data_logger.debug("START_AUDIO: pcmflux audio pipeline already active.")
                                if started:
                                    # A page beside the primary's owner starts its own
                                    # audio; the owner's starts its own and the viewers'.
                                    beside = set(self.co_controllers.get('primary', ()))
                                    if websocket in beside:
                                        self._beside_audio[websocket] = True
                                        told = {websocket}
                                    else:
                                        self._session_audio = True
                                        told = self.clients - beside
                                    for ws in await _broadcast_to_clients(told, "AUDIO_STARTED", watched=True):
                                        self.clients.discard(ws)
                            else:
                                data_logger.warning("START_AUDIO: Cannot start server-to-client audio (pcmflux not available).")
                                try:
                                    await websocket.send_str("AUDIO_DISABLED")
                                except (ConnectionResetError, OSError, RuntimeError):
                                    pass
                    # A re-request supersedes the pending one; disconnect cancels it.
                    if start_audio_task_ws and not start_audio_task_ws.done():
                        start_audio_task_ws.cancel()
                    start_audio_task_ws = asyncio.create_task(_handle_start_audio_request())

                elif message == "STOP_AUDIO":
                    # Off the loop like START_AUDIO: a start the sound server is slow
                    # to answer holds the audio lock, and this socket's input with it.
                    # Taken in order behind that start, and left to finish on disconnect.
                    async def _handle_stop_audio_request():
                        async with self._audio_lock:
                            data_logger.debug("Received STOP_AUDIO")
                            beside = set(self.co_controllers.get('primary', ()))
                            if websocket in beside:
                                self._beside_audio[websocket] = False
                                told = {websocket}
                            else:
                                self._session_audio = False
                                told = self.clients - beside
                            if self.is_pcmflux_capturing and not self._audio_wanted():
                                await self._stop_pcmflux_pipeline()
                            for ws in await _broadcast_to_clients(told, "AUDIO_STOPPED", watched=True):
                                self.clients.discard(ws)
                    _spawn_background_task(_handle_stop_audio_request(), name="stop-audio")

                elif message.startswith("SET_NATIVE_CURSOR_RENDERING,"):
                    # Taken as it comes: before any capture it is only recorded, for the
                    # one the initial SETTINGS starts.
                    try:
                        new_capture_cursor_str = message.split(",")[1].strip().lower()
                        new_capture_cursor = new_capture_cursor_str in ("1", "true")
                        data_logger.info(f"Received SET_NATIVE_CURSOR_RENDERING: {new_capture_cursor}")
                        await self.set_native_cursor_rendering(new_capture_cursor)
                    except (IndexError, ValueError) as e:
                        data_logger.warning(f"Malformed SET_NATIVE_CURSOR_RENDERING message: {message}, error: {e}")

                else:
                    if message.startswith("js,"):
                        # Live store, not the connect-time snapshot: a revoked
                        # or re-slotted token lands on the next message.
                        perms = client_permissions.get(websocket) or {}
                        slot = perms.get("slot")
                        if self.is_secure_mode:
                            live = sessions.user_tokens.get(perms.get("token")) if perms.get("token") else None
                            slot = live.get("slot") if live else None
                        if gamepad_slot_denied(message, perms.get("role"), slot,
                                               self.is_secure_mode):
                            data_logger.warning(
                                f"DENIED gamepad input from {remote_address}: "
                                f"{message[:32]} does not match slot {slot}.")
                            continue

                    # maxsplit=1: a full split of an 8 MiB clipboard chunk stalls the loop.
                    if self.is_secure_mode and message.split(',', 1)[0] in SECURE_INPUT_PREFIXES:
                        if not self._holds_input_authority(websocket):
                            continue

                    if (message.startswith(("r,", "s,"))
                            and websocket in self.co_controllers.get(client_display_id, ())):
                        # The display's owner sizes it and sets its density.
                        continue

                    if self.input_handler and hasattr(
                        self.input_handler, "on_message"
                    ):
                        # conn_id keeps the clipboard debounce per connection, not per display.
                        await self.input_handler.on_message(message, client_display_id, conn_id=id(websocket))

                    if client_display_id == 'primary' and page_put_to_use(message):
                        # After the input, which lands on the layout its page shows.
                        if tab_id:
                            self._tab_used_at[tab_id] = time.monotonic()
                        if websocket in self.co_controllers.get('primary', ()):
                            await self._take_display_in_use(websocket)

    except (ConnectionResetError, OSError, RuntimeError) as e:
        data_logger.info(f"Client {raddr} disconnected: {e}")
    except Exception as e_main_loop:
        data_logger.error(
            f"Error in Data WS handler for {raddr}: {e_main_loop}", exc_info=True
        )
    finally:
        self.last_start_video_request_times.pop(websocket, None)
        for kind in ("keyframe", "lost"):
            self._repair_times.pop((websocket, kind), None)
        self.video_paused_clients.discard(websocket)
        self._stats_subscribers.discard(websocket)
        self._cancel_deferred_rejoin(websocket)
        departing_perms = client_permissions.pop(websocket, None) or {}
        self._audit_session_end(departing_perms)
        # Dropped first: the authority and consumer verdicts below must see
        # the remaining clients only.
        self.clients.discard(websocket)
        data_logger.debug(f"Cleaning up Data WS handler for {raddr} (Display ID: {client_display_id})...")
        await capture_demand.sync(self)
        # A tab that dies mid-press never sends 'js,d'; the button would stay
        # stuck on the virtual pad.
        if self.input_handler and hasattr(self.input_handler, "release_gamepads_for_conn"):
            try:
                await self.input_handler.release_gamepads_for_conn(id(websocket))
            except Exception as e:
                data_logger.warning(f"Gamepad release on disconnect failed: {e}")

        # The release rule is in the docstring: primary owner, or last input-capable client.
        _primary_entry = self.display_clients.get('primary')
        departing_input_authority = self._holds_input_authority(websocket, departing_perms) and (
            (_primary_entry is not None and _primary_entry.get('ws') is websocket)
            or not any(self._holds_input_authority(ws) for ws in self.clients)
        )

        # A cut (no close frame: an ingress retiring, the network) leaves the
        # page to reconnect in place, still holding what it held: its keys and
        # buttons stay down through the reconnect grace and are let go only if
        # it does not come back.
        close_code = getattr(websocket, "close_code", None)
        hold_input = (
            departing_input_authority
            and close_code == WSCloseCode.ABNORMAL_CLOSURE
            and any(info.get('ws') is websocket for info in self.display_clients.values())
        )
        if departing_input_authority and not hold_input:
            await self._release_held_input(raddr)

        # Now rather than at the next fan-out: an idle capture (JPEG, streaming
        # off) sends no chunk to prune a dead relay, which pins its buffers.
        for relay_group in self.video_relay_groups.values():
            stale_relay = relay_group.pop(websocket, None)
            if stale_relay is not None:
                stale_relay.stop()
        for joiners in self.co_controllers.values():
            joiners.pop(websocket, None)
        self._page_settings.pop(websocket, None)
        self._page_hidden_at.pop(websocket, None)
        self._page_shown_at.pop(websocket, None)
        stale = time.monotonic() - 3600
        for gone_tab in [t for t, at in self._tab_used_at.items() if at < stale]:
            del self._tab_used_at[gone_tab]
        had_own_audio = self._beside_audio.pop(websocket, False)
        if self.data_ws is websocket:
            self.data_ws = None
        # A departing non-capable client may let the rest enable RED; a page
        # beside the owner that kept the capture running for itself ends it.
        self.audio_redundancy_by_ws.pop(websocket, None)
        self._red_unsettled.discard(websocket)
        self._heard_at.pop(websocket, None)
        if self.is_pcmflux_capturing:
            async with self._audio_lock:
                if had_own_audio and not self._audio_wanted():
                    await self._stop_pcmflux_pipeline()
                elif self.clients:
                    # With nobody left the stream keeps its distance: a page
                    # back in place finds it unchanged, and the grace
                    # teardown stops the capture if none comes.
                    await self._regate_audio_redundancy()

        disconnected_display_id = None
        for disp_id, client_info in self.display_clients.items():
            if client_info.get('ws') is websocket:
                disconnected_display_id = disp_id
                break

        if disconnected_display_id:
            # Deferred: a reloading page takes the entry over with its capture warm;
            # tearing down here would serialize its startup behind this reconfigure
            # on the lock (seconds of black stream per reload).
            # The code says who ended it: 1000/1001 the page, 1006 a cut with no close
            # frame (a proxy, the network, or a ping of ours left unanswered), 4xxx this server.
            close_error = websocket.exception() if hasattr(websocket, "exception") else None
            data_logger.info(
                f"Client for '{disconnected_display_id}' disconnected (code {close_code}"
                f"{f': {close_error}' if close_error else ''}). Deferring display teardown by "
                f"{self.RECONNECT_GRACE_S:.0f}s for a possible reconnect."
            )

            async def _teardown_if_unclaimed(did=disconnected_display_id, dead_ws=websocket,
                                             held=hold_input):
                disconnect_ts = time.monotonic()
                deadline = disconnect_ts + 15.0
                while True:
                    await asyncio.sleep(self.RECONNECT_GRACE_S)
                    entry = self.display_clients.get(did)
                    if entry is None or entry.get('ws') is not dead_ws:
                        data_logger.info(f"Display '{did}' was claimed by a new connection during the grace period; teardown skipped.")
                        return
                    # A connection newer than the disconnect may still be mid-handshake
                    # (audio setup precedes its claim): held until the deadline.
                    latest_connect = max(self.last_connection_times.values(), default=0.0)
                    if latest_connect > disconnect_ts and time.monotonic() < deadline:
                        continue
                    if await self._promote_co_controller(did):
                        # Its SETTINGS claims the entry; waited for as a reconnect is.
                        disconnect_ts = time.monotonic()
                        deadline = disconnect_ts + 15.0
                        continue
                    break
                entry = self.display_clients.get(did)
                if entry is None or entry.get('ws') is not dead_ws:
                    data_logger.info(f"Display '{did}' was claimed by a new connection during the grace period; teardown skipped.")
                    return
                if held:
                    await self._release_held_input(raddr)
                del self.display_clients[did]
                await capture_demand.sync(self)
                data_logger.info(f"Client for '{did}' did not return within the grace period. Removing and triggering full display reconfiguration.")
                await self.reconfigure_displays()
                # A viewer-started capture has no owning display client, so the
                # reconfigure never stops it.
                await self._stop_primary_if_unconsumed(
                    "No unpaused consumer of 'primary' left after the grace period."
                )
                if not self.clients:
                    data_logger.info("Last client gone after the grace period. Tearing down singleton collectors and pipelines.")
                    await self._stop_stats_collectors()
                    self.capture_cursor = False
                    self._last_keyframe_request.clear()
                    # Self-acquires _reconfigure_lock; it must not be held here.
                    await self.shutdown_pipelines()

            _teardown_task = asyncio.create_task(_teardown_if_unclaimed())
            self._display_teardown_tasks.add(_teardown_task)
            _teardown_task.add_done_callback(self._display_teardown_tasks.discard)
        else:
            data_logger.debug(f"Unregistered client at {raddr} disconnected. No display reconfiguration needed.")
            # Nothing else stops the primary capture for a socket owning no display.
            await self._stop_primary_if_unconsumed(
                "Last unpaused consumer of 'primary' disconnected."
            )

        # Per-connection tasks only; canceling the singleton collectors here
        # would break the remaining clients.
        monitor_tasks = [
            start_audio_task_ws,
            initial_audio_task_ws,
        ]
        for _task_to_cancel in monitor_tasks:
            if not _task_to_cancel:
                continue
            _task_to_cancel.cancel()
            # Awaited unconditionally: a task that already failed on the dying
            # socket has its exception retrieved here, never propagated.
            try:
                await _task_to_cancel
            except asyncio.CancelledError:
                pass
            except Exception as e_conn_task:
                data_logger.debug(
                    f"Per-connection task for {raddr} ended with an error: {e_conn_task}"
                )

        # stop() joins the playback thread; offloaded so a slow PA disconnect
        # cannot block the loop.
        _mic_playback = locals().get("mic_playback")
        if _mic_playback is not None:
            try:
                await asyncio.to_thread(_mic_playback.stop)
                data_logger.debug(f"Stopped Rust mic playback for {raddr}.")
            except Exception as e_mic_pb:
                data_logger.error(f"Error stopping Rust mic playback for {raddr}: {e_mic_pb}")

        if mic_control is not None:
            if pa_module_index is not None and pa_module_owned:
                data_logger.info(
                    f"Unloading PulseAudio module {pa_module_index} for virtual mic (client: {raddr})."
                )
                await mic_control.unload_module(pa_module_index)
            await mic_control.aclose()
            data_logger.debug(f"Closed sound server control connection for {raddr}.")


        # A display-owning socket's last-client teardown ran in the grace task above.
        if disconnected_display_id is None and not self.clients:
             data_logger.info(f"Last client ({raddr}) gone; stopping the capture pipelines.")
             await self._stop_stats_collectors()
             self.capture_cursor = False
             self._last_keyframe_request.clear()
             # Self-acquires _reconfigure_lock; it must not be held here.
             await self.shutdown_pipelines()

        data_logger.debug(f"Data WS handler for {raddr} finished all cleanup.")
paramwebsocketweb.WebSocketResponse

The prepared WebSocket.

paramremote_addresstuple

(ip, port) of the peer.

paramtokenstr
= ''

Auth token (secure mode only).

paramquery_rolestr
= ''

Legacy-mode role request ("viewer" caps the role).

paramquery_slotOptional[str]
= None

Legacy-mode gamepad slot request ("2".."4").

Returns

None
func_run_detached_command(cmd_list, description) -> None

Run a command detached from the server process: its own session (start_new_session) survives our exit and our signals, with no shell in between.

Source Code
async def _run_detached_command(self, cmd_list: list[str], description: str) -> None:
    """Run a command detached from the server process: its own session
    (start_new_session) survives our exit and our signals, with no shell in
    between."""
    data_logger.info(f"Running detached command ({description}): {' '.join(cmd_list)}")
    try:
        await asyncio.create_subprocess_exec(
            *cmd_list,
            stdout=asyncio.subprocess.DEVNULL,
            stderr=asyncio.subprocess.DEVNULL,
            start_new_session=True,
        )
    except Exception as e:
        data_logger.error(f"Failed to run detached command ({description}): {e}")
paramcmd_listlist[str]
paramdescriptionstr

Returns

None
func_run_command(cmd, description, best_effort=False) -> bool

Run an external command (10s bound) and log its output/errors.

Source Code
async def _run_command(self, cmd: list[str], description: str, best_effort: bool = False) -> bool:
    """Run an external command (10s bound) and log its output/errors.

    Args:
        cmd: The argv list (no shell).
        description: Label used in log lines.
        best_effort: Logs a non-zero exit at DEBUG instead of ERROR — for
            delete-if-exists cleanups that fail only because the target is
            already gone.

    Returns:
        True on a zero exit within the timeout.
    """
    try:
        proc = await asyncio.create_subprocess_exec(
            *cmd,
            stdout=asyncio.subprocess.PIPE,
            stderr=asyncio.subprocess.PIPE
        )
        try:
            stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout=10.0)
        except asyncio.TimeoutError:
            try:
                proc.kill()
            except ProcessLookupError:
                pass
            await proc.wait()
            log = data_logger.debug if best_effort else data_logger.error
            log(f"Timed out ({description}) after 10s; killed.")
            return False
        if proc.returncode != 0:
            log = data_logger.debug if best_effort else data_logger.error
            log(
                f"Failed ({description}). RC: {proc.returncode}, "
                f"Stderr: {stderr.decode().strip()}"
            )
            return False
        return True
    except Exception as e:
        log = data_logger.debug if best_effort else data_logger.error
        log(f"Exception during '{description}': {e}", exc_info=not best_effort)
        return False
paramcmdlist[str]

The argv list (no shell).

paramdescriptionstr

Label used in log lines.

parambest_effortbool
= False

Logs a non-zero exit at DEBUG instead of ERROR — for delete-if-exists cleanups that fail only because the target is already gone.

Returns

bool

True on a zero exit within the timeout.

func_wayland_control_module() -> Optional[Any]

A pixelflux handle for compositor output management (any ScreenCapture reaches the shared Wayland backend); prefers the primary's persistent module so no extra instance exists in the common case.

Source Code
def _wayland_control_module(self) -> Optional[Any]:
    """A pixelflux handle for compositor output management (any ScreenCapture
    reaches the shared Wayland backend); prefers the primary's persistent
    module so no extra instance exists in the common case."""
    module = self._persistent_capture_modules.get('primary')
    if module is not None:
        return module
    if ScreenCapture is None:
        return None
    if self._wayland_ctl_module is None:
        self._wayland_ctl_module = ScreenCapture()
    return self._wayland_ctl_module

Returns

typing.Optional[typing.Any]
func_drop_wayland_secondary(display_id, reason) -> None

Refuse a secondary display that cannot stream: destroy its compositor output (Wayland; no-op on X11 where the control module is absent), stop its capture, unregister it, and kill its client with the reason.

Source Code
async def _drop_wayland_secondary(self, display_id: str, reason: str) -> None:
    """Refuse a secondary display that cannot stream: destroy its compositor
    output (Wayland; no-op on X11 where the control module is absent), stop
    its capture, unregister it, and kill its client with the reason."""
    module = self._wayland_control_module()
    if module is not None:
        try:
            await asyncio.to_thread(module.destroy_output, wayland_output_id(display_id))
        except Exception:
            pass
    await self._stop_capture_for_display(display_id)
    dropped_client = self.display_clients.pop(display_id, None)
    getattr(self, 'display_layouts', {}).pop(display_id, None)
    if self.input_handler:
        await self.input_handler.ensure_session_screens(
            [d for d in self.display_clients if d != 'primary'])
    dropped_ws = dropped_client.get('ws') if dropped_client else None
    data_logger.error(f"Secondary display '{display_id}' dropped on Wayland: {reason}")
    if dropped_ws is not None:
        try:
            await asyncio.wait_for(dropped_ws.send_str(f"KILL {reason}"), timeout=2.0)
            await asyncio.wait_for(
                dropped_ws.close(code=1008, message=b"Secondary display unrealizable"),
                timeout=2.0,
            )
        except asyncio.TimeoutError:
            _close_abandoned_ws(dropped_ws)
        except (ConnectionResetError, OSError, RuntimeError):
            pass
paramdisplay_idstr
paramreasonstr

Returns

None
func_realize_wayland_display_dpi(display_id, dpi) -> None

Run the Wayland scale ladder for one display and restart its capture when the scale left for the capture output changed.

A nested session scales its own screen and the capture stays 1.0; a plain session scales the capture output, re-read on the restart. A STOP_VIDEO'd display stays stopped: the next START_VIDEO applies the stored scale.

Source Code
async def _realize_wayland_display_dpi(self, display_id: str, dpi: Any) -> None:
    """Run the Wayland scale ladder for one display and restart its capture
    when the scale left for the capture output changed.

    A nested session scales its own screen and the capture stays 1.0; a
    plain session scales the capture output, re-read on the restart. A
    STOP_VIDEO'd display stays stopped: the next START_VIDEO applies the
    stored scale.

    Args:
        display_id: The display whose screen takes the DPI.
        dpi: The desktop DPI to realize.
    """
    entry = self.display_clients.get(display_id)
    size = ((entry or {}).get('width'), (entry or {}).get('height'))
    scale_val = await self.input_handler.realize_wayland_dpi(dpi, display_id, size)
    if entry is None or entry.get('scale') == scale_val:
        return
    entry['scale'] = scale_val
    if not entry.get('video_active', True):
        return
    layout = getattr(self, 'display_layouts', {}).get(display_id)
    if layout is None:
        return
    data_logger.info(f"Wayland: restarting capture at scale {scale_val} for {display_id}")
    await self._stop_capture_for_display(display_id)
    if display_id == 'primary':
        # The capture is a view over the primary's screen, and a capture
        # start sizes the view alone: the screen carries the scale itself.
        await self._size_wayland_screen(layout['w'], layout['h'])
    await self._start_capture_for_display(
        display_id=display_id,
        width=layout['w'], height=layout['h'],
        x_offset=layout['x'], y_offset=layout['y']
    )
    await self._start_backpressure_task_if_needed(display_id)
    await self._sync_wayland_realized_geometry(display_id)
paramdisplay_idstr

The display whose screen takes the DPI.

paramdpiAny

The desktop DPI to realize.

Returns

None
func_republish_second_screen() -> None

Re-read what backs a second display and re-announce the server settings, so every page shows the second-display offer the session allows now rather than the one it allowed when the page connected.

Source Code
async def _republish_second_screen(self) -> None:
    """Re-read what backs a second display and re-announce the server
    settings, so every page shows the second-display offer the session
    allows now rather than the one it allowed when the page connected."""
    await self._refresh_second_screen_capacity()
    await self._broadcast_live_server_settings('primary')

Returns

None
func_resync_wayland_session_scale(dpi) -> None

A session compositor was adopted after captures started: run the scale ladder again for every display, so the session takes the desktop DPI as its output scale and the capture output, which took it while the session was still starting, drops back to 1.0.

Serialized against reconfiguration: the adoption can land during the pass that started the captures it restarts.

Source Code
async def _resync_wayland_session_scale(self, dpi: Any) -> None:
    """A session compositor was adopted after captures started: run the
    scale ladder again for every display, so the session takes the desktop
    DPI as its output scale and the capture output, which took it while the
    session was still starting, drops back to 1.0.

    Serialized against reconfiguration: the adoption can land during the
    pass that started the captures it restarts.

    Args:
        dpi: The primary's DPI; each other display re-applies its own.
    """
    if not IS_WAYLAND or self.input_handler is None:
        return
    async with self._reconfigure_guard():
        for display_id in list(self.display_clients):
            await self._realize_wayland_display_dpi(
                display_id, dpi if display_id == 'primary' else self._display_dpi(display_id))
paramdpiAny

The primary's DPI; each other display re-applies its own.

Returns

None
func_display_dpi(display_id) -> Any

The DPI a display's page asked for, else the configured default.

Source Code
def _display_dpi(self, display_id: str) -> Any:
    """The DPI a display's page asked for, else the configured default."""
    client = self.display_clients.get(display_id) or {}
    return (client.get('scaling_dpi')
            or getattr(app_settings, "scaling_dpi", "96") or 96)
paramdisplay_idstr

Returns

typing.Any
func_size_wayland_screen(width, height, grow_only=False) -> None

Size the primary's screen (output 0) to its display rectangle.

The primary's capture binds to the view covering that screen, and a capture start sizes the view alone, which the screen must already hold: so the screen is grown ahead of the capture restart and fitted to the rectangle once the capture carries it -- an early shrink is refused by the compositor, which leaves no view hanging outside its screen.

Source Code
async def _size_wayland_screen(self, width: int, height: int,
                               grow_only: bool = False) -> None:
    """Size the primary's screen (output 0) to its display rectangle.

    The primary's capture binds to the view covering that screen, and a
    capture start sizes the view alone, which the screen must already hold:
    so the screen is grown ahead of the capture restart and fitted to the
    rectangle once the capture carries it -- an early shrink is refused by
    the compositor, which leaves no view hanging outside its screen.
    """
    module = self._wayland_control_module()
    if module is None or width <= 0 or height <= 0:
        return
    scale = float((self.display_clients.get('primary') or {}).get('scale', 1.0) or 1.0)
    try:
        if grow_only:
            outputs = {o[0]: o for o in await asyncio.to_thread(module.list_outputs)}
            screen = outputs.get(WAYLAND_SCREEN_OUTPUT_ID)
            if screen:
                width, height = max(width, screen[3]), max(height, screen[4])
        ok = await asyncio.to_thread(
            module.resize_output, WAYLAND_SCREEN_OUTPUT_ID, width, height, scale)
        if not ok:
            data_logger.warning(f"Wayland screen resize to {width}x{height} refused.")
    except Exception as e:
        data_logger.error(f"Wayland resize_output failed: {e}")
paramwidthint
paramheightint
paramgrow_onlybool
= False

Returns

None
func_scale_wayland_screen() -> None

Give the primary's screen (output 0) the primary's capture scale, at the size it has.

The primary's capture is a view over that screen, and a capture start sizes the view alone; a session that takes its scale from the host window's preferred fractional scale (a nested KWin) sees only the screen's. A no-op for the compositor at the scale it already carries.

Source Code
async def _scale_wayland_screen(self) -> None:
    """Give the primary's screen (output 0) the primary's capture scale, at
    the size it has.

    The primary's capture is a view over that screen, and a capture start
    sizes the view alone; a session that takes its scale from the host
    window's preferred fractional scale (a nested KWin) sees only the
    screen's. A no-op for the compositor at the scale it already carries.
    """
    module = self._wayland_control_module()
    if module is None:
        return
    try:
        outputs = {o[0]: o for o in await asyncio.to_thread(module.list_outputs)}
    except Exception as e:
        data_logger.debug(f"Wayland screen scale carry skipped: {e}")
        return
    screen = outputs.get(WAYLAND_SCREEN_OUTPUT_ID)
    if screen:
        await self._size_wayland_screen(screen[3], screen[4])

Returns

None
func_reanchor_wayland_primary(layouts, keep_ids) -> None

Collapse an unrealizable Wayland arrangement: primary back at the origin (layout + capture rebuild) -- the Wayland mirror of the X11 re-anchor when the extension does not fit the realized root.

Source Code
async def _reanchor_wayland_primary(self, layouts: dict, keep_ids: set[str]) -> None:
    """Collapse an unrealizable Wayland arrangement: primary back at the
    origin (layout + capture rebuild) -- the Wayland mirror of the X11
    re-anchor when the extension does not fit the realized root."""
    primary_layout = layouts.get('primary')
    if primary_layout:
        primary_layout['x'], primary_layout['y'] = 0, 0
    if 'primary' in keep_ids:
        keep_ids.discard('primary')
        await self._stop_capture_for_display('primary')
paramlayoutsdict
paramkeep_idsset[str]

Returns

None
func_apply_wayland_output_layout(layouts, keep_ids) -> None

Retire and move compositor screens for the computed union layout.

Every display is a screen of the session compositor's own: the primary shows output 0, the screen the session boots on, and each secondary owns an output created beside it, so the session has as many monitors as the client is shown displays and lays its windows and panels out per monitor. The Wayland counterpart of the X11 monitor/framebuffer apply, split around the primary's capture start: pixelflux refuses any placement that overlaps a live output, and the primary's screen takes its new size only once its capture has restarted, so a secondary moving into room a shrinking primary gives up can only be created after that. This pass therefore only removes, shrinks, moves, and grows: stale and moved secondaries are destroyed (a secondary reposition is a destroy + recreate; its capture dies with the output and the start loop rebuilds it), a secondary that keeps its origin but shrinks gives the room up in place (its capture start grows it to its whole rectangle afterwards), the primary (output 0) is moved to its layout offset ('left'/'up' place it off-origin; teardown re-anchors it at 0,0), and its screen is grown to hold the rectangle its capture is about to take. A primary move the compositor refuses is retried with every secondary output destroyed -- a rectangle the compositor would not shrink can still stand in the way, and the outputs come back in _create_wayland_outputs anyway -- and only then is the arrangement void: primary back at the origin, every secondary dropped. _create_wayland_outputs, run by the start loop right after the primary's capture start, creates the secondary outputs.

Source Code
async def _apply_wayland_output_layout(self, layouts: dict, keep_ids: set[str]) -> None:
    """Retire and move compositor screens for the computed union layout.

    Every display is a screen of the session compositor's own: the primary
    shows output 0, the screen the session boots on, and each secondary
    owns an output created beside it, so the session has as many monitors
    as the client is shown displays and lays its windows and panels out per
    monitor. The Wayland counterpart of the X11 monitor/framebuffer apply,
    split around the primary's capture start: pixelflux refuses any
    placement that overlaps a live output, and the primary's screen takes
    its new size only once its capture has restarted, so a secondary moving
    into room a shrinking primary gives up can only be created after that.
    This pass therefore only removes, shrinks, moves, and grows: stale and
    moved secondaries are destroyed (a secondary reposition is a destroy +
    recreate; its capture dies with the output and the start loop rebuilds
    it), a secondary that keeps its origin but shrinks gives the room up in
    place (its capture start grows it to its whole rectangle afterwards),
    the primary (output 0) is moved to its layout offset ('left'/'up' place
    it off-origin; teardown re-anchors it at 0,0), and its screen is grown
    to hold the rectangle its capture is about to take. A primary move the
    compositor refuses is retried with every secondary output destroyed --
    a rectangle the compositor would not shrink can still stand in the way,
    and the outputs come back in _create_wayland_outputs anyway -- and only
    then is the arrangement void: primary back at the origin, every
    secondary dropped. _create_wayland_outputs, run by the start loop right
    after the primary's capture start, creates the secondary outputs.

    Args:
        layouts: display_id to layout rect; mutated when a display has to
            be dropped (the primary move refused), killing its client like
            the X11 path.
        keep_ids: The keep-alive capture set; mutated alongside `layouts`.
    """
    module = self._wayland_control_module()
    if module is None:
        return
    try:
        outputs = {o[0]: o for o in await asyncio.to_thread(module.list_outputs)}
    except Exception as e:
        data_logger.error(f"Wayland list_outputs failed: {e}")
        outputs = {}
    wanted = {wayland_output_id(did): did for did in layouts if did != 'primary'}
    # The primary's screen and the view its capture binds to always persist.
    session_nodes = {WAYLAND_SCREEN_OUTPUT_ID, wayland_output_id('primary')}
    for oid in list(outputs):
        if oid not in session_nodes and oid not in wanted:
            data_logger.info(f"Destroying stale Wayland output {oid}.")
            try:
                await asyncio.to_thread(module.destroy_output, oid)
            except Exception as e:
                data_logger.error(f"Wayland destroy_output {oid} failed: {e}")
            outputs.pop(oid, None)

    async def recreate_later(oid: int, did: str, why: str) -> None:
        data_logger.info(f"Wayland output {oid} {why}; recreating it.")
        try:
            await asyncio.to_thread(module.destroy_output, oid)
        except Exception as e:
            data_logger.error(f"Wayland destroy_output {oid} failed: {e}")
        keep_ids.discard(did)
        await self._stop_capture_for_display(did)
        outputs.pop(oid, None)

    for oid, did in sorted(wanted.items()):
        layout = layouts[did]
        existing = outputs.get(oid)
        if existing is None:
            continue
        if (existing[1], existing[2]) != (layout['x'], layout['y']):
            await recreate_later(oid, did, f"moves to +{layout['x']}+{layout['y']}")
        elif not await wayland_shrink_output(module, existing, layout['w'], layout['h']):
            await recreate_later(oid, did, f"cannot shrink to {layout['w']}x{layout['h']}")
    primary_layout = layouts.get('primary')
    target = (primary_layout['x'], primary_layout['y']) if primary_layout else (0, 0)
    existing0 = outputs.get(WAYLAND_SCREEN_OUTPUT_ID)
    current = (existing0[1], existing0[2]) if existing0 is not None else (0, 0)
    if target != current:
        moved = await wayland_reposition_primary(module, target[0], target[1])
        if not moved and any(outputs.get(oid) is not None for oid in wanted):
            for oid, did in sorted(wanted.items()):
                if outputs.get(oid) is not None:
                    await recreate_later(oid, did, "blocks the primary's move")
            moved = await wayland_reposition_primary(module, target[0], target[1])
        if not moved:
            await wayland_reposition_primary(module, 0, 0)
            await self._reanchor_wayland_primary(layouts, keep_ids)
            for did in [d for d in list(layouts) if d != 'primary']:
                del layouts[did]
                keep_ids.discard(did)
                await self._drop_wayland_secondary(
                    did, "The compositor cannot move the primary output for this arrangement."
                )
    if primary_layout:
        await self._size_wayland_screen(primary_layout['w'], primary_layout['h'],
                                        grow_only=True)
    if self.input_handler:
        # The session keeps a screen per laid-out display: the ones whose
        # displays left are retired here -- their windows return to the
        # primary -- and _create_wayland_outputs grows each new display's
        # screen right before the output that adopts its host window.
        await self.input_handler.ensure_session_screens(
            [d for d in layouts if d != 'primary'])
        # Which of the session's own screens a capture drives has just changed.
        self.input_handler.resync_session_screens()
paramlayoutsdict

display_id to layout rect; mutated when a display has to be dropped (the primary move refused), killing its client like the X11 path.

paramkeep_idsset[str]

The keep-alive capture set; mutated alongside layouts.

Returns

None
func_create_wayland_outputs(layouts, keep_ids) -> None

Give every laid-out secondary its compositor output, at its layout rectangle.

The second half of the Wayland layout apply, run once the primary's capture start has sized its screen (see _apply_wayland_output_layout). A display the session compositor refuses a screen for, or whose output the capture compositor cannot create, is dropped like the X11 path's unrealizable display, with that reason, and when the arrangement was built around it the primary returns to the origin -- its capture follows the moved output live, so only the layout and the tracked capture offset change.

Source Code
async def _create_wayland_outputs(self, layouts: dict, keep_ids: set[str]) -> None:
    """Give every laid-out secondary its compositor output, at its layout rectangle.

    The second half of the Wayland layout apply, run once the primary's
    capture start has sized its screen (see _apply_wayland_output_layout).
    A display the session compositor refuses a screen for, or whose output
    the capture compositor cannot create, is dropped like the X11 path's
    unrealizable display, with that reason, and when the arrangement was
    built around it the primary returns to the origin -- its capture
    follows the moved output live, so only the layout and the tracked
    capture offset change.

    Args:
        layouts: display_id to layout rect; mutated when a display is
            dropped, killing its client.
        keep_ids: The keep-alive capture set; mutated alongside `layouts`.
    """
    module = self._wayland_control_module()
    if module is None:
        return
    wanted = {wayland_output_id(did): did for did in layouts if did != 'primary'}
    if not wanted:
        return
    for did in [d for d in layouts if d != 'primary' and wanted.get(wayland_output_id(d)) != d]:
        del layouts[did]
        keep_ids.discard(did)
        await self._drop_wayland_secondary(
            did, "This display's name collides with another display's output."
        )
    try:
        outputs = {o[0]: o for o in await asyncio.to_thread(module.list_outputs)}
    except Exception as e:
        data_logger.error(f"Wayland list_outputs failed: {e}")
        outputs = {}
    primary_layout = layouts.get('primary')
    created_any = False
    # A recreated output takes back the very window it lost -- parked
    # windows carry the output they came from -- and each fresh screen is
    # grown right before its own output, so the newest-parked fallback
    # claims the window just added, never a waiting leftover.
    for oid, did in sorted(wanted.items()):
        if did not in layouts or outputs.get(oid) is not None:
            continue
        layout = layouts[did]
        client = self.display_clients.get(did) or {}
        dpi = self._display_dpi(did)
        scale = float(dpi) / 96.0
        refusal = None
        if self.input_handler:
            if not await self.input_handler.ensure_session_screen(
                    did, size=(layout['w'], layout['h']), scale=scale):
                refusal = "The session compositor cannot add a screen for this display."
            else:
                # The screen exists now, so the display's own DPI can reach it;
                # what the session leaves is this output's capture scale.
                scale = await self.input_handler.realize_wayland_dpi(
                    dpi, did, (layout['w'], layout['h']))
                if client:
                    client['scale'] = scale
        if refusal is None:
            created = False
            try:
                created = bool(await asyncio.to_thread(
                    module.create_output, oid,
                    layout['w'], layout['h'], layout['x'], layout['y'], scale,
                ))
            except Exception as e:
                data_logger.error(f"Wayland create_output {oid} failed: {e}")
            if created:
                created_any = True
                continue
            refusal = "The compositor cannot create an output for this display."
        del layouts[did]
        keep_ids.discard(did)
        await self._drop_wayland_secondary(did, refusal)
        if primary_layout and (primary_layout['x'], primary_layout['y']) != (0, 0):
            if await wayland_reposition_primary(module, 0, 0):
                primary_layout['x'], primary_layout['y'] = 0, 0
                self._track_capture_settings('primary', capture_x=0, capture_y=0)
    if created_any and self.input_handler:
        self.input_handler.resync_session_screens()
paramlayoutsdict

display_id to layout rect; mutated when a display is dropped, killing its client.

paramkeep_idsset[str]

The keep-alive capture set; mutated alongside layouts.

Returns

None
func_stop_capture_for_display(display_id) -> None

Stop one display's capture, serialized against any concurrent start/stop.

Source Code
async def _stop_capture_for_display(self, display_id: str) -> None:
    """Stop one display's capture, serialized against any concurrent start/stop."""
    async with self._video_capture_lock:
        await self._stop_capture_for_display_impl(display_id)
paramdisplay_idstr

Returns

None
func_stop_capture_for_display_impl(display_id) -> None

Stop the capture, relays, and backpressure task for one display.

Callers hold _video_capture_lock. Guarantees exactly one PIPELINE_RESETTING per real capture stop: clients rebuild their video sinks/decoders only on that message, including when no backpressure task ran (viewer-only captures, stops before the task armed) — without it a resumed stream plays into the stale sink and freezes silently.

The stats watch goes first, because it reads the capture module from a worker thread and no read may be in flight when the module is torn down; its figures are best-effort, so failing to stop one is logged and the capture still goes.

Source Code
async def _stop_capture_for_display_impl(self, display_id: str) -> None:
    """Stop the capture, relays, and backpressure task for one display.

    Callers hold _video_capture_lock. Guarantees exactly one
    PIPELINE_RESETTING per real capture stop: clients rebuild their video
    sinks/decoders only on that message, including when no backpressure
    task ran (viewer-only captures, stops before the task armed) — without
    it a resumed stream plays into the stale sink and freezes silently.

    The stats watch goes first, because it reads the capture module from a
    worker thread and no read may be in flight when the module is torn
    down; its figures are best-effort, so failing to stop one is logged and
    the capture still goes.
    """
    data_logger.info(f"Stopping all streams for display '{display_id}'...")
    reset_sent = await self._ensure_backpressure_task_is_stopped(display_id)
    capture_info = self.capture_instances.pop(display_id, None)
    try:
        watch = self._stream_watches.get(display_id)
        if watch is not None:
            watch.stop()
    except Exception as e:
        data_logger.warning(f"Stream stats for '{display_id}' not stopped: {e}")
    if capture_info:
        capture_module = capture_info.get('module')
        if capture_module:
            await asyncio.to_thread(capture_module.stop_capture)
    self._close_video_relays(display_id)
    if capture_info and not reset_sent:
        await self._reset_frame_ids_and_notify(display_id)

    data_logger.debug(f"Successfully stopped all streams for display '{display_id}'.")
paramdisplay_idstr

Returns

None
func_reconfigure_guard()

Hold _reconfigure_lock for a direct critical section (a capture restart outside reconfigure_displays()) and, on release, run any reconfigure coalesced meanwhile.

reconfigure_displays()'s own re-run loop only consumes requests that arrive through it; a reconfigure coalesced during a direct hold would otherwise be stranded (orphaning a disconnected display's capture). The re-check runs on raising exits too, and outside the lock, since reconfigure_displays() only coalesces while the lock is held.

Source Code
@contextlib.asynccontextmanager
async def _reconfigure_guard(self):
    """Hold _reconfigure_lock for a direct critical section (a capture
    restart outside reconfigure_displays()) and, on release, run any
    reconfigure coalesced meanwhile.

    reconfigure_displays()'s own re-run loop only consumes requests that
    arrive through it; a reconfigure coalesced during a direct hold would
    otherwise be stranded (orphaning a disconnected display's capture).
    The re-check runs on raising exits too, and outside the lock, since
    reconfigure_displays() only coalesces while the lock is held.
    """
    try:
        async with self._reconfigure_lock:
            yield
    finally:
        if self._reconfigure_pending:
            await self.reconfigure_displays()

Returns

None
funcreconfigure_displays() -> None

Rebuild the virtual desktop layout for ALL connected clients.

Called on connect, disconnect, or settings change. Starts capture pipelines only for clients with video_active True. Self-serializing: a call while a pass is running coalesces (last-write-wins) into one follow-up pass instead of queueing, so state converges on the latest request without a reconfigure storm.

Source Code
async def reconfigure_displays(self) -> None:
    """Rebuild the virtual desktop layout for ALL connected clients.

    Called on connect, disconnect, or settings change. Starts capture
    pipelines only for clients with video_active True. Self-serializing:
    a call while a pass is running coalesces (last-write-wins) into one
    follow-up pass instead of queueing, so state converges on the latest
    request without a reconfigure storm.
    """
    if self._reconfigure_lock.locked():
        self._reconfigure_pending = True
        data_logger.debug("Reconfiguration already in progress; coalescing this request.")
        return
    while True:
        async with self._reconfigure_lock:
            self._reconfigure_pending = False
            self._is_reconfiguring = True
            data_logger.debug("Starting display reconfiguration...")
            try:
                await self._reconfigure_displays_locked()
            except Exception as e:
                data_logger.error(f"A critical error occurred during display reconfiguration: {e}", exc_info=True)
            finally:
                self._last_display_count = len(self.display_clients)
                self._is_reconfiguring = False
                data_logger.debug("Reconfiguration process complete (state unlocked).")
        if not self._reconfigure_pending:
            break

Returns

None
func_signal_all_displays_stopped() -> None

Send VIDEO_STOPPED to clients on a reconfiguration abort without clearing video_active: a transient abort (zero size, no screen_name, a failed newmode) must not permanently stop healthy displays, so the next successful reconfigure auto-restarts them. stop_signaled marks a client that now discards frames until that reconfigure sends it VIDEO_STARTED.

Source Code
async def _signal_all_displays_stopped(self) -> None:
    """Send VIDEO_STOPPED to clients on a reconfiguration abort without
    clearing video_active: a transient abort (zero size, no screen_name, a
    failed newmode) must not permanently stop healthy displays, so the
    next successful reconfigure auto-restarts them. `stop_signaled` marks
    a client that now discards frames until that reconfigure sends it
    VIDEO_STARTED."""
    # Snapshot: the sends await, and a concurrent connect/disconnect would
    # change the dict mid-iteration.
    for display_id, client_data in list(self.display_clients.items()):
        # The entry may have been removed during a prior iteration's await.
        if self.display_clients.get(display_id) is not client_data:
            continue
        ws = client_data.get('ws')
        if ws:
            try:
                # Bounded: runs under _reconfigure_lock; a frozen client is dropped,
                # not waited on.
                await asyncio.wait_for(ws.send_str("VIDEO_STOPPED"), timeout=2.0)
                client_data['stop_signaled'] = True
            except asyncio.TimeoutError:
                _close_abandoned_ws(ws)
            except (ConnectionResetError, OSError, RuntimeError):
                pass

Returns

None
func_signal_display_stopped(display_id) -> None

Tell one display's client the pipeline stopped, keeping video_active so a later successful reconfigure restarts it. The single-display form of _signal_all_displays_stopped, used when a primary capture did not come up (a failed start, or a host compositor that died) so the client sees a truthful verdict instead of a page frozen on "Waiting for stream".

Source Code
async def _signal_display_stopped(self, display_id: str) -> None:
    """Tell one display's client the pipeline stopped, keeping video_active so a
    later successful reconfigure restarts it. The single-display form of
    _signal_all_displays_stopped, used when a primary capture did not come up (a
    failed start, or a host compositor that died) so the client sees a truthful
    verdict instead of a page frozen on "Waiting for stream"."""
    client_data = self.display_clients.get(display_id)
    ws = client_data.get('ws') if client_data else None
    if not ws:
        return
    try:
        await asyncio.wait_for(ws.send_str("VIDEO_STOPPED"), timeout=2.0)
        client_data['stop_signaled'] = True
    except asyncio.TimeoutError:
        _close_abandoned_ws(ws)
    except (ConnectionResetError, OSError, RuntimeError):
        pass
paramdisplay_idstr

Returns

None
func_reconfigure_displays_locked() -> None

One reconfiguration pass. Must only be called by reconfigure_displays() with _reconfigure_lock held; early returns here abort just this pass.

The pass: optionally swap in a multi-monitor-capable WM (X11), compute the union layout from all display clients, decide per running capture whether it can follow the new layout live (structurally identical sessions retune in place; the rest are stopped and rebuilt), realize the layout (on X11 an output per display, or logical monitors over the one output where the server has none to plug in; on Wayland a compositor screen per display, the secondaries created only after the primary's capture start has sized its screen), clamp everything to what the server actually realized — dropping displays that cannot exist — then (re)start the active captures and broadcast the resulting resolutions and roster. A capture that did not come up yields a verdict rather than a page stuck on "Waiting for stream": a secondary is dropped (X11 parity), the primary is told the stream stopped with video_active kept so the next successful pass restarts it — which also surfaces a dead host compositor.

Source Code
async def _reconfigure_displays_locked(self) -> None:
    """One reconfiguration pass. Must only be called by reconfigure_displays()
    with _reconfigure_lock held; early returns here abort just this pass.

    The pass: optionally swap in a multi-monitor-capable WM (X11), compute
    the union layout from all display clients, decide per running capture
    whether it can follow the new layout live (structurally identical
    sessions retune in place; the rest are stopped and rebuilt), realize
    the layout (on X11 an output per display, or logical monitors over the one
    output where the server has none to plug in; on Wayland a
    compositor screen per display, the secondaries created only after the
    primary's capture start has sized its screen), clamp everything to what
    the server actually realized — dropping displays that cannot exist —
    then (re)start the active captures and broadcast the resulting
    resolutions and roster. A capture that did not come up yields a
    verdict rather than a page stuck on "Waiting for stream": a secondary
    is dropped (X11 parity), the primary is told the stream stopped with
    video_active kept so the next successful pass restarts it — which
    also surfaces a dead host compositor.
    """
    current_display_count = len(self.display_clients)
    await self._wm_swap.ensure_for(current_display_count, IS_WAYLAND)
    if not self.display_clients:
        for display_id in list(self.capture_instances.keys()):
            await self._stop_capture_for_display(display_id)
        data_logger.warning("No display clients connected. Video pipelines remain stopped.")
        if not IS_WAYLAND:
            await retire_displays()
        else:
            # The primary's screen persists; only the secondaries' are retired.
            await self._apply_wayland_output_layout({}, set())
        return
    data_logger.debug("Calculating new extended desktop layout from ALL clients...")
    layouts = {}
    total_width = 0
    total_height = 0
    primary_client = self.display_clients.get('primary')
    secondary_client = None
    secondary_id = None
    for display_id, client in self.display_clients.items():
        if display_id != 'primary':
            secondary_client = client
            secondary_id = display_id
            break
    if primary_client and not secondary_client:
        p_w, p_h = primary_client.get('width', 0), primary_client.get('height', 0)
        if p_w > 0 and p_h > 0:
            layouts['primary'] = {'x': 0, 'y': 0, 'w': p_w, 'h': p_h}
            total_width, total_height = p_w, p_h
    elif primary_client and secondary_client:
        p_w, p_h = primary_client.get('width', 0), primary_client.get('height', 0)
        s_w, s_h = secondary_client.get('width', 0), secondary_client.get('height', 0)
        position = secondary_client.get('position', 'right')
        if position not in ('right', 'left', 'up', 'down'):
            data_logger.warning(f"Invalid display position '{position}'; falling back to 'right'.")
            position = 'right'
        # Auto-resize feedback guard, shared with the WebRTC layout engine.
        p_w, p_h = clamp_primary_feedback(
            (p_w, p_h), getattr(self, 'display_layouts', None), position
        )
        if p_w > 0 and p_h > 0 and s_w > 0 and s_h > 0:
            computed, total_width, total_height = compute_dual_layout(
                (p_w, p_h), (s_w, s_h), position
            )
            layouts['primary'] = computed['primary']
            layouts[secondary_id] = computed['secondary']
    if total_width == 0 or total_height == 0:
        data_logger.error("Calculated total display size is zero. Aborting reconfiguration.")
        await self._signal_all_displays_stopped()
        return
    # The single-display total still needs the xrandr framebuffer alignment.
    total_width = (total_width + 7) & ~7
    self.display_layouts = layouts
    data_logger.info(f"Layout calculated: Total Size={total_width}x{total_height}. Layouts: {layouts}")

    keep_ids = set()
    async with self._video_capture_lock:
        for did in list(self.capture_instances.keys()):
            inst = self.capture_instances[did]
            module = inst.get('module')
            client = self.display_clients.get(did)
            wanted = did in layouts and client is not None and client.get('video_active', False)
            alive = False
            if wanted and module is not None:
                try:
                    alive = bool(module.is_capturing)
                except Exception:
                    alive = False
            structural_ok = False
            if alive:
                old_cs, layout = inst.get('settings'), layouts[did]
                try:
                    fresh = self._get_capture_settings(did, layout['w'], layout['h'], layout['x'], layout['y'])
                    structural_ok = old_cs is not None and all(
                        getattr(fresh, k) == getattr(old_cs, k)
                        for k in STRUCTURAL_CAPTURE_SETTINGS
                    )
                    if structural_ok:
                        inst['settings'] = fresh
                except Exception:
                    structural_ok = False
            if structural_ok:
                keep_ids.add(did)
            else:
                await self._stop_capture_for_display_impl(did)

    if not IS_WAYLAND:
        curr_res, _, available_resolutions, _, screen_name = await get_new_res("1x1")
        total_mode_str = f"{total_width}x{total_height}"
        # Displays that are outputs of their own each take their own mode;
        # only the logical-monitor layout needs one covering the framebuffer.
        pluggable = await has_pluggable_outputs()
        if not screen_name:
            # A server with no connected RandR output (a GPU without a
            # display engine, a driver told to use none) has no mode to
            # set: its framebuffer is sized outright where the server
            # allows, and the layouts are clamped to what it has
            # otherwise. The monitors below are still what gives the
            # toolkits their screens, and carry no output there.
            data_logger.info(
                "No connected RandR output on this X server; the desktop is sized as a bare "
                "framebuffer, and its displays are monitors carrying no output.")
        # A real display's refresh caps what a vsynced application shows,
        # so its modes never run slower than the fastest stream.
        stream_fps = max(float((self.display_clients.get(did) or {}).get('framerate')
                               or self.app.framerate) for did in layouts)
        if screen_name and not pluggable and total_mode_str not in available_resolutions:
            data_logger.debug(f"Mode {total_mode_str} not found. Creating it.")
            # Native first: a mode made by per-invocation xrandr dies with its
            # connection on some servers (Xvfb).
            if not await ensure_mode(total_mode_str, stream_fps):
                try:
                    _, modeline_params = await generate_xrandr_gtf_modeline(total_mode_str)
                    await self._run_command(["xrandr", "--newmode", total_mode_str] + modeline_params.split(), "create new mode")
                    await self._run_command(["xrandr", "--addmode", screen_name, total_mode_str], "add new mode")
                except Exception as e:
                    data_logger.error(f"FATAL: Could not create extended mode {total_mode_str}: {e}. Aborting.")
                    await self._signal_all_displays_stopped()
                    return
        if keep_ids:
            # Grow first, shrink after: a region outside the root fails the grab and
            # kills the capture thread. The grow runs whenever the union exceeds the
            # current root, or the re-target pins clamped (its grab never fails).
            try:
                cur_w, cur_h = (int(v) for v in curr_res.lower().replace(" ", "").split("x"))
            except (ValueError, AttributeError):
                cur_w, cur_h = total_width, total_height
            union_w, union_h = max(cur_w, total_width), max(cur_h, total_height)
            grew = True
            if (union_w, union_h) != (cur_w, cur_h):
                grew = await grow_framebuffer(union_w, union_h)
            if not grew:
                # At the framebuffer's bound a layout past the current root would
                # pin clamped at re-target; those captures restart after the mode-set.
                for did in sorted(list(keep_ids)):
                    layout = layouts[did]
                    if (layout['x'] + layout['w'] > cur_w
                            or layout['y'] + layout['h'] > cur_h):
                        data_logger.warning(
                            f"Framebuffer grow refused (still {cur_w}x{cur_h}); "
                            f"capture '{did}' restarts after the mode-set.")
                        keep_ids.discard(did)
                        await self._stop_capture_for_display(did)
            for did in sorted(keep_ids):
                layout = layouts[did]
                module = self.capture_instances[did]['module']
                try:
                    module.update_capture_region(layout['x'], layout['y'], layout['w'], layout['h'])
                    data_logger.info(f"Re-targeted live capture '{did}' to {layout} (no restart).")
                except Exception as e:
                    data_logger.warning(f"Live re-target failed for '{did}' ({e}); restarting it.")
                    keep_ids.discard(did)
                    await self._stop_capture_for_display(did)
        if pluggable and await apply_output_layout(layouts, total_width, total_height, stream_fps):
            data_logger.debug("Displays laid out as outputs of their own.")
        else:
            data_logger.debug("Swapping logical monitors to the new layout...")
            # Monitors go in before the framebuffer change (a lone display's
            # after it, below), at their final rectangles and under a server
            # grab: window managers re-tile on every root ConfigureNotify and
            # must never see a monitor-less or partial set.
            snapshot = await window_snapshot()
            # One display is shown whole by the output: Qt announces a monitor's
            # new geometry only where the monitor is exactly its CRTC.
            output_size = ((layouts['primary']['w'], layouts['primary']['h'])
                           if len(layouts) == 1 and 'primary' in layouts else None)
            # A mode change is the dominant cost of a reconfigure (CRTC reprogram,
            # every client repaints), so a same-size reload skips it. A live
            # re-target that grew the framebuffer above still shrinks here.
            curr_norm = (curr_res or "").lower().replace(" ", "")
            # A lone display's monitor is its CRTC, and a desktop that reads
            # the CRTC when told the monitors changed (MATE's panel) lays out
            # for whatever mode it finds: one re-reading between a swap and
            # the mode set finds the new monitor over the old mode, and the
            # mode set then changes no monitor, so it is never told again.
            # Its mode goes in first and the monitor after, so every change
            # it can see is one whose mode is final. Swapped first, the panel
            # stayed laid out for the root the session started on, its
            # bottom half off screen.
            resizes = output_size is not None and curr_norm != total_mode_str
            if not resizes:
                await replace_selkies_monitors(layouts, screen_name=screen_name)
            if curr_norm == total_mode_str:
                data_logger.debug(f"Screen already at {total_mode_str}; skipping redundant framebuffer/mode-set.")
            elif not await resize_display(total_mode_str, stream_fps, output_size):
                # Some servers refuse runtime modes but honor a plain framebuffer
                # grow (RRSetScreenSize); captures and pointer warps address the root.
                if await grow_framebuffer(total_width, total_height):
                    data_logger.info(f"Mode-set for {total_mode_str} failed; grew the framebuffer instead.")
                else:
                    data_logger.error(f"Applying mode {total_mode_str} failed; clamping to the realized size below.")
            if resizes:
                await replace_selkies_monitors(layouts, screen_name=screen_name)
            await follow_display_moves(snapshot, layouts)
        # The X server is the authority: a driver can refuse the size and leave
        # the root as it was, and a region outside the root grabs garbage.
        realized_w, realized_h = await read_realized_root((total_width, total_height))
        if (realized_w, realized_h) != (total_width, total_height):
            data_logger.warning(
                f"Realized screen size {realized_w}x{realized_h} differs from target "
                f"{total_width}x{total_height}; clamping display layouts to it."
            )
            offsets = {d: (l['x'], l['y']) for d, l in layouts.items()}
            fit = reconcile_realized_layout(layouts, realized_w, realized_h)
            if fit.reanchored:
                data_logger.error(
                    f"Primary at +{offsets['primary'][0]}+{offsets['primary'][1]} does not fit "
                    f"the realized {realized_w}x{realized_h} root; re-anchored at the origin."
                )
                if 'primary' in keep_ids:
                    # Re-targeted to the void offset above; rebuilt at the re-anchored region.
                    keep_ids.discard('primary')
                    await self._stop_capture_for_display('primary')
            for did in fit.dropped:
                data_logger.error(
                    f"Display '{did}' at +{offsets[did][0]}+{offsets[did][1]} does not fit the "
                    f"realized {realized_w}x{realized_h} root; dropping it. The X server "
                    "must allow a framebuffer covering all displays (e.g. a larger Xvfb "
                    "-screen) for extended layouts."
                )
                keep_ids.discard(did)
                await self._stop_capture_for_display(did)
                dropped_client = self.display_clients.get(did)
                dropped_ws = dropped_client.get('ws') if dropped_client else None
                if dropped_ws is not None:
                    try:
                        await asyncio.wait_for(
                            dropped_ws.send_str(
                                "KILL The X server cannot extend the desktop to fit this display."
                            ),
                            timeout=2.0,
                        )
                        await asyncio.wait_for(
                            dropped_ws.close(code=1008, message=b"Extended layout unrealizable"),
                            timeout=2.0,
                        )
                    except asyncio.TimeoutError:
                        _close_abandoned_ws(dropped_ws)
                    except (ConnectionResetError, OSError, RuntimeError):
                        pass
            for did in fit.clamped:
                layout = layouts[did]
                data_logger.warning(
                    f"Display '{did}': layout clamped to {layout['w']}x{layout['h']} "
                    "inside the realized root."
                )
                client_data = self.display_clients.get(did)
                if client_data:
                    client_data['width'], client_data['height'] = layout['w'], layout['h']
                if did == 'primary':
                    self.app.display_width = layout['w']
                    self.app.display_height = layout['h']
                # A kept capture was re-targeted to the pre-clamp region.
                inst = self.capture_instances.get(did)
                if did in keep_ids and inst and inst.get('module'):
                    try:
                        inst['module'].update_capture_region(
                            layout['x'], layout['y'], layout['w'], layout['h']
                        )
                        inst['settings'] = self._get_capture_settings(
                            did, layout['w'], layout['h'], layout['x'], layout['y']
                        )
                    except Exception as e:
                        data_logger.warning(
                            f"Re-target to clamped region failed for '{did}' ({e}); restarting it."
                        )
                        keep_ids.discard(did)
                        await self._stop_capture_for_display(did)
            # One atomic re-swap (RRSetMonitor cannot redefine a name in place);
            # a root that merely came back larger needs none, since every swap re-tiles.
            if (fit.dropped or fit.reanchored or fit.clamped) and not (
                    pluggable
                    and await apply_output_layout(layouts, realized_w, realized_h, stream_fps)):
                await replace_selkies_monitors(layouts, screen_name=screen_name)
    else:
        await self._apply_wayland_output_layout(layouts, keep_ids)
    data_logger.debug("Starting separate capture instances for each ACTIVE display region...")
    # The primary first: on Wayland its capture start sizes its screen.
    for display_id in sorted(layouts, key=lambda did: did != 'primary'):
        if display_id not in layouts:
            continue
        layout = layouts[display_id]
        client_data = self.display_clients.get(display_id)
        if client_data and client_data.get('video_active', False):
            try:
                if display_id in keep_ids:
                    # Kept live: the current rates/tunables are pushed so settings drift rides.
                    inst = self.capture_instances[display_id]
                    module, fresh = inst['module'], inst['settings']
                    if IS_WAYLAND:
                        # A start on the live capture reconfigures it in place,
                        # serialized against a concurrent teardown.
                        async with self._video_capture_lock:
                            await asyncio.to_thread(module.start_capture, inst['callback'], fresh)
                    else:
                        module.update_framerate(float(fresh.target_fps))
                        module.update_video_bitrate(int(fresh.video_bitrate_kbps))
                        module.update_tunables(fresh)
                    data_logger.info(f"Capture '{display_id}' followed the new layout live (no restart).")
                else:
                    data_logger.debug(f"Client '{display_id}' is active. Starting its capture.")
                    await self._start_capture_for_display(
                        display_id=display_id,
                        width=layout['w'], height=layout['h'],
                        x_offset=layout['x'], y_offset=layout['y']
                    )
                await self._start_backpressure_task_if_needed(display_id)
                # A client told VIDEO_STOPPED by a transient abort still discards frames.
                if client_data.get('stop_signaled'):
                    ws = client_data.get('ws')
                    if ws:
                        try:
                            await asyncio.wait_for(ws.send_str("VIDEO_STARTED"), timeout=2.0)
                        except asyncio.TimeoutError:
                            _close_abandoned_ws(ws)
                        except (ConnectionResetError, OSError, RuntimeError):
                            pass
                    client_data['stop_signaled'] = False
            except Exception as e:
                data_logger.error(
                    f"Failed to start capture for display '{display_id}' during reconfiguration. "
                    f"This display will not stream. Error: {e}", exc_info=False
                )
        else:
            data_logger.debug(f"Client '{display_id}' is connected but not active. Skipping video start.")
        if IS_WAYLAND and display_id == 'primary':
            # The primary's capture carries its rectangle now, so its screen
            # comes down to it before a secondary is created in the room it
            # gave up; the session compositor then arranges its own screens
            # by its own rule until it is told this one.
            primary_layout = layouts.get('primary')
            if primary_layout:
                await self._size_wayland_screen(primary_layout['w'], primary_layout['h'])
            await self._create_wayland_outputs(layouts, keep_ids)
            if self.input_handler:
                self.input_handler.schedule_session_screen_layout(layouts)
    for display_id in list(layouts.keys()):
        client_data = self.display_clients.get(display_id)
        if not (client_data and client_data.get('video_active', False)):
            continue
        if IS_WAYLAND:
            # Barrier: the read answers only after the queued start finished,
            # so is_capturing is authoritative below.
            await self._sync_wayland_realized_geometry(display_id, broadcast=False)
        inst = self.capture_instances.get(display_id)
        module = inst.get('module') if inst else None
        capturing = False
        if module is not None:
            try:
                capturing = bool(module.is_capturing)
            except Exception:
                capturing = False
        if not capturing:
            last_error = self._wayland_capture_last_error(module, display_id)
            if display_id == 'primary':
                data_logger.error(
                    "Primary capture is not live after reconfiguration"
                    + (f": {last_error}." if last_error else "."))
                await self._signal_display_stopped(display_id)
            else:
                await self._drop_wayland_secondary(
                    display_id,
                    last_error or "The capture pipeline could not start for this "
                    "display (encoder session or GPU resources exhausted).",
                )
    if IS_WAYLAND and layouts.get('primary'):
        # Last, because the primary's view is as big as what it captures and
        # the capture is live at its new size only past the barrier above.
        await self._size_wayland_screen(layouts['primary']['w'], layouts['primary']['h'])
    await self.broadcast_stream_resolution()
    await self.broadcast_display_config()
    data_logger.debug("Display reconfiguration finished successfully.")

Returns

None
func_ensure_viewer_capture() -> bool

Start the primary capture for a shared/player viewer when no display- owning client is connected (fresh server, or the controller left): the desktop exists regardless, so a lone viewer must not wait on a controller ("Waiting for stream..." forever). Captures the CURRENT desktop geometry — viewers never resize anything; the next controller's settings re-layout as usual.

Source Code
async def _ensure_viewer_capture(self) -> bool:
    """Start the primary capture for a shared/player viewer when no display-
    owning client is connected (fresh server, or the controller left): the
    desktop exists regardless, so a lone viewer must not wait on a controller
    ("Waiting for stream..." forever). Captures the CURRENT desktop geometry —
    viewers never resize anything; the next controller's settings re-layout
    as usual.

    Returns:
        True when the primary capture is running afterwards.
    """
    if 'primary' in self.capture_instances:
        return True
    layout = getattr(self, 'display_layouts', {}).get('primary')
    if layout:
        w, h, x, y = layout['w'], layout['h'], layout['x'], layout['y']
    else:
        w, h = self.app.display_width, self.app.display_height
        x = y = 0
        if not IS_WAYLAND:
            # On X11 the desktop size is external truth; on Wayland the start sizes the output.
            try:
                curr_res = (await get_new_res(f"{w}x{h}"))[0]
                w, h = map(int, curr_res.split('x'))
            except Exception as e:
                data_logger.warning(f"Viewer capture: desktop geometry query failed ({e}); using {w}x{h}.")
        if hasattr(self, 'display_layouts'):
            self.display_layouts['primary'] = {'w': w, 'h': h, 'x': x, 'y': y}
    started = False
    try:
        started = bool(await self._start_capture_for_display(
            'primary', width=w, height=h, x_offset=x, y_offset=y))
    except Exception as e:
        data_logger.error(f"Viewer-driven capture start failed: {e}", exc_info=True)
    if started:
        await self._start_backpressure_task_if_needed('primary')
        # Built from session defaults: a client keyed to the departed
        # controller's encoder would otherwise drop every chunk.
        await self._broadcast_live_server_settings('primary')
        # The audio fan-out is shared, so a lone viewer must not wait for a controller
        # either; off the receive loop for the reason _apply_initial_audio_policy gives.
        if PCMFLUX_AVAILABLE and settings.audio_enabled[0] and not self.is_pcmflux_capturing:
            _spawn_background_task(self._start_audio_for_viewers(), name="viewer-audio-start")
    return started

Returns

bool

True when the primary capture is running afterwards.

func_start_audio_for_viewers() -> None

Start the audio capture a viewer-driven primary capture is owed, unless every client left while the sound server was being asked.

Source Code
async def _start_audio_for_viewers(self) -> None:
    """Start the audio capture a viewer-driven primary capture is owed, unless
    every client left while the sound server was being asked."""
    try:
        async with self._audio_lock:
            if self.clients:
                await self._start_pcmflux_pipeline()
    except Exception as e:
        data_logger.error(f"Viewer-driven audio start failed: {e}", exc_info=True)

Returns

None
func_warn_if_unframed(display_id, module) -> None

Say so when the capture started for display_id is still the live one and has delivered nothing since.

Source Code
def _warn_if_unframed(self, display_id: str, module: Any) -> None:
    """Say so when the capture started for `display_id` is still the live one
    and has delivered nothing since."""
    inst = self.capture_instances.get(display_id)
    if inst is not None and inst.get('module') is module and display_id not in self._framed_displays:
        data_logger.warning(no_first_frame(display_id, str(getattr(inst.get('settings'), 'codec', '?'))))
paramdisplay_idstr
parammoduleAny

Returns

None
func_start_capture_for_display(display_id, width, height, x_offset, y_offset) -> bool

Start (or confirm) one display's capture, serialized under _video_capture_lock.

Also refreshes second-screen capacity afterwards: a capture start is what establishes the host session in host-capture mode, so the host's output count can first become known — or change — here.

Source Code
async def _start_capture_for_display(self, display_id: str, width: int, height: int,
                                     x_offset: int, y_offset: int) -> bool:
    """Start (or confirm) one display's capture, serialized under _video_capture_lock.

    Also refreshes second-screen capacity afterwards: a capture start is
    what establishes the host session in host-capture mode, so the host's
    output count can first become known — or change — here.

    Returns:
        True when a live capture exists for the display afterwards.
    """
    async with self._video_capture_lock:
        started = await self._start_capture_for_display_impl(display_id, width, height, x_offset, y_offset)
    if started and await self._refresh_second_screen_capacity():
        await self._broadcast_live_server_settings(display_id)
    return started
paramdisplay_idstr
paramwidthint
paramheightint
paramx_offsetint
paramy_offsetint

Returns

bool

True when a live capture exists for the display afterwards.

func_start_capture_for_display_impl(display_id, width, height, x_offset, y_offset) -> bool

Start a capture instance for one display region.

Callers hold _video_capture_lock. Builds the CaptureSettings, installs the zero-copy frame callback (which fans chunks out to the per-client relays via call_soon_threadsafe) and the pixelflux cursor handler, and starts the persistent ScreenCapture module (reused across restarts so the encoder backend stays warm). A genuinely capturing existing instance is left alone (an IDR is nudged for rejoining clients); a stale one is rebuilt.

Source Code
async def _start_capture_for_display_impl(self, display_id: str, width: int, height: int,
                                          x_offset: int, y_offset: int) -> bool:
    """Start a capture instance for one display region.

    Callers hold _video_capture_lock. Builds the CaptureSettings, installs
    the zero-copy frame callback (which fans chunks out to the per-client
    relays via call_soon_threadsafe) and the pixelflux cursor handler, and
    starts the persistent ScreenCapture module (reused across restarts so
    the encoder backend stays warm). A genuinely capturing existing
    instance is left alone (an IDR is nudged for rejoining clients); a
    stale one is rebuilt.

    Returns:
        True on success; False when the start failed (reported so callers
        do not ack a false VIDEO_STARTED).

    Raises:
        SelkiesAppError: When the pixelflux library is unavailable.
    """
    # Before CaptureSettings() dies on a bare TypeError far from the import warning.
    if not X11_CAPTURE_AVAILABLE:
        raise SelkiesAppError(
            "Cannot start capture: the pixelflux library failed to import "
            "(see the startup warning for the underlying error)."
        )
    existing = self.capture_instances.get(display_id)
    if existing is not None:
        module = existing.get('module')
        alive = True
        if module is not None:
            try:
                alive = bool(module.is_capturing)
            except Exception:
                # Unknown state: assumed alive rather than churn a healthy stream.
                alive = True
        if alive:
            if module is not None:
                try:
                    module.request_idr_frame()
                except Exception:
                    pass
            data_logger.debug(f"Capture instance for '{display_id}' already running; requested IDR.")
            return True
        data_logger.warning(f"Capture instance for '{display_id}' is stale (not capturing); rebuilding.")
        await self._stop_capture_for_display_impl(display_id)

    data_logger.debug(
        f"Preparing to start capture for display='{display_id}': "
        f"Res={width}x{height}, Offset={x_offset}x{y_offset}"
    )
    if IS_WAYLAND and display_id == 'primary':
        await self._scale_wayland_screen()

    try:
        settings = self._get_capture_settings(display_id, width, height, x_offset, y_offset)

        # Fallback for relays created before capture_instances registers this display.
        relay_budget = max(
            VIDEO_RELAY_BUDGET_MIN_BYTES,
            int(int(getattr(settings, 'video_bitrate_kbps', 0) or 0)
                * 125 * VIDEO_RELAY_BUDGET_SECONDS),
        )

        def queue_data_for_display(frame):
            """pixelflux frame callback, on its native thread.

            Wraps the frame zero-copy and hands the fan-out to the event
            loop. The frame owns its native buffer (every pixelflux mode
            emits its wire header natively, JPEG's 0x03 included) and is
            kept as `owner` behind the memoryview because aiohttp may
            retain a view past send_bytes; every relay backlog shares the
            one item, and the buffer frees when the last holder releases
            it. An oversized chunk is an upstream bug and is refused, as
            emitting it would trip proxy/WS-stack frame limits.
            """
            if frame is None:
                return
            self._framed_displays.add(display_id)
            try:
                if not len(frame):
                    return
                if len(frame) > WS_MESSAGE_SIZE_HARD_CAP:
                    data_logger.error(
                        f"Refusing to relay a {len(frame)}-byte video chunk "
                        f"(hard cap {WS_MESSAGE_SIZE_HARD_CAP} bytes); chunk dropped.")
                    return

                item = {'data': memoryview(frame), 'owner': frame,
                        # Only the low 16 bits go on the wire and come back in
                        # ACKs; masked here so RTT lookups match past frame 65535.
                        'frame_id': frame.frame_id & 0xFFFF}

                def do_fanout():
                    """Offer the chunk to each target socket's relay, on the loop."""
                    group = self.video_relay_groups.get(display_id)
                    # No group means the capture is stopping; the buffer frees with the frame.
                    if group is None:
                        return
                    owner = self.display_clients.get(display_id)
                    if owner is not None:
                        produced = time.monotonic()
                        if produced - owner.get('produced_at', 0.0) > STILL_SCREEN_GAP_SECONDS:
                            owner['resumed_at'] = produced
                        owner['produced_at'] = produced
                    pc_ws = None
                    if display_id == 'primary':
                        secondary_ws = {
                            ci.get('ws')
                            for did, ci in self.display_clients.items()
                            if did != 'primary' and ci.get('ws')
                        }
                        targets = (self.clients - secondary_ws
                                   - self.video_paused_clients)
                        keep = set(targets)
                        ps = self.display_clients.get('primary')
                        pc_ws = ps.get('ws') if ps else None
                        if (pc_ws is not None and pc_ws in targets
                                and not ps.get('backpressure_enabled', True)):
                            # ACK backpressure throttles the controller only; its relay
                            # stays warm but gated, resuming where the lift says.
                            targets.discard(pc_ws)
                            relay = group.get(pc_ws)
                            if relay is not None:
                                relay.flush_for_gate(ps.get('stall_gated_at') is None, item)
                    else:
                        ci = self.display_clients.get(display_id)
                        ws = ci.get('ws') if ci else None
                        keep = {ws} if ws is not None else set()
                        if ws is not None and ci.get('backpressure_enabled', True):
                            targets = {ws}
                        else:
                            targets = set()
                            relay = group.get(ws) if ws is not None else None
                            if relay is not None:
                                relay.flush_for_gate(ci.get('stall_gated_at') is None, item)
                    # A socket gone for good (disconnect, pause, demotion to
                    # secondary) takes its relay with it; gated sockets stay in keep.
                    if len(group) > len(keep):
                        for ws in [w for w in group if w not in keep]:
                            group.pop(ws).stop()
                    need_sync = False
                    for ws in targets:
                        relay = group.get(ws)
                        if relay is None:
                            relay = _VideoRelay(
                                self, display_id, ws,
                                self._video_relay_budget(display_id, relay_budget))
                            group[ws] = relay
                            relay.start()
                        # A page that does not own the display asks for the shared key
                        # frame at most once a second, as its own requests do.
                        if relay.offer(item) and self._repair_taken(ws, display_id, "keyframe"):
                            need_sync = True
                    if need_sync:
                        self._schedule_idr_for_display(display_id)

                self.capture_loop.call_soon_threadsafe(do_fanout)

            except Exception as e:
                data_logger.error(f"Error in capture callback for {display_id}: {e}", exc_info=False)

        def pixelflux_cursor_handler(msg_type, data_bytes, hot_x, hot_y):
            # A call already in flight when shutdown cleared `app`.
            app = self.app
            if app is None:
                return
            try:
                # An auto cursor_size is None; the formatter needs a fallback
                # dimension, the same 24 the WebRTC handler uses.
                size = int(self.cursor_size or 0)
                payload = format_pixelflux_cursor(
                    msg_type, data_bytes, hot_x, hot_y, size if size > 0 else 24)
                if payload is not None:
                    app.send_ws_cursor_data(payload)
            except Exception as e:
                data_logger.error(f"Error handling pixelflux cursor: {e}")

        self.video_relay_groups[display_id] = {}
        data_logger.debug(
            f"Video relays for '{display_id}': skip-ahead budget "
            f"{relay_budget} bytes/client.")


        capture_module = self._persistent_capture_modules.get(display_id)
        if capture_module is None:
            capture_module = ScreenCapture()
            self._persistent_capture_modules[display_id] = capture_module
        else:
            data_logger.debug(
                f"Reusing ScreenCapture instance for '{display_id}' (backend kept warm)."
            )

        # pixelflux is the cursor source on both backends.
        capture_module.set_cursor_callback(pixelflux_cursor_handler)

        self._framed_displays.discard(display_id)
        starting = {'module': capture_module, 'settings': settings}
        self._starting_captures[display_id] = starting
        try:
            await self.capture_loop.run_in_executor(
                None,
                capture_module.start_capture,
                queue_data_for_display,
                settings
            )
        finally:
            self._starting_captures.pop(display_id, None)

        self.capture_instances[display_id] = {
            'module': capture_module,
            'callback': queue_data_for_display,
            'settings': starting['settings'],
        }
        self.capture_loop.call_later(
            FIRST_FRAME_WAIT_S, self._warn_if_unframed, display_id, capture_module)
        # The X11 start already raised on failure; a Wayland start only
        # enqueues a command, so its outcome is read back here.
        live, last_error = await self._wayland_start_verdict(capture_module, display_id)
        if not live:
            data_logger.error(
                f"Capture did not start for '{display_id}': "
                f"{last_error or 'the compositor reported no live pipeline'}.")
            self._close_video_relays(display_id)
            self.capture_instances.pop(display_id, None)
            return False
        if last_error:
            data_logger.warning(
                f"Capture started for '{display_id}' with a caveat: {last_error}")
        data_logger.info(
            f"Capture started for '{display_id}': {width}x{height} at +{x_offset}+{y_offset}.")
        self._schedule_active_codec_settle(display_id)
        self._watch_stream(display_id, capture_module)
        return True

    except Exception as e:
        data_logger.error(f"Failed to start capture for '{display_id}': {e}", exc_info=True)
        self._close_video_relays(display_id)
        return False
paramdisplay_idstr
paramwidthint
paramheightint
paramx_offsetint
paramy_offsetint

Returns

bool

True on success; False when the start failed (reported so callers

func_schedule_active_codec_settle(display_id, attempt=0) -> None

Read back, once frames flow, the codec a fresh capture streams.

The selection ladder demotes a codec no encoder could serve to H.264 with a log line; the clients must then hear the encoder they really receive, so the display's setting follows and the settings are re-announced.

Source Code
def _schedule_active_codec_settle(self, display_id: str, attempt: int = 0) -> None:
    """Read back, once frames flow, the codec a fresh capture streams.

    The selection ladder demotes a codec no encoder could serve to H.264 with
    a log line; the clients must then hear the encoder they really receive,
    so the display's setting follows and the settings are re-announced.
    """
    loop = asyncio.get_running_loop()
    loop.call_later(1.0, lambda: asyncio.ensure_future(self._settle_active_codec(display_id, attempt)))
paramdisplay_idstr
paramattemptint
= 0

Returns

None
func_settle_active_codec(display_id, attempt) -> None
Source Code
async def _settle_active_codec(self, display_id: str, attempt: int) -> None:
    module = (self.capture_instances.get(display_id) or {}).get('module')
    if module is None or not hasattr(module, "active_codec"):
        return
    try:
        active = await asyncio.to_thread(module.active_codec)
    except Exception as e:
        data_logger.debug(f"Active codec of '{display_id}' unknown: {e}")
        return
    if active is None:
        if attempt < 5:
            self._schedule_active_codec_settle(display_id, attempt + 1)
        return
    entry = self.display_clients.get(display_id)
    encoder = (entry or {}).get('encoder') or self.app.encoder
    if codec_for_encoder(encoder) == active:
        return
    demoted = encoder_for_codec(active)
    data_logger.warning(
        f"Display '{display_id}' streams {CODEC_LABELS.get(active, active)} as '{demoted}': "
        f"no encoder served '{encoder}'.")
    if entry is not None:
        entry['encoder'] = demoted
    if display_id == 'primary':
        self.app.encoder = demoted
    await self._broadcast_live_server_settings(display_id)
paramdisplay_idstr
paramattemptint

Returns

None
func_wayland_start_verdict(module, display_id) -> Tuple[bool, Optional[str]]

Read the truthful outcome of a Wayland capture start.

The compositor processes StartCapture asynchronously, so a fresh start's real result is not known when start_capture returns. get_realized_geometry is answered only once the queued start ran, so it doubles as a barrier that makes is_capturing and capture_state authoritative; capture_state then reports whether a live pipeline exists and, if it degraded or failed, why.

Non-Wayland returns (True, None) -- the X11 path already surfaces its failures by raising.

Source Code
async def _wayland_start_verdict(self, module: Any, display_id: str) -> Tuple[bool, Optional[str]]:
    """Read the truthful outcome of a Wayland capture start.

    The compositor processes StartCapture asynchronously, so a fresh start's
    real result is not known when ``start_capture`` returns. ``get_realized_geometry``
    is answered only once the queued start ran, so it doubles as a barrier that
    makes ``is_capturing`` and ``capture_state`` authoritative; ``capture_state``
    then reports whether a live pipeline exists and, if it degraded or failed, why.

    Non-Wayland returns ``(True, None)`` -- the X11 path already surfaces its
    failures by raising.

    Returns:
        ``(is_live, last_error)``: whether a live capture exists, and the reason a
        start failed or a caveat a degraded-but-live start came up with.
    """
    if not IS_WAYLAND:
        return True, None
    try:
        await asyncio.to_thread(module.get_realized_geometry, wayland_output_id(display_id))
    except Exception as e:
        data_logger.warning(f"Wayland start barrier failed for '{display_id}': {e}")
    last_error = None
    try:
        _state, last_error = await asyncio.to_thread(
            module.capture_state, wayland_output_id(display_id))
    except Exception:
        last_error = None
    live = False
    try:
        live = bool(module.is_capturing)
    except Exception:
        live = False
    return live, last_error
parammoduleAny
paramdisplay_idstr

Returns

bool

(is_live, last_error): whether a live capture exists, and the reason a

func_wayland_capture_last_error(module, display_id) -> Optional[str]

The reason a Wayland capture failed, or a caveat a live one came up with, or None.

Read straight from capture_state (no command round-trip); the caller is responsible for any ordering barrier.

Source Code
def _wayland_capture_last_error(self, module: Any, display_id: str) -> Optional[str]:
    """The reason a Wayland capture failed, or a caveat a live one came up with, or None.

    Read straight from ``capture_state`` (no command round-trip); the caller is
    responsible for any ordering barrier.
    """
    if module is None:
        return None
    try:
        _state, last_error = module.capture_state(wayland_output_id(display_id))
        return last_error
    except Exception:
        return None
parammoduleAny
paramdisplay_idstr

Returns

typing.Optional[str]
func_get_capture_settings(display_id, width, height, x, y) -> Any

Build a pixelflux CaptureSettings for a specific display region.

Per-display stored tunables win; each falls back to its session default, which is what a viewer-driven primary capture (no display-owning client) runs on entirely.

Source Code
def _get_capture_settings(self, display_id: str, width: int, height: int,
                          x: int, y: int) -> Any:
    """Build a pixelflux CaptureSettings for a specific display region.

    Per-display stored tunables win; each falls back to its session
    default, which is what a viewer-driven primary capture (no
    display-owning client) runs on entirely.

    Returns:
        A populated pixelflux CaptureSettings (typed Any because pixelflux
        is an optional import).

    Raises:
        SelkiesAppError: For an unknown non-primary display_id.
    """
    display_state = self.display_clients.get(display_id)
    if not display_state:
        if display_id == 'primary':
            display_state = {}
        else:
            raise SelkiesAppError(f"Cannot get capture settings for unknown display_id '{display_id}'")

    cs = CaptureSettings()
    cs.capture_width = width
    cs.capture_height = height
    cs.capture_x = x
    cs.capture_y = y
    encoder = display_state.get('encoder', self.app.encoder)
    cs.codec = codec_for_encoder(encoder)
    if cs.codec == "jpeg":
        cs.jpeg_quality = display_state.get('jpeg_quality', self._initial_jpeg_quality)
        cs.paint_over_jpeg_quality = display_state.get('paint_over_jpeg_quality', self._initial_paint_over_jpeg_quality)
    ih = getattr(self, 'input_handler', None)
    apply_common_capture_settings(
        cs, self.cli_args,
        is_wayland=IS_WAYLAND,
        display_name=display_id,
        scale=display_state.get('scale', 1.0),
        framerate=self._capture_fps(display_state),
        encoder=encoder,
        use_cpu=display_state.get(
            'use_cpu', effective_use_cpu(encoder, None, self._initial_use_cpu)),
        cbr=display_state.get('rate_control_mode', self.rc_mode.value) == 'cbr',
        bitrate_kbps=self._video_bitrate_kbps(display_state),
        crf=display_state.get('video_crf', self._initial_video_crf),
        paintover_crf=display_state.get('video_paintover_crf', self._initial_video_paintover_crf),
        paintover_burst=display_state.get('video_paintover_burst_frames', self._initial_video_paintover_burst_frames),
        fullcolor=display_state.get('video_fullcolor', self._initial_video_fullcolor),
        ten_bit=display_state.get('video_10bit', self._initial_video_10bit),
        streaming=display_state.get('video_streaming_mode', self._initial_video_streaming_mode),
        use_paint_over_quality=display_state.get('use_paint_over_quality', self._initial_use_paint_over_quality),
        capture_cursor=self.capture_cursor,
        cursor_size_cap_hint=int(getattr(ih, 'cursor_size_cap', 0) or 0),
        cpu_encode_threading=display_state.get(
            'cpu_encode_threading', self._cpu_encode_threading_for(encoder, None)),
    )
    return cs
paramdisplay_idstr
paramwidthint
paramheightint
paramxint
paramyint

Returns

typing.Any

A populated pixelflux CaptureSettings (typed Any because pixelflux

funcrun() -> None

Start the server's components and block until shutdown is signaled.

Spawns the input handler's connect/clipboard/cursor tasks, realizes the configured scale on Wayland, then waits on shutdown_event; cleanup always runs via shutdown() on the way out.

Source Code
async def run(self) -> None:
    """Start the server's components and block until shutdown is signaled.

    Spawns the input handler's connect/clipboard/cursor tasks, realizes the
    configured scale on Wayland, then waits on shutdown_event; cleanup
    always runs via shutdown() on the way out.
    """
    self._shutdown_called = False
    self.initialize()

    logger.debug("Starting DataStreamingServer...")

    self._tasks_to_run = []
    if hasattr(self.input_handler, "connect"):
        self._tasks_to_run.append(
            asyncio.create_task(self.input_handler.connect(), name="InputConnect")
        )
    if hasattr(self.input_handler, "start_clipboard"):
        self.input_handler.clipboard_monitor_task = asyncio.create_task(
            self.input_handler.start_clipboard(), name="ClipboardMon"
        )
        self._tasks_to_run.append(self.input_handler.clipboard_monitor_task)
    if hasattr(self.input_handler, "probe_apps_runner"):
        self._tasks_to_run.append(
            asyncio.create_task(self.input_handler.probe_apps_runner(), name="AppsProbe")
        )

    # 96 is unity, where a compositor starts; it gets its cursor size via
    # CaptureSettings instead. X11's density was settled before the listener opened.
    startup_dpi = int(float(getattr(settings, "scaling_dpi", "96") or 96))
    if IS_WAYLAND and startup_dpi != 96 and self.input_handler is not None:
        await self.input_handler.realize_wayland_dpi(startup_dpi)

    try:
        await self.shutdown_event.wait()
    except asyncio.CancelledError:
        logger.debug("Main application task was canceled.")
    except Exception as e_main:
        logger.critical(f"Critical error in main execution: {e_main}", exc_info=True)
    finally:
        logger.debug("Main loop ending or interrupted. Performing cleanup...")
        await self.shutdown()

Returns

None
funcshutdown() -> None

Shut down all components and release resources; idempotent.

Closes every client socket first (code 4000) so handlers exit and no stray capture keeps encoding for a page that can no longer receive, then stops pipelines while display state still exists to address their tasks, stops every capture that survived that pass and withdraws its cursor callback, cancels auxiliary tasks, stops the input handler, drops the persistent capture modules, and unregisters the registry-global Prometheus gauges (re-entering this mode after a switch would otherwise fail on duplicated timeseries). The close carries no KILL verb: KILL is the client's terminal verdict (it clears the reconnect timer and drops its onclose handler), whereas a shutdown is usually a mode switch every page must recover from — a bare close leaves the client's reconnect/mode-flip loop armed, which converges the tabs.

Source Code
async def shutdown(self) -> None:
    """Shut down all components and release resources; idempotent.

    Closes every client socket first (code 4000) so handlers exit and no
    stray capture keeps encoding for a page that can no longer receive,
    then stops pipelines while display state still exists to address
    their tasks, stops every capture that survived that pass and withdraws
    its cursor callback, cancels auxiliary tasks, stops the input handler,
    drops the persistent capture modules, and unregisters the
    registry-global Prometheus gauges
    (re-entering this mode after a switch would otherwise fail on
    duplicated timeseries). The close carries no KILL verb: KILL is the
    client's terminal verdict (it clears the reconnect timer and drops its
    onclose handler), whereas a shutdown is usually a mode switch every
    page must recover from — a bare close leaves the client's
    reconnect/mode-flip loop armed, which converges the tabs.
    """
    if self._shutdown_called:
        logger.debug("Shutdown already called, skipping")
        return
    self._shutdown_called = True
    logger.debug("DataStreamingServer shutdown initiated...")
    capture_demand.detach(self)

    sockets_to_close = set(self.clients)
    for info in self.display_clients.values():
        ws = info.get('ws')
        if ws is not None:
            sockets_to_close.add(ws)

    async def _close_one(sock):
        try:
            await asyncio.wait_for(sock.close(code=4000, message=b"server shutting down"), timeout=1.0)
        except Exception:
            _close_abandoned_ws(sock)

    if sockets_to_close:
        await asyncio.gather(
            *[_close_one(s) for s in sockets_to_close], return_exceptions=True
        )

    try:
        await self.shutdown_pipelines()
    except Exception as e:
        logger.error(f"Pipeline shutdown during server shutdown failed: {e}")

    self.clients.clear()
    self.video_paused_clients.clear()
    self._report_client_presence()
    self.display_clients.clear()

    # Unconditional, and only now: the reconfigure pass stops captures in its
    # no-clients branch alone, which the reconnect grace holds shut until long
    # after this returns.
    for display_id in list(self.capture_instances.keys()):
        try:
            await self._stop_capture_for_display(display_id)
        except Exception as e:
            logger.error(f"Capture for '{display_id}' failed to stop during shutdown: {e}")
    self.capture_instances.clear()
    for module in self._persistent_capture_modules.values():
        release_pixelflux_cursor_callback(module)

    all_tasks_for_cleanup = [
        t for t in self._tasks_to_run
        if t and not t.done()
    ]

    for task in all_tasks_for_cleanup:
        logger.debug(f"Canceling task: {task.get_name()}")
        task.cancel()

    if all_tasks_for_cleanup:
        await asyncio.gather(*all_tasks_for_cleanup, return_exceptions=True)
        logger.debug("Auxiliary tasks cancellation complete.")

    if self.input_handler:
        logger.debug("Stopping InputHandler components...")
        if hasattr(self.input_handler, "stop_clipboard"):
            self.input_handler.stop_clipboard()
        if hasattr(self.input_handler, "disconnect") and inspect.iscoroutinefunction(
            self.input_handler.disconnect
        ):
            await self.input_handler.disconnect()

    self._persistent_capture_modules.clear()

    if self.metrics:
        try:
            await asyncio.to_thread(self.metrics.unregister)
        except Exception as e:
            logger.exception(f"Error unregistering metrics: {e}")
        self.metrics = None

    self.app = None
    self.input_handler = None
    logger.info("DataStreamingServer shutdown complete.")

Returns

None
funcstart() -> None
Source Code
async def start(self) -> None:
    self.shutdown_event.clear()
    await self.run()

Returns

None
funcstop() -> None
Source Code
async def stop(self) -> None:
    self.shutdown_event.set()

Returns

None
funcregister_routes(api_prefix, main_router) -> None

Register the data WebSocket and token endpoints on the shared router.

Both live under /api so ONE nginx location /api (with the WebSocket upgrade) fronts every dynamic path — control endpoints, this data socket, and the WebRTC signaling socket alike; everything the browser needs is proxied through /api.

Source Code
def register_routes(self, api_prefix: str, main_router: web.UrlDispatcher) -> None:
    """Register the data WebSocket and token endpoints on the shared router.

    Both live under /api so ONE nginx `location /api` (with the WebSocket
    upgrade) fronts every dynamic path — control endpoints, this data
    socket, and the WebRTC signaling socket alike; everything the browser
    needs is proxied through /api.
    """
    main_router.add_get(f'{api_prefix}/api/websockets{{slash:/?}}', self.data_ws_handler)
    main_router.add_post(f'{api_prefix}/api/tokens', self.handle_tokens)
paramapi_prefixstr
parammain_routerweb.UrlDispatcher

Returns

None
funchandle_tokens(request) -> web.StreamResponse

Accept a full replacement of the session's token/permission table.

Provisioning is transport-independent: sessions.user_tokens/sessions.active_mk_token govern authority for both the websockets and WebRTC gates, so tokens are accepted in any active mode (unlike the data WS endpoint, which is mode-gated). Secure mode is read from settings.master_token, not self.is_secure_mode, which is only set once the websockets service's initialize() runs (never in WebRTC mode). Opens the config gate on first provision and reconciles live clients against the new table.

Source Code
async def handle_tokens(self, request: web.Request) -> web.StreamResponse:
    """Accept a full replacement of the session's token/permission table.

    Provisioning is transport-independent: sessions.user_tokens/sessions.active_mk_token
    govern authority for both the websockets and WebRTC gates, so tokens
    are accepted in any active mode (unlike the data WS endpoint, which is
    mode-gated). Secure mode is read from settings.master_token, not
    self.is_secure_mode, which is only set once the websockets service's
    initialize() runs (never in WebRTC mode). Opens the config gate on
    first provision and reconciles live clients against the new table.
    """
    if not settings.master_token:
        return web.json_response({"error": "Server not in secure mode"}, status=404)

    try:
        new_token_data = await request.json()
        # The whole payload is validated before global auth state changes.
        error = token_table_error(new_token_data)
    except ValueError as e:
        error = str(e)
    if error:
        # The detail names the caller's own payload, but it reaches an unauthenticated
        # endpoint, so it stays in the log.
        logger.warning(f"Rejected a token table update: {error}")
        return web.Response(status=400, text="Bad Request")

    self.provision_tokens(new_token_data)
    return web.Response(status=200, text="OK")
paramrequestweb.Request

Returns

aiohttp.web.aiohttp.web.StreamResponse
funcprovision_tokens(new_token_data) -> None

Replace the token table with new_token_data, as /api/tokens and the tokens file do: the first table opens the config gate, and every one reconciles live clients against it. Only the JSON true elects an entry's mk_control, as only "controller" names a controller: a string such as "false" is no grant.

Source Code
def provision_tokens(self, new_token_data: dict) -> None:
    """Replace the token table with `new_token_data`, as `/api/tokens` and the
    tokens file do: the first table opens the config gate, and every one
    reconciles live clients against it. Only the JSON `true` elects an entry's
    `mk_control`, as only "controller" names a controller: a string such as
    "false" is no grant.

    Args:
        new_token_data: A table `token_table_error` accepts.
    """
    new_mk_owner = None
    for tkn, perms in new_token_data.items():
        if "slot" in perms:
            perms["slot"] = sessions.stored_slot(perms["slot"])
        if perms.get("mk_control") is True and new_mk_owner is None:
            new_mk_owner = tkn
    roleless = sum(perms.get("role") not in ("controller", "viewer") for perms in new_token_data.values())
    if roleless:
        logger.warning(f"{roleless} token entries name no role 'controller' or 'viewer'; they connect as viewers.")
    sessions.user_tokens = new_token_data
    sessions.active_mk_token = new_mk_owner
    logger.info(f"Updated user tokens. Now tracking {len(sessions.user_tokens)} tokens.")
    if not self.config_gate.is_set():
        self.config_gate.set()
        logger.info("Configuration gate is now open. WebSocket server will accept connections.")
    _spawn_background_task(reconcile_clients())
paramnew_token_datadict

A table token_table_error accepts.

Returns

None
funcwatch_tokens_file() -> None

Provision the token table from tokens_file, at start and on every change.

The file holds the body /api/tokens takes and is provisioned the same way, so a restart needs no POST. It is polled rather than watched, so a rename over it or a Kubernetes secret update is seen too. A POST still replaces the table until the file next changes, and a file that cannot be used leaves the table as it was.

Source Code
async def watch_tokens_file(self) -> None:
    """Provision the token table from `tokens_file`, at start and on every change.

    The file holds the body `/api/tokens` takes and is provisioned the same
    way, so a restart needs no POST. It is polled rather than watched, so a
    rename over it or a Kubernetes secret update is seen too. A POST still
    replaces the table until the file next changes, and a file that cannot
    be used leaves the table as it was.
    """
    path = settings.tokens_file
    if not settings.master_token:
        logger.warning("tokens_file is ignored: it needs secure mode, which a master token turns on.")
        return
    seen: Any = None
    while True:
        try:
            info = await asyncio.to_thread(os.stat, path)
        except OSError as exc:
            if seen != "missing":
                logger.warning(f"The tokens file {path!r} cannot be read yet: {exc}")
                seen = "missing"
        else:
            # The change time moves on a write and on a chmod or chown, which can make a
            # refused file usable.
            current = (info.st_ino, info.st_ctime_ns, info.st_size)
            if current != seen:
                seen = current
                table = await asyncio.to_thread(read_tokens_file, path)
                if table is not None:
                    self.provision_tokens(table)
        await asyncio.sleep(TOKENS_FILE_POLL_S)

Returns

None
funcdata_ws_handler(request) -> web.StreamResponse

aiohttp entry point: upgrade to a WebSocket and hand off to ws_handler.

Refuses when the websockets transport is not the active mode. A view-only basic-auth credential caps the role at viewer no matter what the query string asks for (legacy, non-secure mode); secure mode leaves the ceiling unset and lets the token govern. In secure mode an upgrade presents its token (handshake_session_token). A plain GET is the client's reconnect probe, past the auth middleware on a token of its own: it is answered 204, that the transport is up, rather than with an error status every browser logs as a failed load.

Source Code
async def data_ws_handler(self, request: web.Request) -> web.StreamResponse:
    """aiohttp entry point: upgrade to a WebSocket and hand off to ws_handler.

    Refuses when the websockets transport is not the active mode. A
    view-only basic-auth credential caps the role at viewer no matter what
    the query string asks for (legacy, non-secure mode); secure mode leaves
    the ceiling unset and lets the token govern. In secure mode an upgrade
    presents its token (``handshake_session_token``). A plain GET is the
    client's reconnect probe, past the auth middleware on a token of its
    own: it is answered 204, that the transport is up, rather than with an
    error status every browser logs as a failed load.
    """
    if self.supervisor.current_mode != self.mode:
        return web.Response(status=409, text="WebSocket mode is inactive")
    if request.headers.get("Upgrade", "").lower() != "websocket":
        return web.Response(status=204)

    token = ""
    if self.cli_args.master_token and request.headers.get("Upgrade", "").lower() == "websocket":
        token = handshake_session_token(request) or ""
        if not token:
            return web.Response(status=401, text="Token missing in secure mode")

    # compress=False: the frames are already H.264/JPEG/Opus. heartbeat:
    # protocol pings reap a silently dead peer, as the signaling sockets' probes
    # do. autoping=False: the loop answers PING and feeds PONG to the uplink gauge.
    ws = web.WebSocketResponse(compress=False, max_msg_size=WS_MAX_MESSAGE_BYTES, heartbeat=30, autoping=False,
                               protocols=(SESSION_TOKEN_PROTOCOL,))
    await ws.prepare(request)

    peername = request.transport.get_extra_info('peername')
    remote_address = peername[:2] if peername else (request.remote, 0)
    query_role = request.query.get('role', '')
    query_slot = request.query.get('slot')
    if request.get("auth_role_ceiling") == "viewer":
        query_role = "viewer"
        query_slot = None
    try:
        await self.ws_handler(ws, remote_address, token, query_role=query_role, query_slot=query_slot)
    finally:
        self._report_client_presence()
    return ws
paramrequestweb.Request

Returns

aiohttp.web.aiohttp.web.StreamResponse
funcuplink_session_conns() -> list[tuple[Any, Optional[str], Optional[str]]]

(websocket, session token, peer ip) per connected data socket, for the supervisor's upload uplink gauge.

Source Code
def uplink_session_conns(self) -> list[tuple[Any, Optional[str], Optional[str]]]:
    """``(websocket, session token, peer ip)`` per connected data socket,
    for the supervisor's upload uplink gauge."""
    conns = []
    for ws in list(self.clients):
        perms = client_permissions.get(ws) or {}
        addr = perms.get("remote_address")
        conns.append((ws, perms.get("token"), addr[0] if addr else None))
    return conns

Returns

list[tuple[typing.Any, typing.Optional[str], typing.Optional[str]]]