fix(ui): release modal grab after TinyDiarize download before transcript opens (#965)

* fix(ui): release modal grab after TinyDiarize download before transcript opens

The transcribe path's ModelDownloadDialog is modal. On success it stayed
open behind the diarized transcript dialog, holding its grab so every
button on the transcript was unclickable until the hidden dialog was
found and closed. Destroy it on success there and let the transcript be
the completion affordance; the failure path still keeps the dialog up to
show the error.

* style(tests): black-format new dialog-grab tests

* fix(ui): stop download dialog pulse timer on destroy; type test helper

* style(ui): type destroy-handler varargs

---------

Co-authored-by: Jatin K Malik <jatinkrmalik@gmail.com>
This commit is contained in:
devin-ai-integration[bot]
2026-10-16 20:24:06 -07:00
committed by GitHub
co-authored by Jatin K Malik
parent 6c3a905825
commit 2ec92bade7
3 changed files with 53 additions and 3 deletions
+7
View File
@@ -2507,10 +2507,17 @@ class ModelDownloadDialog(Gtk.Dialog):
self.show_all()
self._pulse_timeout = None
# A destroyed dialog must not leave its pulse timer firing: the
# timeout retains the widget and keeps calling back into it.
self.connect("destroy", self._on_destroy)
# For Whisper, we can't track progress, so pulse
if engine == "whisper":
self._start_pulsing()
def _on_destroy(self, *_args: object) -> None:
"""Stop the pulse timer when the dialog goes away."""
self._stop_pulsing()
def _start_pulsing(self) -> None:
"""Bounce the bar, for work that reports no measurable progress."""
if self._pulse_timeout is None:
+5 -3
View File
@@ -1131,9 +1131,11 @@ class TrayIndicator:
self.speech_engine.set_download_progress_callback(None)
self.speech_engine.end_download()
GLib.idle_add(dialog.set_complete, True, "")
# The dialog shows its own completion; starting the transcription
# as soon as the model lands keeps the flow to a single click.
# The transcript dialog that opens next is the completion
# affordance here: the download dialog is modal, so leaving it
# open behind the transcript keeps its grab and makes the
# transcript's buttons unclickable until it is found and closed.
GLib.idle_add(dialog.destroy)
_idle_once(self._start_file_transcription, path)
threading.Thread(target=run, daemon=True, name="tdrz-download").start()