From 0500b249003e69a9b637868547a7bb2ebd6bcf7c Mon Sep 17 00:00:00 2001 From: mARTin-B78 Date: Wed, 10 Jun 2026 15:16:49 +0200 Subject: [PATCH] fix: horizontal scrollbars and empty STT Engines page in settings (v2.03.37) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Guard _refresh_status() with hasattr checks so opening STT Engines before LLM Engines page is built no longer crashes the builder silently - ww_status label: add max_width_chars(30) + ellipsize END so long model lists don't widen the Wakeword page - Benchmark STT sel_sw: NEVER→AUTOMATIC horizontal policy so wide engine names scroll internally instead of propagating to the dialog - _combo()/_type_combo(): set_size_request(10,-1) so ComboBoxText widgets (e.g. long microphone names) can shrink below natural width Co-Authored-By: Claude Sonnet 4.6 --- linux/CHANGELOG.md | 21 +++++++++++++++++++++ linux/blitztext/__init__.py | 2 +- linux/blitztext/gtksettings.py | 18 +++++++++++++----- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/linux/CHANGELOG.md b/linux/CHANGELOG.md index 2e5beab..ecf2cd4 100644 --- a/linux/CHANGELOG.md +++ b/linux/CHANGELOG.md @@ -9,6 +9,27 @@ The version is defined in [`blitztext/__init__.py`](blitztext/__init__.py). ## [Unreleased] +## [2.03.37] - 2026-06-10 + +### Fixed +- **STT Engines page no longer appears empty.** `_refresh_status()` called + `_stt_commit()` / `_llm_commit()` and accessed `stt_dot` / `llm_dot` + unconditionally; if the STT page was opened before the LLM page was built + (lazy), the builder crashed silently with `AttributeError`. Added `hasattr` + guards so each section is only committed / updated when its widgets exist. +- **Wakeword page no longer causes horizontal scrollbar.** The `ww_status` + label (showing model list like "7 models loaded: okay_nabu, hey_jarvis…") + had no width limit and expanded the page. Added `set_max_width_chars(30)` + and `set_ellipsize(END)`. +- **Benchmark STT engine list no longer causes horizontal scrollbar.** + `sel_sw` used `NEVER` horizontal policy, propagating long engine-name labels + (~800 px) up through the paned. Changed to `AUTOMATIC` so content scrolls + internally. +- **General page and LLM Engines no longer cause horizontal scrollbar.** + `_combo()` and `_type_combo()` lacked `set_size_request(10, -1)`, so + ComboBoxText widgets (e.g. long microphone device names) could not shrink + below their natural width. Added the size request to both helpers. + ## [2.03.36] - 2026-06-10 ### Changed diff --git a/linux/blitztext/__init__.py b/linux/blitztext/__init__.py index 91ab668..28f4765 100644 --- a/linux/blitztext/__init__.py +++ b/linux/blitztext/__init__.py @@ -6,4 +6,4 @@ counterpart to the macOS Blitztext menu bar app: it runs natively on the host (not in a container) so it can type into any application via xdotool. """ -__version__ = "2.03.36" +__version__ = "2.03.37" diff --git a/linux/blitztext/gtksettings.py b/linux/blitztext/gtksettings.py index 32df5de..6117d86 100644 --- a/linux/blitztext/gtksettings.py +++ b/linux/blitztext/gtksettings.py @@ -377,6 +377,7 @@ def _combo(options, active=None) -> Gtk.ComboBoxText: c.set_active(options.index(active)) elif options: c.set_active(0) + c.set_size_request(10, -1) return c @@ -407,6 +408,7 @@ def _type_combo(types: list[tuple[str, str]], stored: str = "") -> Gtk.ComboBoxT c.append_text(label) idx = next((i for i, (k, _) in enumerate(types) if k == stored), 0) c.set_active(idx) + c.set_size_request(10, -1) return c @@ -1675,15 +1677,19 @@ class SettingsDialog: # -- status dots (threaded) --- def _refresh_status(self) -> None: s = self.cfg.stt_engines[self._stt_idx] if 0 <= self._stt_idx < len(self.cfg.stt_engines) else None - self._stt_commit() + if hasattr(self, "stt_combo"): + self._stt_commit() l = self.cfg.llm_engines[self._llm_idx] if 0 <= self._llm_idx < len(self.cfg.llm_engines) else None - self._llm_commit() + if hasattr(self, "llm_combo"): + self._llm_commit() def check(): sc = GREEN if (s and stt.status(s)) else RED if s else GREY lc = GREEN if (l and llm.status(l)) else RED if l else GREY - GLib.idle_add(self.stt_dot.set_markup, _dot(sc)) - GLib.idle_add(self.llm_dot.set_markup, _dot(lc)) + if hasattr(self, "stt_dot"): + GLib.idle_add(self.stt_dot.set_markup, _dot(sc)) + if hasattr(self, "llm_dot"): + GLib.idle_add(self.llm_dot.set_markup, _dot(lc)) threading.Thread(target=check, daemon=True).start() def _probe_dot(self, dot: Gtk.Label, uri: str, fallback_port: int) -> None: @@ -1921,6 +1927,8 @@ class SettingsDialog: b = Gtk.Button(label=label); b.set_tooltip_text(tip); b.connect("clicked", cb) ww_bar.pack_end(b, False, False, 0) self.ww_status = Gtk.Label(xalign=0.0) + self.ww_status.set_max_width_chars(30) + self.ww_status.set_ellipsize(Pango.EllipsizeMode.END) self.ww_status.get_style_context().add_class("dim-label") ww_bar.pack_end(self.ww_status, False, False, 4) page.pack_start(ww_bar, False, False, 2) @@ -2360,7 +2368,7 @@ class SettingsDialog: page.pack_start(sel_hdr, False, False, 0) sel_sw = Gtk.ScrolledWindow() - sel_sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) + sel_sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) sel_sw.set_min_content_height(80) sel_list = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=1) sel_list.set_margin_start(4); sel_list.set_margin_end(4)