diff --git a/linux/CHANGELOG.md b/linux/CHANGELOG.md index 5cb6065..9a259cd 100644 --- a/linux/CHANGELOG.md +++ b/linux/CHANGELOG.md @@ -9,6 +9,16 @@ The version is defined in [`blitztext/__init__.py`](blitztext/__init__.py). ## [Unreleased] +## [2.03.24] - 2026-06-10 + +### Fixed +- **Input level meter works without visiting General first.** The level meter + was only started inside `_build_general()` and referenced `mic_level` + unconditionally. If Input was opened first the meter never started. Now + `_build_input()` also starts the meter when it isn't running yet, and both + level bars (`mic_level` in General and `ww_mic_level` in Input) are updated + defensively via `hasattr` so either tab can be visited in any order. + ## [2.03.23] - 2026-06-10 ### Fixed diff --git a/linux/blitztext/__init__.py b/linux/blitztext/__init__.py index fef13c2..199a185 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.23" +__version__ = "2.03.24" diff --git a/linux/blitztext/gtksettings.py b/linux/blitztext/gtksettings.py index 918c51d..7ed44a5 100644 --- a/linux/blitztext/gtksettings.py +++ b/linux/blitztext/gtksettings.py @@ -1806,6 +1806,11 @@ notebook.bt-nb tab:checked label { self.snd_after = self._sound_field(snd_card, "Stop sound", self.cfg.sound_after, "Plays when manual recording stops (paste, paste+Enter, or auto-stop).", width=LW) + # Start meter if not already running (covers the case where Input is + # visited before General, which is where _start_meter() normally fires). + if self._meter is None: + self._start_meter() + def _sound_field(self, page, label: str, value: str, tooltip: str = "", empty_note: str = "Leave empty to use the built-in system sound.", clear_tip: str = "Clear — use the built-in system sound", @@ -1948,13 +1953,16 @@ notebook.bt-nb tab:checked label { self._start_meter() def _selected_mic_name(self) -> str: + if not hasattr(self, "gen_mic"): + return "" # General tab not yet built; use default device i = self.gen_mic.get_active() return self._mics[i][0] if 0 <= i < len(self._mics) else "" def _start_meter(self) -> None: self._stop_meter() def on_level(v): - GLib.idle_add(self.mic_level.set_value, v) + if hasattr(self, "mic_level"): + GLib.idle_add(self.mic_level.set_value, v) if hasattr(self, "ww_mic_level"): GLib.idle_add(self.ww_mic_level.set_value, v) self._meter = audio.LevelMeter(self._selected_mic_name(), on_level=on_level)