From 1c276e767b1719be4bee9497cd91253ccfdcb94e Mon Sep 17 00:00:00 2001 From: mARTin-B78 Date: Wed, 10 Jun 2026 11:38:48 +0200 Subject: [PATCH] fix: block scroll-wheel changes on all ComboBoxText dropdowns (v2.03.28) Hovering over a combo and scrolling could silently change the selection. All ComboBoxText widgets now return True from their scroll-event handler, swallowing the event before GTK's default handler can act on it. Co-Authored-By: Claude Sonnet 4.6 --- linux/CHANGELOG.md | 7 +++++++ linux/blitztext/__init__.py | 2 +- linux/blitztext/gtksettings.py | 20 +++++++++++++------- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/linux/CHANGELOG.md b/linux/CHANGELOG.md index c0f2822..6dd98e8 100644 --- a/linux/CHANGELOG.md +++ b/linux/CHANGELOG.md @@ -9,6 +9,13 @@ The version is defined in [`blitztext/__init__.py`](blitztext/__init__.py). ## [Unreleased] +## [2.03.28] - 2026-06-10 + +### Fixed +- **Dropdowns no longer change on accidental scroll.** All `ComboBoxText` + widgets in the settings dialog now swallow scroll events so hovering over + a combo and scrolling doesn't silently change the selected value. + ## [2.03.27] - 2026-06-10 ### Added diff --git a/linux/blitztext/__init__.py b/linux/blitztext/__init__.py index da66f45..b8eea89 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.27" +__version__ = "2.03.28" diff --git a/linux/blitztext/gtksettings.py b/linux/blitztext/gtksettings.py index df59a1f..8c57290 100644 --- a/linux/blitztext/gtksettings.py +++ b/linux/blitztext/gtksettings.py @@ -359,8 +359,14 @@ def _entry(text="", placeholder="") -> Gtk.Entry: return e +def _block_scroll(combo: Gtk.ComboBoxText) -> Gtk.ComboBoxText: + """Prevent accidental value changes from mouse-wheel hover-scrolling.""" + combo.connect("scroll-event", lambda _w, _e: True) + return combo + + def _combo(options, active=None) -> Gtk.ComboBoxText: - c = Gtk.ComboBoxText() + c = _block_scroll(Gtk.ComboBoxText()) for o in options: c.append_text(o) if active in options: @@ -392,7 +398,7 @@ def _info_btn(text: str) -> Gtk.Button: def _type_combo(types: list[tuple[str, str]], stored: str = "") -> Gtk.ComboBoxText: """Combo that shows human-readable labels but maps to/from internal key values via index.""" - c = Gtk.ComboBoxText() + c = _block_scroll(Gtk.ComboBoxText()) for _, label in types: c.append_text(label) idx = next((i for i, (k, _) in enumerate(types) if k == stored), 0) @@ -899,7 +905,7 @@ notebook.bt-nb tab:checked label { # ── Selector bar ────────────────────────────────────────────────────── bar = Gtk.Box(spacing=8) bar.set_margin_bottom(6) - self.wf_combo = Gtk.ComboBoxText() + self.wf_combo = _block_scroll(Gtk.ComboBoxText()) for wf in self.cfg.workflows: self.wf_combo.append_text(wf.name) self.wf_combo.set_active(0) @@ -1210,7 +1216,7 @@ notebook.bt-nb tab:checked label { # ── Selector bar ────────────────────────────────────────────────────── bar = Gtk.Box(spacing=6) - self.stt_combo = Gtk.ComboBoxText() + self.stt_combo = _block_scroll(Gtk.ComboBoxText()) for e in self.cfg.stt_engines: self.stt_combo.append_text(e.name) self.stt_combo.set_active(self._index_of(self.cfg.stt_engines, self.cfg.stt_active)) @@ -1300,7 +1306,7 @@ notebook.bt-nb tab:checked label { # ── Selector bar ────────────────────────────────────────────────────── bar = Gtk.Box(spacing=6) - self.llm_combo = Gtk.ComboBoxText() + self.llm_combo = _block_scroll(Gtk.ComboBoxText()) for e in self.cfg.llm_engines: self.llm_combo.append_text(e.name) self.llm_combo.set_active(self._index_of(self.cfg.llm_engines, self.cfg.llm_active)) @@ -1783,7 +1789,7 @@ notebook.bt-nb tab:checked label { # ── Engine selector bar ─────────────────────────────────────────────── ww_bar = Gtk.Box(spacing=6); ww_bar.set_margin_top(6) - self.ww_combo = Gtk.ComboBoxText(); self.ww_combo.set_hexpand(True) + self.ww_combo = _block_scroll(Gtk.ComboBoxText()); self.ww_combo.set_hexpand(True) for e in self.cfg.wakeword_engines: self.ww_combo.append_text(e.name) active_idx = next((i for i, e in enumerate(self.cfg.wakeword_engines) @@ -2982,7 +2988,7 @@ notebook.bt-nb tab:checked label { lvl_lbl = Gtk.Label(label="Level:"); lvl_lbl.set_margin_start(8) bar.pack_start(lvl_lbl, False, False, 0) - self.log_level = Gtk.ComboBoxText() + self.log_level = _block_scroll(Gtk.ComboBoxText()) for lvl in ("Verbose", "Info", "Warning", "Error"): self.log_level.append_text(lvl) self.log_level.set_active(1) # default: Info