Module: Tuile::TerminalBackground
- Defined in:
- lib/tuile/terminal_background.rb,
sig/tuile.rbs
Overview
Detects whether the terminal background is light or dark, so Screen can pick Tuile::Theme::LIGHT or Tuile::Theme::DARK automatically at startup.
Two mechanisms, in order of reliability:
- OSC 11 query — writes
ESC ] 11 ; ? BELto the terminal; modern terminals (xterm, kitty, alacritty, wezterm, iTerm2, GNOME Terminal, Windows Terminal) reply on stdin with the background color (\e]11;rgb:RRRR/GGGG/BBBB+ BEL or ST). The color's relative luminance against a 0.5 threshold decides light vs dark. Terminals that don't support the query simply never reply, so the read is bounded by a short timeout. COLORFGBGenv var — rxvt/konsole export"fg;bg"ANSI palette indices. Less reliable (stale across SSH/tmux, often unset); used only when OSC 11 yields nothing.
Timing matters: the OSC 11 reply arrives on stdin, so the query must complete before EventQueue#start_key_thread owns stdin — otherwise the reply bytes get consumed as garbage keystrokes. Screen calls TerminalBackground.detect from its constructor, which apps run before Screen#run_event_loop; don't call this after the event loop started.
Constant Summary collapse
- QUERY_TIMEOUT =
How long to wait for the OSC 11 reply. Generous for a local terminal; bounded so unsupporting terminals (which never reply) don't stall startup.
0.1- QUERY =
The OSC 11 background-color query, BEL-terminated.
"\e]11;?\a"- REPLY =
Matches the OSC 11 reply. Components are 1–4 hex digits each (terminals vary);
rgba:(4 components) also matches — the alpha tail is ignored. %r{\e\]11;rgba?:(\h{1,4})/(\h{1,4})/(\h{1,4})}- NOTIFY_ON =
Enables mode 2031: the terminal pushes a color-scheme report (
\e[?997;1ndark /\e[?997;2nlight) whenever the OS appearance flips — see EventQueue::ColorSchemeEvent. Terminals without support ignore the sequence. Written by Screen#run_event_loop. "\e[?2031h"- NOTIFY_OFF =
Disables mode 2031 again; written when the event loop exits.
"\e[?2031l"
Class Method Summary collapse
-
.detect(input: $stdin, output: $stdout, env: ENV, timeout: QUERY_TIMEOUT) ⇒ Object
Detects the terminal background.
Class Method Details
.detect(input: $stdin, output: $stdout, env: ENV, timeout: QUERY_TIMEOUT) ⇒ Object
Detects the terminal background. Queries OSC 11 when both input
and output are TTYs, falling back to COLORFGBG.
@param input — where the OSC 11 reply arrives (the TTY input).
@param output — where the query is written (the TTY output).
@param env — environment for the COLORFGBG fallback; defaults to ENV (which duck-types the [] lookup).
@param timeout — max seconds to wait for the OSC 11 reply.
@return — :light, :dark, or nil when undetectable.
63 64 65 66 |
# File 'lib/tuile/terminal_background.rb', line 63 def detect(input: $stdin, output: $stdout, env: ENV, timeout: QUERY_TIMEOUT) osc = query_osc11(input, output, timeout) if input.tty? && output.tty? osc || from_colorfgbg(env["COLORFGBG"]) end |