Raxol.Terminal.Driver.BackgroundQuery (Raxol Terminal v2.6.1)

Copy Markdown View Source

OSC 11 terminal background-color detection + DECRQM 2026 probe.

Emits an OSC 11 query (ESC ] 11 ; ? BEL) and a DECRQM query for mode 2026 (CSI ? 2026 $ p, synchronized output), followed by a primary Device Attributes probe (CSI c) as the sentinel. Every terminal answers DA, so a DA reply that arrives without a wanted reply means the terminal does not support that query and callers fall back conservative (silence is the failure mode, F0 §2).

Replies arrive asynchronously on the input stream, interleaved with keystrokes. scan/1 routes the chunk through Raxol.Terminal.Capabilities.ReplyScanner (grammar dispatch, both OSC terminators, leak-free residual) so reply bytes never leak into key-event parsing. A parsed DECRQM 2026 reply is noted on Raxol.Terminal.Capabilities -- Capabilities.sync_output?/0 is the one public emit-gate render paths consult. scan/1 keeps its original {result, cleaned} contract for the driver.

detected_background/0 is now a delegating shim over the unified Raxol.Terminal.Capabilities session record (native-palette-riding): it reads Capabilities.background/0 first, falling back to this module's own :persistent_term cache (written by store/1) only when no Capabilities record has been cached yet. store/1 is unchanged and still the entry point older callers use directly. The parse functions (parse_color/1 and friends) stay live -- Raxol.Terminal.Capabilities's own scanner/classifier path reuses them. Retirement planned: once every caller reads Capabilities.background/0 (or ground/0) directly, this module's :persistent_term fallback and store/1 go away and only the parse helpers, if still needed, get a new home.

Higher layers (e.g. salience theming) convert the background to a ground lightness -- see Raxol.UI.Theming.SalienceTheme.detect_ground/0.

Summary

Functions

Returns the detected background color, if any.

Escape sequence to write to the terminal to start detection.

Scans a raw input chunk for OSC 11 / DECRQM / DA replies while a query is pending.

Stores a detected background color for later lookup.

Types

rgb()

@type rgb() :: {0..255, 0..255, 0..255}

Functions

detected_background()

@spec detected_background() :: {:ok, rgb()} | :error

Returns the detected background color, if any.

Delegates to the unified Capabilities record when one has been cached for the session; falls back to this module's own :persistent_term cache (as written by store/1) only when no Capabilities record is cached yet. See the moduledoc's retirement note.

query_sequence()

@spec query_sequence() :: String.t()

Escape sequence to write to the terminal to start detection.

scan(data)

@spec scan(binary()) :: {{:ok, rgb()} | :unsupported | :pending, binary()}

Scans a raw input chunk for OSC 11 / DECRQM / DA replies while a query is pending.

Returns {result, cleaned} where cleaned is the chunk with any reply bytes removed (safe to hand to the key-event parser) and result is:

  • {:ok, {r, g, b}} - background color reported (8-bit per channel)
  • :unsupported - DA reply arrived without an OSC 11 reply
  • :pending - no reply in this chunk yet

store(rgb)

@spec store(rgb()) :: :ok

Stores a detected background color for later lookup.