From 83677a2235d275186ebc83a95b7470060151ffda Mon Sep 17 00:00:00 2001 From: Forrest Date: Wed, 10 Jun 2026 02:18:14 -0700 Subject: [PATCH] fix(choose-fonts): guard preview rendering against partial terminal color query MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The choose-fonts kitten queries the terminal for the user's foreground and background colors at startup by sending a DCS request. The terminal responds with separate DCS response strings — one per field — which arrive asynchronously through on_query_response. The background handler unconditionally called draw_screen() after storing its value. If the terminal's DCS response for "background" arrived before the response for "foreground", draw_screen() fired with text_style.Foreground still at its Go zero value (""). The font list preview (list.go) only guarded against empty Background, not empty Foreground, so it passed the check and sent a render_family_samples command to the Python backend with foreground="". The backend's to_color('') raised ValueError: Invalid color name: '', crashing the kitten. The faces pane (faces.go) launched a render_family_samples goroutine unconditionally when its preview cache was empty, with no guard at all. Fix --- 1. ui.go — Only trigger draw_screen() from the foreground or background handler when the counterpart field is already populated, so the UI never renders with a partial TextStyle. 2. list.go — Require both Foreground and Background to be non-empty before rendering the font preview, not just Background alone. 3. faces.go — Skip the render_family_samples goroutine if either color field is still empty. The preview cache stays empty, so the next redraw (triggered when the counterpart query response arrives, or by on_wakeup) retries with full colors. --- kittens/choose_fonts/faces.go | 3 +++ kittens/choose_fonts/list.go | 2 +- kittens/choose_fonts/ui.go | 7 ++++++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/kittens/choose_fonts/faces.go b/kittens/choose_fonts/faces.go index 9f33e8015..5b51245b5 100644 --- a/kittens/choose_fonts/faces.go +++ b/kittens/choose_fonts/faces.go @@ -52,6 +52,9 @@ func (self *faces) draw_screen() (err error) { previews, found := self.preview_cache[key] if !found { self.preview_cache[key] = make(map[string]RenderedSampleTransmit) + if self.handler.text_style.Foreground == "" || self.handler.text_style.Background == "" { + return + } go func() { var r map[string]RenderedSampleTransmit s := key.settings diff --git a/kittens/choose_fonts/list.go b/kittens/choose_fonts/list.go index ecff98d88..8150a399a 100644 --- a/kittens/choose_fonts/list.go +++ b/kittens/choose_fonts/list.go @@ -122,7 +122,7 @@ func (self *FontList) draw_family_summary(start_x int, sz loop.ScreenSize) (err lp.QueueWriteString(line) y++ } - if self.handler.text_style.Background != "" { + if self.handler.text_style.Foreground != "" && self.handler.text_style.Background != "" { return self.draw_preview(start_x, y, sz) } return diff --git a/kittens/choose_fonts/ui.go b/kittens/choose_fonts/ui.go index 11d16fe8d..78ad5e15a 100644 --- a/kittens/choose_fonts/ui.go +++ b/kittens/choose_fonts/ui.go @@ -139,9 +139,14 @@ func (h *handler) on_query_response(key, val string, valid bool) error { } case "foreground": h.text_style.Foreground = val + if h.text_style.Background != "" { + return h.draw_screen() + } case "background": h.text_style.Background = val - return h.draw_screen() + if h.text_style.Foreground != "" { + return h.draw_screen() + } } return nil }