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:
co-authored by
Jatin K Malik
parent
6c3a905825
commit
2ec92bade7
@@ -1166,3 +1166,44 @@ class TestAppIndicatorImportFallback(unittest.TestCase):
|
||||
import vocalinux.ui.tray_indicator as tray
|
||||
|
||||
self.assertIs(tray.AppIndicator3, sentinel)
|
||||
|
||||
|
||||
class TestTdrzDownloadDialog(TestTrayIndicator):
|
||||
"""The transcribe-path TinyDiarize download dialog must release its modal
|
||||
grab once the model lands: the transcript dialog opening behind it would
|
||||
otherwise be unclickable until the hidden dialog is found and closed."""
|
||||
|
||||
def _run_download(
|
||||
self, download_side_effect: Exception | None = None
|
||||
) -> tuple[MagicMock, MagicMock]:
|
||||
from vocalinux.ui.tray_indicator import Gtk
|
||||
|
||||
mock_prompt = MagicMock()
|
||||
mock_prompt.run.return_value = Gtk.ResponseType.OK
|
||||
mock_dialog = MagicMock()
|
||||
mock_dialog.cancelled = False
|
||||
self.mock_speech_engine.try_begin_download.return_value = True
|
||||
self.mock_speech_engine.download_whispercpp_model.side_effect = download_side_effect
|
||||
|
||||
with (
|
||||
patch("vocalinux.ui.tray_indicator.Gtk.MessageDialog", return_value=mock_prompt),
|
||||
patch("vocalinux.ui.tray_indicator.ModelDownloadDialog", return_value=mock_dialog),
|
||||
patch.object(self.tray_indicator, "_start_file_transcription") as mock_start,
|
||||
):
|
||||
self.tray_indicator._offer_tdrz_download("/tmp/clip.wav")
|
||||
run = self.mock_thread_class.call_args.kwargs["target"]
|
||||
run()
|
||||
return mock_dialog, mock_start
|
||||
|
||||
def test_success_destroys_modal_dialog(self) -> None:
|
||||
mock_dialog, mock_start = self._run_download()
|
||||
mock_dialog.destroy.assert_called_once()
|
||||
mock_dialog.set_complete.assert_not_called()
|
||||
mock_start.assert_called_once_with("/tmp/clip.wav")
|
||||
|
||||
def test_failure_keeps_dialog_for_the_error(self) -> None:
|
||||
mock_dialog, mock_start = self._run_download(Exception("network down"))
|
||||
mock_dialog.set_complete.assert_called_once()
|
||||
self.assertFalse(mock_dialog.set_complete.call_args[0][0])
|
||||
mock_dialog.destroy.assert_not_called()
|
||||
mock_start.assert_not_called()
|
||||
|
||||
Reference in New Issue
Block a user