diff --git a/src/vocalinux/speech_recognition/recognition_manager.py b/src/vocalinux/speech_recognition/recognition_manager.py index fe62667..25660e6 100644 --- a/src/vocalinux/speech_recognition/recognition_manager.py +++ b/src/vocalinux/speech_recognition/recognition_manager.py @@ -2073,6 +2073,15 @@ class SpeechRecognitionManager: if restart_needed: logger.info("Engine or model changed, re-initializing...") + + # Stop any active recognition before switching engines. + # This is critical to prevent segfaults when the old engine's + # native resources (e.g. whisper.cpp C model) are freed while + # a background thread is still using them. + if self.state != RecognitionState.IDLE: + logger.info("Stopping active recognition before engine switch...") + self.stop_recognition() + # When reconfiguring from UI, allow downloads old_defer = self._defer_download self._defer_download = not force_download diff --git a/src/vocalinux/ui/settings_dialog.py b/src/vocalinux/ui/settings_dialog.py index 8aa870a..8797728 100644 --- a/src/vocalinux/ui/settings_dialog.py +++ b/src/vocalinux/ui/settings_dialog.py @@ -1916,6 +1916,13 @@ class SettingsDialog(Gtk.Dialog): self.config_manager.update_speech_recognition_settings(settings) self.config_manager.save_settings() + + # Stop recognition before reconfiguring to avoid segfaults when + # switching between engines with native resources (e.g. whisper.cpp) + was_running = self.speech_engine.state != RecognitionState.IDLE + if was_running: + self.speech_engine.stop_recognition() + self.speech_engine.reconfigure(**settings) logger.info("Settings auto-applied successfully") except Exception as e: