Commit Graph

102 Commits

Author SHA1 Message Date
ccf3801545 feat: icons on all settings tabs and section headers (v2.03.12)
GTK symbolic icons on every tab label and every section/card header.
Also fixes the resize grip landing in the tab bar instead of the bottom-right corner.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 00:07:41 +02:00
efa44c8872 feat: resize grip indicator on settings window (v2.03.11)
Draws a classic dotted SE-corner grip overlaid on the bottom-right of the
notebook so users know the settings dialog is resizable.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 23:50:20 +02:00
c292ff2242 fix: probe Prometheus /metrics at server root, not under /v1 (v2.03.10)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 23:30:33 +02:00
c3cf123afe feat: server RAM via Prometheus /metrics in benchmark (v2.03.09)
Probe remote engines' /metrics for process_resident_memory_bytes or
container_memory_rss; show actual server-side MB in RAM column.
Falls back to "server" when the endpoint is not exposed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 23:24:40 +02:00
86632e1918 fix: hide Internal Engine section for remote/streaming engines (v2.03.08)
Removes whitespace gap between STT config card and device/precision card
by hiding the latter when a Server or Realtime engine type is selected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 23:06:32 +02:00
d5e512a812 feat: per-engine timeout field, WhisperX default 120s (v2.03.07)
- STTEngine gains timeout: int = 30 field; used as HTTP timeout per engine
- Engines tab shows "Timeout (s)" field; blank = 30s default
- WhisperX quickstart template pre-sets 120s (diarization is slow)
- config load/save: only written when != 30 to keep config clean
- RAM column header tooltip explains "server" for Docker/remote engines

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 22:48:53 +02:00
2326f20a28 fix: numeric sort for Time, Accuracy, RAM columns (v2.03.06)
String sort put "14.85" before "2.47". Now uses a custom comparator
that strips % and non-numeric markers before comparing as float.
Non-numeric values ("—", "server") sort to the bottom.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 22:37:17 +02:00
05ccfbdeb4 fix: RAM column shows "server" for remote engines (v2.03.05)
Remote engines run models server-side so local RSS never changes.
Show "server" instead of "—" to make the reason clear.
Local engines show measured MB; local already-loaded shows "—".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 22:34:41 +02:00
d40721dd3d fix: reduce transcription timeout to 30s (v2.03.04)
300s was too long; nobody waits 5 min for a result.
30s gives slow remote servers a fair window while still failing fast.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 22:25:17 +02:00
79f3b5cdab fix: API probe URLs, 5min timeout for slow engines like WhisperX (v2.03.03)
- Add _api_base() to strip endpoint-specific path suffixes before probing
  /models, /metadata, /info — fixes /transcribe/models 404 spam when URL
  ends with a custom path like /v1/transcribe
- Increase default transcribe() timeout 60s → 300s — WhisperX with speaker
  diarization (pyannote) takes 2-5 min and was always timing out

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 22:23:13 +02:00
766002a478 fix: WhisperX URL — add template, tooltip clarifying /transcribe path (v2.03.02)
- Add "WhisperX server" quickstart template pre-filled with /transcribe endpoint
- Add tooltip to STT URL field explaining that non-standard servers (WhisperX)
  should use the full endpoint as the URL, not /v1
- _url_field_lb accepts optional tooltip= kwarg

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 22:16:21 +02:00
d9603c98bf feat: RAM usage column in benchmark, docs update (v2.03.01)
- benchmark.py: measure RSS delta via /proc/self/status before/after each
  transcription; add ram_mb field to BenchRow
- gtksettings.py: add RAM (MB) column to results table (index 8); tooltip
  column shifted to index 10
- CHANGELOG.md: full history from v2.02.00 through v2.03.01
- README.md: benchmark description updated to mention RAM column
- MANUAL.md: benchmark result columns as table; Log tab documents
  level filter dropdown

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 22:11:38 +02:00
f5f65ffba9 fix: stability, WhisperX 404, log levels (v2.03.00)
- Stability: remove blocking TCP socket call from _collect() — was
  freezing the GTK main thread on Save when wakeword server unreachable;
  now checks async in background and logs result
- Thread safety: fix _ww_load() reading GTK widget from background thread;
  capture URI on main thread before spawning
- WhisperX 404: _transcribe_remote now detects non-standard paths
  (anything other than /v1) and uses the URL as the full endpoint,
  so http://host/transcribe works without /audio/transcriptions appended
- Log levels: logbuffer stores (ts, level, msg) tuples; log() accepts
  level= (DEBUG/INFO/WARNING/ERROR); Log tab gets a Level dropdown
  (Verbose/Info/Warning/Error) that filters displayed entries live

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 22:01:14 +02:00
6fb41d5a9b feat: wakeword server preset dropdown in Input tab (v2.02.03)
Adds a "Server preset" combo in the Hands-free wakeword card that lists
all configured wakeword engines by name. Selecting one auto-fills the
URI and model fields and re-probes the connection. Selection persists
via wakeword_active in config.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 21:01:57 +02:00
48014ae662 fix: license in md style, benchmark pane minimum height (v2.02.02)
- About tab: render License with _md_panel instead of _text_panel
- Benchmark pane: set_size_request 320px min, shrink=False on both sides
  so the engine list and results table are always visible

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 20:55:57 +02:00
9b95c632fa feat: show last benchmark time+accuracy on selected STT engine (v2.02.01)
After running a benchmark, each engine's best result (time, accuracy)
is persisted to config and shown as a small info line in the Engines tab
when that engine is selected. Updates live as the benchmark runs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 20:42:22 +02:00
2df5be3212 feat: language metadata in benchmark — Lang column, filter support (v2.02.00)
- stt.py: add ModelMeta dataclass, fmt_languages(), list_models_meta(),
  detect_remote_device(); refactor list_models() to delegate
- benchmark.py: add languages field to BenchRow; fetch via _get_langs()
  with URL-level caching using list_models_meta()
- gtksettings.py: show language labels per engine in checkbox list;
  add language codes to search filter; add Lang column to results table

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 20:02:12 +02:00
51ab6d5aff ui: larger, more visible tab labels (v2.01.03)
- Tab font-size 12px → 14px (matches body text)
- Inactive tabs: muted foreground color so they're clearly readable
  but visually distinct from the active tab
- Active tab: bold + blue (#1a73e8), slightly more padding (8px 18px)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 19:34:48 +02:00
8d79c84a8f chore: adopt x.xx.xx versioning schema (v2.01.02)
Schema: MAJOR.FEATURE.FIX
  MAJOR  — breaking changes / major redesign
  FEATURE — two-digit, new user-visible features (00-99)
  FIX     — two-digit, bug fixes within a feature release (00-99)

Renamed 2.1.2 → 2.01.02 to start the new format.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 19:27:13 +02:00
81b79299ea fix: _run_bench crashes when Engines tab was never opened (v2.1.2)
_stt_commit() accesses self.stt_name which only exists after the Engines
tab is lazily built. Guard with hasattr so running a benchmark directly
from the Benchmark tab no longer throws AttributeError.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 19:21:56 +02:00
0eafb59d82 benchmark: resizable engine/results pane; auto-save WAV+ref paths (v2.1.1)
- Engine checklist and results table now split by a Gtk.Paned (vertical)
  so the user can drag the divider to give more room to either panel
- WAV and reference .txt paths are written to disk (save()) the moment a
  file is picked via the file chooser, without needing to click Save;
  also saved on Run if they changed since the last disk write

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 19:18:34 +02:00
e39b253906 benchmark: engine checkbox selector + status dots; manual/about/templates (v2.0.9)
- Benchmark tab: scrollable engine checklist above Run with live
  reachability dots (green/red), name+model+URL filter, All/None buttons;
  _run_bench respects selection and shows clear message when nothing ticked
- About tab: changelog now rendered via _md_panel (markdown headers, bold,
  lists) instead of plain monospace _text_panel
- Manual tab: graceful fallback with clickable GitHub link when MANUAL.md
  is not installed; build-deb.sh now copies MANUAL.md from repo root so
  /opt/blitztext/MANUAL.md exists in future installs
- STT quickstart templates expanded: Speaches docker, whisper.cpp server,
  NVIDIA NIM/Parakeet, five built-in local model sizes (tiny→large-v3)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 19:06:08 +02:00
a6d960bfbf benchmark: sortable columns (v2.0.8)
Wrap ListStore in TreeModelSort and set sort_column_id on every column
so clicking any header sorts ascending/descending.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 18:36:27 +02:00
5458fdc1eb engines: Test button inline with result + selectable; benchmark: persist WAV/ref paths (v2.0.7)
- Engines tab: move Test button out of the toolbar, place it in a row
  directly beside the result label so button and output are co-located;
  result label is now selectable so error text can be copied
- Benchmark tab: add bench_wav/bench_ref/bench_expand_models to Config;
  file pickers restore last-used paths on open; any change (file-set,
  toggle, or Run) writes directly to cfg so paths survive without Save;
  [benchmark] section written to config.toml on Save

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 18:29:01 +02:00
1c16cfeb0f benchmark: remote GPU detection, URL column, test-all-models (v2.0.6)
- stt.detect_remote_device(): probes /info (faster-whisper-server) then
  /metadata (NVIDIA NIM) to detect CUDA vs CPU; cached per unique URL
- BenchRow gains url field; Device column now shows "CUDA" for GPU remotes
  instead of the generic "remote"
- Benchmark table gains URL column (scheme stripped, max 180px wide)
- "Test all models per engine" checkbox: fetches list_models() for each
  remote engine and expands to one row per model when checked
- benchmark.run() gains expand_models parameter

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 18:19:42 +02:00
bc6e2a6e54 benchmark: deduplicate engines, friendly error messages, tooltip for full error (v2.0.5)
- _run_bench: deduplicate STT engines by name before running; show a
  warning in the summary line listing which names were skipped
- _bench_add_row: replace raw HTTP error strings with human-readable
  reasons ("Wrong model name", "Server offline", "Timed out", etc.);
  full raw error stored in hidden column 7 shown as row tooltip on hover
- bench_store: added 8th column (tooltip text); tree.set_tooltip_column(7)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 18:12:09 +02:00
4d59853da6 benchmark: add 'Best for' column, rename GPU→CUDA (v2.0.4)
- BenchRow gains `best_for` field: "Short clips" / "Short / medium" /
  "Long / batch" / "Streaming" — derived from engine type and model name
- Device now shows "CUDA" instead of "GPU" for clarity
- Benchmark table gains a "Best for" column between Device and Time(s)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 17:28:55 +02:00
0ff0f604c2 stt: omit model field when empty (fixes Riva 400); settings: always-visible scrollbar (v2.0.3)
- stt._transcribe_remote: no longer falls back to "whisper-1" when
  engine.model is empty — omits the field entirely so Riva/NIM uses its
  default model instead of rejecting the request with HTTP 400
- gtksettings._page: switch vertical scroll policy to ALWAYS and disable
  overlay scrolling so the scrollbar is permanently visible, making
  it obvious when a tab has more content below the visible area

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 17:00:58 +02:00
101bb1e796 engines: detect Riva/NIM model from /metadata, show placeholder on empty fetch
- stt.list_models(): fall back to /metadata (NVIDIA Riva/NIM) when /models
  returns nothing — extracts shortName and strips the version tag suffix
- Settings: show "type model name manually" placeholder when fetch returns
  empty and no model is currently set

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 16:49:58 +02:00
6534284c56 bump version to 2.0.2
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 16:04:38 +02:00
4f68eda501 fix: suppress numpy Pylance false positive in wakeword_bench.py
numpy is a runtime dep bundled in the .deb venv but not in the dev
.venv, so Pylance can't resolve it at edit time.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 16:02:50 +02:00
9022b17186 fix: Pylance errors in gtksettings.py + pyrightconfig venv path
- str() wrap float config values passed to _entry() (min_speech_seconds,
  silence_rms, wakeword_silence_seconds) — type error + runtime safety
- Guard m.group() calls after re.match() with 'if m:' — m can be None
- Fix _bench_done: guard 'acc' None check alongside 'fastest'
- Fix wakeword_bench.run() call: pass engines as first positional arg,
  remove invalid wakeword_model/wakeword_uri kwargs
- gi.repository import: add type: ignore[import-untyped] to suppress
  Pylance false positives from missing C-extension stubs
- pyrightconfig.json: point venv to linux/.venv so numpy resolves;
  add reportMissingModuleSource=none for stub-less system packages

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 16:02:07 +02:00
aea24400af fix: auto-paste long/multiline output, O(n²) overlay accumulation (v2.0.1)
Root cause of session freeze confirmed: a 15 000-char code block was typed
character-by-character via xdotool at 12ms/char = ~3 min, flooding the X11
per-client event buffer until the entire session froze.

- paste.py: any text >300 chars or containing newlines auto-upgrades to
  clipboard paste (instant Ctrl+V) regardless of configured output mode.
  xdotool type is kept only for short single-line text where it matters.
- daemon.py: replace on_token "".join(acc) accumulation (O(n²) for long
  code blocks) with a sliding deque that shows only the last 400 chars in
  the overlay — Pango no longer re-lays out a growing 15 KB string on each
  incoming token.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 15:56:44 +02:00
73264af2be fix SyntaxWarning: escape backslash in SIGQUIT docstring
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 15:38:39 +02:00
99340b0ff3 bump version to 2.0.0
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 15:35:28 +02:00
0d1311ba18 stability: fix GTK thread safety, wakeword hang, freeze diagnostic (v2.0.0)
- daemon: GLib.timeout_add (thinking animation) was called from a background
  thread — NOT thread-safe in PyGObject/GTK3 and the prime suspect for the
  session-level freezes. Fixed via idle_add so timeout_add runs on main thread.
- daemon: add SIGQUIT handler — kill -QUIT <pid> dumps all thread stacks to
  the log so the freeze location can be identified without rebooting.
- daemon: VAD hard-timeout safety net — if LevelMeter fails to open the mic
  (device busy because wakeword pw-record holds it), dictation now auto-stops
  after 30s instead of hanging forever. Wakeword sessions also capped at 60s.
- overlay: coalesce set_level() calls the same way set_text() is coalesced,
  so mic level spikes from 3 simultaneous pw-record streams can't flood the
  GTK main loop either.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 15:29:45 +02:00
59118364fb bump version to 1.9.9
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 15:10:22 +02:00
0875fe7ac0 llm: catch all exceptions, validate response, show transcription preview (v1.9.9)
- llm.py: catch OSError/TimeoutError (socket.timeout is NOT a URLError subclass)
  and bare Exception so no path kills the background thread silently
- daemon.py: catch unexpected exceptions from llm.chat and surface them as
  overlay errors instead of silent thread death
- daemon.py: reject LLM responses that are >80 % whitespace (cold-start
  model returning spaces/blank lines gets discarded, not typed)
- daemon.py: show transcribed text in overlay immediately before thinking
  animation so user can see what was heard while LLM processes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 15:02:45 +02:00
749ef78383 dictation: spoken newlines + LLM thinking animation (v1.9.8)
- Add expand_spoken_punctuation() in quality.py: converts spoken phrases
  "new line" / "neue Zeile" → \n and "new paragraph" / "neuer Absatz" → \n\n
  before text is typed; xdotool/wtype handle \n as Return
- Daemon: pulse " Thinking..." animation in the overlay while waiting for
  the first LLM token (400ms interval), replaced automatically when streaming
  starts so the user sees activity during cold-start latency

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 14:43:15 +02:00
946d344090 presets: per-preset LLM engine selector + fix streaming freeze (v1.9.7)
- Add llm_engine field to Workflow (config.py load/save)
- Daemon picks the named engine per-preset, falls back to active engine
- Settings Presets tab: replace free-text model field with engine dropdown
  populated from configured engines; "(active engine)" = default
- Fix LLM token streaming crash: coalesce GLib.idle_add calls so only
  one flush is ever queued (prevents GTK main loop flooding)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 14:39:59 +02:00
9e291437bd stability + settings: fix AT-SPI session freeze, markdown Manual, bigger emojis (v1.9.6)
caret: change default overlay_anchor from "caret" to "pointer" — AT-SPI's
synchronous D-Bus extents read on the GTK main loop could freeze the entire
X11 session when the focused app was slow to respond. Pointer anchor is a
reliable fallback (the mouse is almost always near where you're typing) and
avoids AT-SPI entirely by default.

caret: wrap the AT-SPI rect() read in a daemon thread with a hard 300ms
timeout — so even if overlay_anchor="caret" is configured manually, a frozen
or unresponsive target app can never stall the GTK main loop.

settings: replace the Manual tab's plain TextView with a styled markdown
renderer (_md_panel): # h1/h2/h3 headings, **bold**, *italic*, `inline code`,
> blockquotes, --- rules, bullet/numbered lists, and | tables |.

settings: infobox background changed from theme-adaptive grey (unreadable on
dark themes) to a fixed blue tint (rgba 66,133,244 @ 9%) with a matching blue
border — readable in both light and dark themes.

settings: active notebook tab now shows bold text with a #1a73e8 blue colour
and extra padding, making the current tab obviously distinct.

settings: emoji picker buttons enlarged to 20 px / 38×38 px minimum (grid)
and 18 px / 34×34 px (category bar) via bt-emoji-btn / bt-emoji-cat-btn CSS
classes — previously rendered at the default button label size (~11 px).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 14:20:05 +02:00
48be824a50 settings: emoji search, Manual tab fix, readable infobox (v1.9.5)
- Emoji picker: SearchEntry at top filters all categories via unicodedata.name()
  in real time; category view hides while searching, restores on clear
- Manual tab: add pkg_dir/MANUAL.md to _app_paths() search list so it works in
  both venv and deb installs (MANUAL.md deployed alongside the package)
- bt-infobox CSS: replace @theme_selected_bg_color (saturated blue) with a
  neutral 5% mix of fg/bg so banner text is always readable

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 13:09:42 +02:00
2fe6632269 settings: complete UI redesign — card layout, section titles, scrollable tabs (v1.9.4)
All settings tabs now use a card-based GTK3 layout:
- Related fields grouped into Gtk.ListBox cards with rounded borders (bt-card /
  boxed-list CSS) and bold all-caps section headers via _card_section helper
- CSS provider injected at init: .bt-section, .bt-card, .bt-infobox styles
- Each notebook page wraps content in a ScrolledWindow (740×700 px dialog)
- _labeled and _switch_row accept both Gtk.Box and Gtk.ListBox parents
- New helpers: _section_title, _card_section, _lb_add, _url_field_lb,
  _icon_field_lb, _key_field_lb
- Engines toolbars: creation buttons (+ Add/Stream/Quickstart) left-aligned,
  action buttons (Delete/Test/⟳) right-aligned via pack_end
- Presets: Identity / Trigger / Behaviour / Prompt cards
- Input: Input mode & keys / Quality gate / Wakeword / Sound cues cards
- General: Microphone / Output & language / Notifications / Startup cards
- Section names cleaned up (no more "WW -" prefix, cleaner device label)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 12:18:50 +02:00
dd617f625e settings: info buttons, Manual tab, engine quickstart templates, human-readable type names (v1.9.3)
- Every _labeled and _switch_row field now gets a clickable ⓘ info button
  that opens a plain-language help popover — targeted at non-technical users
- New Manual tab in Settings renders MANUAL.md directly inside the dialog
- STT and LLM toolbars each get a "Quickstart ▾" button: a menu of common
  providers (OpenAI, Groq, OpenRouter, Ollama, LM Studio, vLLM, llama-swap,
  faster-whisper-server, NVIDIA Riva) that pre-fills the engine form in one click
- Engine type combos now show human-readable labels ("Internal — faster-whisper",
  "LAN server — runs on your machine", "GPU (CUDA)", "int8 — fast, less memory")
  while storing the same internal key values (no config migration needed)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 11:48:02 +02:00
d2c6d352a5 presets: replace emoji picker with categorized WhatsApp-style grid
Replaces the 60-emoji flat list with 8 standard Unicode categories
(Smileys, People, Animals, Food, Travel, Activities, Objects, Symbols),
each with 30–100 emojis. The picker now has a category tab bar at the top
(emoji icons, highlighted active tab) and a scrollable emoji grid below —
matching the layout used in WhatsApp and other messaging apps.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 11:33:30 +02:00
cc589f254b presets: add emoji picker to the Icon field (v1.9.2)
Adds a 😀 button next to the Icon (emoji) entry in Settings → Presets.
Clicking it opens a GTK popover with 60 common emojis in a scrollable
flow grid; selecting one writes it into the field and closes the picker.
The entry still accepts direct keyboard input as before.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 10:32:11 +02:00
7cbd828781 gtksettings: fix NameError in ww_load error lambda (Python 3.12 scoping)
In Python 3.12 the 'except ... as e' variable is deleted after the except
block exits, so a plain lambda that closes over 'e' raises NameError when
GLib fires it later. Bind e as a default argument at lambda creation time.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 21:21:43 +02:00
b0b7a8c95e gtksettings: align Input tab labels to uniform 175px width; autostart: add 12s delay
All rows in the Input tab (labeled, key_field, url_field, sound_field) now share
a single LW=175 label width, eliminating the jagged left edge on input fields.
Added X-GNOME-Autostart-Delay=12 to the .desktop entry so gnome-shell, AT-SPI,
and the input stack are fully initialised before Blitztext connects — fixes the
session crash on first login after installation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 20:00:33 +02:00
a472ce62ba settings: lazy-build tabs (instant open); move connection dots beside the field; single-instance Settings dialog; Release 1.9.1
- gtksettings: build each notebook tab on first view instead of all up front, so
  the dialog opens instantly (was ~1.3s building Input/Benchmark file-choosers);
  _collect() force-builds unvisited tabs before saving so no field is missed.
- gtksettings: connection dot now sits left of the URL entry (like the Engines
  tab) instead of at the far right.
- gtkui: open_settings raises the existing dialog instead of opening a second.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 19:30:08 +02:00
27cf81de46 gtksettings: connection dots for the Wakeword (Wyoming) + TTS URLs; rename "Wyoming URI" to "Wakeword engine"; Release 1.9.0
Green/red/grey reachability dot next to the wakeword and TTS endpoint fields,
matching the existing STT/LLM engine dots. Lightweight background TCP probe,
refreshed on open, on reload (⟳), and on focus-out — never blocks dialog build.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 19:15:29 +02:00