diff --git a/src/fenrirscreenreader/core/speechHistoryManager.py b/src/fenrirscreenreader/core/speechHistoryManager.py index 5fa82fb9..4e62ad4d 100644 --- a/src/fenrirscreenreader/core/speechHistoryManager.py +++ b/src/fenrirscreenreader/core/speechHistoryManager.py @@ -172,6 +172,7 @@ class SpeechHistoryManager: str([1, ["KEY_KPENTER"]]): [1, ["KEY_KPENTER"]], str([1, ["KEY_ESC"]]): [1, ["KEY_ESC"]], } + self._refresh_input_bindings() def _restore_bindings(self): if self.bindings_backup is not None: @@ -180,3 +181,21 @@ class SpeechHistoryManager: self.env["rawBindings"] = self.raw_bindings_backup self.bindings_backup = None self.raw_bindings_backup = None + self._reset_input_state() + self._refresh_input_bindings() + + def _reset_input_state(self): + try: + self.env["runtime"]["InputManager"].reset_input_state() + except Exception: + pass + + def _refresh_input_bindings(self): + try: + refresh_grabs = getattr( + self.env["runtime"]["InputDriver"], "refresh_grabs", None + ) + if refresh_grabs: + refresh_grabs(force=True) + except Exception: + pass diff --git a/tests/unit/test_speech_history_manager.py b/tests/unit/test_speech_history_manager.py index 18a432d8..1a570ebe 100644 --- a/tests/unit/test_speech_history_manager.py +++ b/tests/unit/test_speech_history_manager.py @@ -16,11 +16,15 @@ def build_speech_history_manager(history_size=3): settings_manager = Mock() settings_manager.get_setting_as_int.return_value = history_size memory_manager = Mock(add_value_to_first_index=Mock()) + input_manager = Mock(reset_input_state=Mock()) + input_driver = Mock(refresh_grabs=Mock()) env = { "runtime": { "OutputManager": output_manager, "SettingsManager": settings_manager, "MemoryManager": memory_manager, + "InputManager": input_manager, + "InputDriver": input_driver, }, "bindings": {"original": "COMMAND"}, "rawBindings": {"original": [1, ["KEY_FENRIR"]]}, @@ -105,6 +109,8 @@ def test_open_history_installs_modal_bindings_and_replay_is_not_recorded(): assert env["bindings"][str([1, ["KEY_UP"]])] == "SPEECH_HISTORY_PREV" assert env["bindings"][str([1, ["KEY_ENTER"]])] == "SPEECH_HISTORY_COPY" assert env["bindings"][str([1, ["KEY_ESC"]])] == "SPEECH_HISTORY_CLOSE" + input_driver = env["runtime"]["InputDriver"] + input_driver.refresh_grabs.assert_called_once_with(force=True) @pytest.mark.unit @@ -145,3 +151,22 @@ def test_copy_current_adds_clipboard_and_restores_bindings(): assert not manager.is_active() assert env["bindings"] == {"original": "COMMAND"} assert env["rawBindings"] == {"original": [1, ["KEY_FENRIR"]]} + env["runtime"]["InputManager"].reset_input_state.assert_called_once_with() + assert env["runtime"]["InputDriver"].refresh_grabs.call_count == 2 + + +@pytest.mark.unit +def test_close_history_restores_keyboard_state_and_grabs(): + manager, env, _spoken_messages, _memory_manager = ( + build_speech_history_manager() + ) + manager.add_text("first") + manager.open_history() + + manager.close_history() + + assert not manager.is_active() + assert env["bindings"] == {"original": "COMMAND"} + assert env["rawBindings"] == {"original": [1, ["KEY_FENRIR"]]} + env["runtime"]["InputManager"].reset_input_state.assert_called_once_with() + assert env["runtime"]["InputDriver"].refresh_grabs.call_count == 2