Forward keypress bug fixed.
This commit is contained in:
@@ -4,5 +4,5 @@
|
|||||||
# Fenrir TTY screen reader
|
# Fenrir TTY screen reader
|
||||||
# By Chrys, Storm Dragon, and contributors.
|
# By Chrys, Storm Dragon, and contributors.
|
||||||
|
|
||||||
version = "2026.05.13"
|
version = "2026.05.14"
|
||||||
code_name = "testing"
|
code_name = "testing"
|
||||||
|
|||||||
@@ -426,10 +426,13 @@ class driver(inputDriver):
|
|||||||
return names
|
return names
|
||||||
|
|
||||||
def keysym_to_name(self, keysym):
|
def keysym_to_name(self, keysym):
|
||||||
keysym_name = XK.keysym_to_string(keysym)
|
keysym_name = KEYSYM_NAME_MAP.get(keysym)
|
||||||
if keysym_name:
|
if keysym_name and keysym >= 0xFF00:
|
||||||
return keysym_name
|
return keysym_name
|
||||||
return KEYSYM_NAME_MAP.get(keysym)
|
keysym_string = XK.keysym_to_string(keysym)
|
||||||
|
if keysym_string:
|
||||||
|
return keysym_string
|
||||||
|
return keysym_name
|
||||||
|
|
||||||
def keysym_name_to_key_name(self, keysym_name):
|
def keysym_name_to_key_name(self, keysym_name):
|
||||||
if not keysym_name:
|
if not keysym_name:
|
||||||
|
|||||||
@@ -351,7 +351,7 @@ class driver(screenDriver):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def synthesize_backspace_shortcut(self, msg_bytes, event_queue):
|
def synthesize_backspace_shortcut(self, msg_bytes, event_queue):
|
||||||
if msg_bytes not in [b"\x7f", b"\x08"]:
|
if not self.is_backspace_shortcut_sequence(msg_bytes):
|
||||||
return False
|
return False
|
||||||
if "KEY_FENRIR" not in self.env["input"]["curr_input"]:
|
if "KEY_FENRIR" not in self.env["input"]["curr_input"]:
|
||||||
return False
|
return False
|
||||||
@@ -380,6 +380,27 @@ class driver(screenDriver):
|
|||||||
)
|
)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def is_backspace_shortcut_sequence(self, msg_bytes):
|
||||||
|
if msg_bytes in [b"\x7f", b"\x08"]:
|
||||||
|
return True
|
||||||
|
try:
|
||||||
|
sequence = msg_bytes.decode("ascii")
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
return False
|
||||||
|
if not sequence.startswith("\x1b["):
|
||||||
|
return False
|
||||||
|
if sequence.endswith("~"):
|
||||||
|
parts = sequence[2:-1].split(";")
|
||||||
|
if parts[0] == "3":
|
||||||
|
return True
|
||||||
|
if parts[0] == "27" and parts[-1] in ["8", "127"]:
|
||||||
|
return True
|
||||||
|
elif sequence.endswith("u"):
|
||||||
|
parts = sequence[2:-1].split(";")
|
||||||
|
if parts[0] in ["8", "127"]:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def get_session_information(self):
|
def get_session_information(self):
|
||||||
self.env["screen"]["autoIgnoreScreens"] = []
|
self.env["screen"]["autoIgnoreScreens"] = []
|
||||||
self.env["general"]["prev_user"] = getpass.getuser()
|
self.env["general"]["prev_user"] = getpass.getuser()
|
||||||
|
|||||||
@@ -217,6 +217,35 @@ def test_pty_backspace_with_fenrir_key_synthesizes_shortcut_events():
|
|||||||
assert second_event["data"]["event_state"] == 0
|
assert second_event["data"]["event_state"] == 0
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.unit
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"sequence",
|
||||||
|
[
|
||||||
|
b"\x08",
|
||||||
|
b"\x1b[3~",
|
||||||
|
b"\x1b[3;5~",
|
||||||
|
b"\x1b[27;5;8~",
|
||||||
|
b"\x1b[27;5;127~",
|
||||||
|
b"\x1b[8;5u",
|
||||||
|
b"\x1b[127;5u",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_pty_xterm_backspace_variants_with_fenrir_key_synthesize_shortcut_events(
|
||||||
|
sequence,
|
||||||
|
):
|
||||||
|
pty_driver = PtyDriver()
|
||||||
|
event_queue = Mock()
|
||||||
|
pty_driver.env = {
|
||||||
|
"input": {"curr_input": ["KEY_FENRIR"]},
|
||||||
|
}
|
||||||
|
|
||||||
|
handled = pty_driver.synthesize_backspace_shortcut(sequence, event_queue)
|
||||||
|
|
||||||
|
assert handled is True
|
||||||
|
first_event = event_queue.put.call_args_list[0].args[0]
|
||||||
|
assert first_event["data"]["event_name"] == "KEY_BACKSPACE"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.unit
|
@pytest.mark.unit
|
||||||
def test_pty_plain_backspace_is_not_synthesized():
|
def test_pty_plain_backspace_is_not_synthesized():
|
||||||
pty_driver = PtyDriver()
|
pty_driver = PtyDriver()
|
||||||
@@ -229,3 +258,17 @@ def test_pty_plain_backspace_is_not_synthesized():
|
|||||||
|
|
||||||
assert handled is False
|
assert handled is False
|
||||||
event_queue.put.assert_not_called()
|
event_queue.put.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.unit
|
||||||
|
def test_pty_plain_delete_sequence_is_not_synthesized():
|
||||||
|
pty_driver = PtyDriver()
|
||||||
|
event_queue = Mock()
|
||||||
|
pty_driver.env = {
|
||||||
|
"input": {"curr_input": []},
|
||||||
|
}
|
||||||
|
|
||||||
|
handled = pty_driver.synthesize_backspace_shortcut(b"\x1b[3~", event_queue)
|
||||||
|
|
||||||
|
assert handled is False
|
||||||
|
event_queue.put.assert_not_called()
|
||||||
|
|||||||
@@ -85,6 +85,25 @@ def test_x11_key_name_mapping_for_keypad_and_capslock():
|
|||||||
assert x11.keysym_name_to_key_name("_") == "KEY_MINUS"
|
assert x11.keysym_name_to_key_name("_") == "KEY_MINUS"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.unit
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("keysym_name", "key_name"),
|
||||||
|
[
|
||||||
|
("BackSpace", "KEY_BACKSPACE"),
|
||||||
|
("Tab", "KEY_TAB"),
|
||||||
|
("Return", "KEY_ENTER"),
|
||||||
|
("Escape", "KEY_ESC"),
|
||||||
|
("Delete", "KEY_DELETE"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_x11_special_keysyms_use_symbolic_names(keysym_name, key_name):
|
||||||
|
x11 = X11Driver()
|
||||||
|
resolved_name = x11.keysym_to_name(XK.string_to_keysym(keysym_name))
|
||||||
|
|
||||||
|
assert resolved_name == keysym_name
|
||||||
|
assert x11.keysym_name_to_key_name(resolved_name) == key_name
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.unit
|
@pytest.mark.unit
|
||||||
def test_x11_keycode_mapping_prefers_keypad_aliases():
|
def test_x11_keycode_mapping_prefers_keypad_aliases():
|
||||||
x11 = X11Driver()
|
x11 = X11Driver()
|
||||||
|
|||||||
Reference in New Issue
Block a user