Skip to content

Commit 36da9b0

Browse files
Detect terminal background via OSC 11 in login splash
Queries the terminal with OSC 11 and picks light/dark from the reported luminance. Falls back to COLORFGBG, then dark. Much broader support than COLORFGBG alone (iTerm2, Alacritty, kitty, WezTerm, Ghostty, Windows Terminal, etc.). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 9efd9c5 commit 36da9b0

2 files changed

Lines changed: 50 additions & 3 deletions

File tree

docs/login-splash.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ All settings are controlled via environment variables with sensible defaults:
112112
| Variable | Default | Description |
113113
|----------|---------|-------------|
114114
| `BODHI_NOSPLASH` | *(unset)* | Set to any value to suppress the splash |
115-
| `BODHI_SPLASH_THEME` | *(auto-detect)* | Force `light` or `dark` color scheme (auto-detects via `COLORFGBG`) |
115+
| `BODHI_SPLASH_THEME` | *(auto-detect)* | Force `light` or `dark` color scheme (auto-detects via OSC 11 query, falling back to `COLORFGBG`) |
116116
| `BODHI_MOTD_DIR` | `/etc/bodhi/motd.d` | Directory for admin message files |
117117
| `BODHI_MOTD_FILE` | `/etc/bodhi/motd` | Single admin message file (fallback) |
118118
| `BODHI_SPLASH_HOSTS` | *(unset — show everywhere)* | Hostname glob to restrict to login nodes |

scripts/bodhi-splash

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,59 @@ __bodhi_splash_main() {
3333
local _docs_url="${BODHI_DOCS_URL:-https://rnabioco.github.io/bodhi-docs/}"
3434

3535
# -- Theme detection ---------------------------------------------------
36+
# Query the terminal's background via OSC 11.
37+
# Sends: ESC ] 11 ; ? BEL
38+
# Expects: ESC ] 11 ; rgb:RRRR/GGGG/BBBB BEL (components are 1-4 hex digits)
39+
# Echoes "light" or "dark" on success; returns non-zero on failure.
40+
_bs_probe_osc11() {
41+
[[ -t 0 && -t 1 ]] || return 1
42+
[[ -z "${TERM:-}" || "$TERM" == "dumb" ]] && return 1
43+
# Screen swallows OSC queries; skip to avoid hanging or leaking the probe
44+
[[ -n "${STY:-}" ]] && return 1
45+
46+
local _response _old_stty
47+
_old_stty=$(stty -g 2>/dev/null) || return 1
48+
stty -echo -icanon 2>/dev/null || return 1
49+
50+
printf '\e]11;?\a' > /dev/tty 2>/dev/null
51+
# Read up to BEL; rely on -t timeout rather than rc (ST-terminated
52+
# replies time out but still populate the variable with partial data).
53+
IFS= read -rs -t 0.15 -d $'\a' _response < /dev/tty
54+
55+
stty "$_old_stty" 2>/dev/null
56+
57+
[[ -z "$_response" ]] && return 1
58+
59+
if [[ "$_response" =~ rgb:([0-9a-fA-F]+)/([0-9a-fA-F]+)/([0-9a-fA-F]+) ]]; then
60+
local _rh="${BASH_REMATCH[1]}" _gh="${BASH_REMATCH[2]}" _bh="${BASH_REMATCH[3]}"
61+
local _max
62+
case "${#_rh}" in
63+
1) _max=15 ;;
64+
2) _max=255 ;;
65+
3) _max=4095 ;;
66+
4) _max=65535 ;;
67+
*) return 1 ;;
68+
esac
69+
local _lum=$(( ( 16#$_rh + 16#$_gh + 16#$_bh ) * 100 / (3 * _max) ))
70+
if (( _lum >= 50 )); then echo "light"; else echo "dark"; fi
71+
return 0
72+
fi
73+
return 1
74+
}
75+
3676
_bs_detect_theme() {
3777
# 1. Explicit override
3878
if [[ -n "${BODHI_SPLASH_THEME:-}" ]]; then
3979
echo "$BODHI_SPLASH_THEME"
4080
return
4181
fi
42-
# 2. Auto-detect via COLORFGBG (set by xterm, rxvt, etc.)
82+
# 2. Ask the terminal directly (OSC 11)
83+
local _theme
84+
if _theme=$(_bs_probe_osc11); then
85+
echo "$_theme"
86+
return
87+
fi
88+
# 3. Fall back to COLORFGBG (xterm/rxvt legacy)
4389
# Format: "fg;bg" or "fg;fade;bg" — last value is bg palette index
4490
if [[ -n "${COLORFGBG:-}" ]]; then
4591
local _bg="${COLORFGBG##*;}"
@@ -51,6 +97,7 @@ __bodhi_splash_main() {
5197
fi
5298
fi
5399
fi
100+
# 4. Default
54101
echo "dark"
55102
}
56103

@@ -352,7 +399,7 @@ __bodhi_splash_main() {
352399

353400
# -- Cleanup ---------------------------------------------------------
354401
unset -f _bs_top _bs_mid _bs_bot _bs_row _bs_row_colored_full
355-
unset -f _bs_detect_theme
402+
unset -f _bs_detect_theme _bs_probe_osc11
356403
unset -f _bs_now_epoch _bs_today_str _bs_last_thursday_epoch
357404
unset -f _bs_get_next_maintenance _bs_maintenance_banner
358405
unset -f _bs_has_messages _bs_admin_messages

0 commit comments

Comments
 (0)