fix: fix background color detection printing stuff into terminal on wsl boot

This commit is contained in:
Daniel Bauer
2026-08-28 13:31:16 +02:00
parent 2bac4dd8c4
commit f105143b5c

View File

@@ -13,19 +13,43 @@
# export TERM_BACKGROUND=light # or dark # export TERM_BACKGROUND=light # or dark
# in ~/.environment.local on that machine. # in ~/.environment.local on that machine.
# #
# Tune the response wait via TERM_BACKGROUND_TIMEOUT (tenths of a second). # Tune the per-attempt wait via TERM_BACKGROUND_TIMEOUT (tenths of a second)
# and the number of attempts via TERM_BACKGROUND_ATTEMPTS. We poll rather than
# do a single fixed-length read because on a freshly booted WSL instance the
# very first terminal's OSC 11 reply can arrive well after a short window
# closes; if we restored cooked/echo mode by then, the late reply leaks onto
# the screen (and into the shell's input buffer) as literal text. Staying in
# raw/no-echo mode across multiple short attempts lets a slow first reply
# still be captured silently instead of leaking.
# Need a controlling terminal to talk to. # Need a controlling terminal to talk to.
[ -t 0 ] || { echo dark; exit 0; } [ -t 0 ] || { echo dark; exit 0; }
exec 3<>/dev/tty || { echo dark; exit 0; } exec 3<>/dev/tty || { echo dark; exit 0; }
# Raw mode with a short read timeout (min 0 time N = up to N*0.1s) so an
# unresponsive terminal costs us at most that long.
saved=$(stty -g <&3 2>/dev/null) || { echo dark; exit 0; } saved=$(stty -g <&3 2>/dev/null) || { echo dark; exit 0; }
stty raw -echo min 0 time "${TERM_BACKGROUND_TIMEOUT:-4}" <&3 2>/dev/null stty raw -echo min 0 time "${TERM_BACKGROUND_TIMEOUT:-4}" <&3 2>/dev/null
printf '\033]11;?\033\\' >&3 # OSC 11 query printf '\033]11;?\033\\' >&3 # OSC 11 query
answer=$(dd bs=64 count=1 <&3 2>/dev/null)
answer=""
attempts="${TERM_BACKGROUND_ATTEMPTS:-3}"
i=0
while [ "$i" -lt "$attempts" ]; do
answer="$answer$(dd bs=64 count=1 <&3 2>/dev/null)"
# A full "rgb:RRRR/GGGG/BBBB" reply has two '/' separators; stop as soon
# as we have them instead of waiting out every remaining attempt.
rest=${answer#*rgb:}
if [ "$rest" != "$answer" ]; then
tmp=$rest
count=0
while [ "$tmp" != "${tmp#*/}" ]; do
count=$((count + 1))
tmp=${tmp#*/}
done
[ "$count" -ge 2 ] && break
fi
i=$((i + 1))
done
stty "$saved" <&3 2>/dev/null # restore before anything else stty "$saved" <&3 2>/dev/null # restore before anything else
exec 3>&- exec 3>&-