Improve review spelling shortcuts
This commit is contained in:
@@ -15,15 +15,12 @@ KEY_FENRIR,KEY_ALT,KEY_2=present_last_line
|
|||||||
KEY_KP5=review_curr_word
|
KEY_KP5=review_curr_word
|
||||||
KEY_KP4=review_prev_word
|
KEY_KP4=review_prev_word
|
||||||
KEY_KP6=review_next_word
|
KEY_KP6=review_next_word
|
||||||
KEY_FENRIR,KEY_SHIFT,KEY_KP5=review_curr_word_phonetic
|
2,KEY_KP5=review_curr_word_spell
|
||||||
KEY_FENRIR,KEY_SHIFT,KEY_KP4=review_prev_word_phonetic
|
3,KEY_KP5=review_curr_word_phonetic
|
||||||
KEY_FENRIR,KEY_SHIFT,KEY_KP6=review_next_word_phonetic
|
|
||||||
KEY_KP2=review_curr_char
|
KEY_KP2=review_curr_char
|
||||||
KEY_KP1=review_prev_char
|
KEY_KP1=review_prev_char
|
||||||
KEY_KP3=review_next_char
|
KEY_KP3=review_next_char
|
||||||
KEY_FENRIR,KEY_SHIFT,KEY_KP2=review_curr_char_phonetic
|
2,KEY_KP2=review_curr_char_phonetic
|
||||||
KEY_FENRIR,KEY_SHIFT,KEY_KP1=review_prev_char_phonetic
|
|
||||||
KEY_FENRIR,KEY_SHIFT,KEY_KP3=review_next_char_phonetic
|
|
||||||
KEY_FENRIR,KEY_CTRL,KEY_KP8=review_up
|
KEY_FENRIR,KEY_CTRL,KEY_KP8=review_up
|
||||||
KEY_FENRIR,KEY_CTRL,KEY_KP2=review_down
|
KEY_FENRIR,KEY_CTRL,KEY_KP2=review_down
|
||||||
KEY_FENRIR,KEY_KPDOT=exit_review
|
KEY_FENRIR,KEY_KPDOT=exit_review
|
||||||
|
|||||||
@@ -15,15 +15,12 @@ KEY_FENRIR,KEY_ALT,KEY_2=present_last_line
|
|||||||
KEY_FENRIR,KEY_K=review_curr_word
|
KEY_FENRIR,KEY_K=review_curr_word
|
||||||
KEY_FENRIR,KEY_J=review_prev_word
|
KEY_FENRIR,KEY_J=review_prev_word
|
||||||
KEY_FENRIR,KEY_L=review_next_word
|
KEY_FENRIR,KEY_L=review_next_word
|
||||||
KEY_FENRIR,KEY_ALT,KEY_K=review_curr_word_phonetic
|
2,KEY_FENRIR,KEY_K=review_curr_word_spell
|
||||||
KEY_FENRIR,KEY_ALT,KEY_J=review_prev_word_phonetic
|
3,KEY_FENRIR,KEY_K=review_curr_word_phonetic
|
||||||
KEY_FENRIR,KEY_ALT,KEY_L=review_next_word_phonetic
|
|
||||||
KEY_FENRIR,KEY_COMMA=review_curr_char
|
KEY_FENRIR,KEY_COMMA=review_curr_char
|
||||||
KEY_FENRIR,KEY_M=review_prev_char
|
KEY_FENRIR,KEY_M=review_prev_char
|
||||||
KEY_FENRIR,KEY_DOT=review_next_char
|
KEY_FENRIR,KEY_DOT=review_next_char
|
||||||
KEY_FENRIR,KEY_ALT,KEY_COMMA=curr_char_phonetic
|
2,KEY_FENRIR,KEY_COMMA=review_curr_char_phonetic
|
||||||
KEY_FENRIR,KEY_ALT,KEY_M=prev_char_phonetic
|
|
||||||
KEY_FENRIR,KEY_ALT,KEY_DOT=next_char_phonetic
|
|
||||||
KEY_FENRIR,KEY_CTRL,KEY_I=review_up
|
KEY_FENRIR,KEY_CTRL,KEY_I=review_up
|
||||||
KEY_FENRIR,KEY_CTRL,KEY_COMMA=review_down
|
KEY_FENRIR,KEY_CTRL,KEY_COMMA=review_down
|
||||||
KEY_FENRIR,KEY_SLASH=exit_review
|
KEY_FENRIR,KEY_SLASH=exit_review
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class command:
|
|||||||
self.env["screen"]["new_content_text"],
|
self.env["screen"]["new_content_text"],
|
||||||
)
|
)
|
||||||
|
|
||||||
if curr_word.isspace():
|
if not curr_word or curr_word.isspace():
|
||||||
self.env["runtime"]["OutputManager"].present_text(
|
self.env["runtime"]["OutputManager"].present_text(
|
||||||
_("blank"), interrupt=True, flush=False
|
_("blank"), interrupt=True, flush=False
|
||||||
)
|
)
|
||||||
|
|||||||
+8
-10
@@ -20,7 +20,7 @@ class command:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def get_description(self):
|
def get_description(self):
|
||||||
return _("Phonetically spells the next word and moves review to it")
|
return _("Spells the current word")
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self.env["runtime"][
|
self.env["runtime"][
|
||||||
@@ -29,30 +29,28 @@ class command:
|
|||||||
(
|
(
|
||||||
self.env["screen"]["newCursorReview"]["x"],
|
self.env["screen"]["newCursorReview"]["x"],
|
||||||
self.env["screen"]["newCursorReview"]["y"],
|
self.env["screen"]["newCursorReview"]["y"],
|
||||||
next_word,
|
curr_word,
|
||||||
end_of_screen,
|
end_of_screen,
|
||||||
line_break,
|
line_break,
|
||||||
) = word_utils.get_next_word(
|
) = word_utils.get_current_word(
|
||||||
self.env["screen"]["newCursorReview"]["x"],
|
self.env["screen"]["newCursorReview"]["x"],
|
||||||
self.env["screen"]["newCursorReview"]["y"],
|
self.env["screen"]["newCursorReview"]["y"],
|
||||||
self.env["screen"]["new_content_text"],
|
self.env["screen"]["new_content_text"],
|
||||||
)
|
)
|
||||||
|
|
||||||
if next_word.isspace():
|
if not curr_word or curr_word.isspace():
|
||||||
self.env["runtime"]["OutputManager"].present_text(
|
self.env["runtime"]["OutputManager"].present_text(
|
||||||
_("blank"), interrupt=True, flush=False
|
_("blank"), interrupt=True, flush=False
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
first_sequence = True
|
for index, curr_char in enumerate(curr_word):
|
||||||
for c in next_word:
|
char_utils.present_char_for_review(
|
||||||
curr_char = char_utils.get_phonetic(c)
|
self.env,
|
||||||
self.env["runtime"]["OutputManager"].present_text(
|
|
||||||
curr_char,
|
curr_char,
|
||||||
interrupt=first_sequence,
|
interrupt=index == 0,
|
||||||
announce_capital=True,
|
announce_capital=True,
|
||||||
flush=False,
|
flush=False,
|
||||||
)
|
)
|
||||||
first_sequence = False
|
|
||||||
if end_of_screen:
|
if end_of_screen:
|
||||||
if self.env["runtime"]["SettingsManager"].get_setting_as_bool(
|
if self.env["runtime"]["SettingsManager"].get_setting_as_bool(
|
||||||
"review", "end_of_screen"
|
"review", "end_of_screen"
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Fenrir TTY screen reader
|
|
||||||
# By Chrys, Storm Dragon, and contributors.
|
|
||||||
|
|
||||||
from fenrirscreenreader.core.i18n import _
|
|
||||||
from fenrirscreenreader.utils import char_utils
|
|
||||||
|
|
||||||
|
|
||||||
class command:
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def initialize(self, environment):
|
|
||||||
self.env = environment
|
|
||||||
|
|
||||||
def shutdown(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_description(self):
|
|
||||||
return _(
|
|
||||||
"phonetically presents the next character and set review to it"
|
|
||||||
)
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
self.env["runtime"][
|
|
||||||
"CursorManager"
|
|
||||||
].enter_review_mode_curr_text_cursor()
|
|
||||||
|
|
||||||
(
|
|
||||||
self.env["screen"]["newCursorReview"]["x"],
|
|
||||||
self.env["screen"]["newCursorReview"]["y"],
|
|
||||||
next_char,
|
|
||||||
end_of_screen,
|
|
||||||
line_break,
|
|
||||||
) = char_utils.get_next_char(
|
|
||||||
self.env["screen"]["newCursorReview"]["x"],
|
|
||||||
self.env["screen"]["newCursorReview"]["y"],
|
|
||||||
self.env["screen"]["new_content_text"],
|
|
||||||
)
|
|
||||||
|
|
||||||
next_char = char_utils.get_phonetic(next_char)
|
|
||||||
self.env["runtime"]["OutputManager"].present_text(
|
|
||||||
next_char, interrupt=True, announce_capital=True, flush=False
|
|
||||||
)
|
|
||||||
if end_of_screen:
|
|
||||||
if self.env["runtime"]["SettingsManager"].get_setting_as_bool(
|
|
||||||
"review", "end_of_screen"
|
|
||||||
):
|
|
||||||
self.env["runtime"]["OutputManager"].present_text(
|
|
||||||
_("end of screen"),
|
|
||||||
interrupt=True,
|
|
||||||
sound_icon="EndOfScreen",
|
|
||||||
)
|
|
||||||
if line_break:
|
|
||||||
if self.env["runtime"]["SettingsManager"].get_setting_as_bool(
|
|
||||||
"review", "line_break"
|
|
||||||
):
|
|
||||||
self.env["runtime"]["OutputManager"].present_text(
|
|
||||||
_("line break"), interrupt=False, sound_icon="EndOfLine"
|
|
||||||
)
|
|
||||||
|
|
||||||
def set_callback(self, callback):
|
|
||||||
pass
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Fenrir TTY screen reader
|
|
||||||
# By Chrys, Storm Dragon, and contributors.
|
|
||||||
|
|
||||||
from fenrirscreenreader.core.i18n import _
|
|
||||||
from fenrirscreenreader.utils import char_utils
|
|
||||||
|
|
||||||
|
|
||||||
class command:
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def initialize(self, environment):
|
|
||||||
self.env = environment
|
|
||||||
|
|
||||||
def shutdown(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_description(self):
|
|
||||||
return _(
|
|
||||||
"phonetically presents the previous character and set review to it"
|
|
||||||
)
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
self.env["runtime"][
|
|
||||||
"CursorManager"
|
|
||||||
].enter_review_mode_curr_text_cursor()
|
|
||||||
|
|
||||||
(
|
|
||||||
self.env["screen"]["newCursorReview"]["x"],
|
|
||||||
self.env["screen"]["newCursorReview"]["y"],
|
|
||||||
prev_char,
|
|
||||||
end_of_screen,
|
|
||||||
line_break,
|
|
||||||
) = char_utils.get_prev_char(
|
|
||||||
self.env["screen"]["newCursorReview"]["x"],
|
|
||||||
self.env["screen"]["newCursorReview"]["y"],
|
|
||||||
self.env["screen"]["new_content_text"],
|
|
||||||
)
|
|
||||||
|
|
||||||
prev_char = char_utils.get_phonetic(prev_char)
|
|
||||||
self.env["runtime"]["OutputManager"].present_text(
|
|
||||||
prev_char, interrupt=True, announce_capital=True, flush=False
|
|
||||||
)
|
|
||||||
if end_of_screen:
|
|
||||||
if self.env["runtime"]["SettingsManager"].get_setting_as_bool(
|
|
||||||
"review", "end_of_screen"
|
|
||||||
):
|
|
||||||
self.env["runtime"]["OutputManager"].present_text(
|
|
||||||
_("start of screen"),
|
|
||||||
interrupt=True,
|
|
||||||
sound_icon="StartOfScreen",
|
|
||||||
)
|
|
||||||
if line_break:
|
|
||||||
if self.env["runtime"]["SettingsManager"].get_setting_as_bool(
|
|
||||||
"review", "line_break"
|
|
||||||
):
|
|
||||||
self.env["runtime"]["OutputManager"].present_text(
|
|
||||||
_("line break"), interrupt=False, sound_icon="EndOfLine"
|
|
||||||
)
|
|
||||||
|
|
||||||
def set_callback(self, callback):
|
|
||||||
pass
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Fenrir TTY screen reader
|
|
||||||
# By Chrys, Storm Dragon, and contributors.
|
|
||||||
|
|
||||||
from fenrirscreenreader.core.i18n import _
|
|
||||||
from fenrirscreenreader.utils import char_utils
|
|
||||||
from fenrirscreenreader.utils import word_utils
|
|
||||||
|
|
||||||
|
|
||||||
class command:
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def initialize(self, environment):
|
|
||||||
self.env = environment
|
|
||||||
|
|
||||||
def shutdown(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_description(self):
|
|
||||||
return _(
|
|
||||||
"Phonetically spells the previous word and moves review to it"
|
|
||||||
)
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
self.env["runtime"][
|
|
||||||
"CursorManager"
|
|
||||||
].enter_review_mode_curr_text_cursor()
|
|
||||||
(
|
|
||||||
self.env["screen"]["newCursorReview"]["x"],
|
|
||||||
self.env["screen"]["newCursorReview"]["y"],
|
|
||||||
prev_word,
|
|
||||||
end_of_screen,
|
|
||||||
line_break,
|
|
||||||
) = word_utils.get_prev_word(
|
|
||||||
self.env["screen"]["newCursorReview"]["x"],
|
|
||||||
self.env["screen"]["newCursorReview"]["y"],
|
|
||||||
self.env["screen"]["new_content_text"],
|
|
||||||
)
|
|
||||||
|
|
||||||
if prev_word.isspace():
|
|
||||||
self.env["runtime"]["OutputManager"].present_text(
|
|
||||||
_("blank"), interrupt=True, flush=False
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
first_sequence = True
|
|
||||||
for c in prev_word:
|
|
||||||
curr_char = char_utils.get_phonetic(c)
|
|
||||||
self.env["runtime"]["OutputManager"].present_text(
|
|
||||||
curr_char,
|
|
||||||
interrupt=first_sequence,
|
|
||||||
announce_capital=True,
|
|
||||||
flush=False,
|
|
||||||
)
|
|
||||||
first_sequence = False
|
|
||||||
if end_of_screen:
|
|
||||||
if self.env["runtime"]["SettingsManager"].get_setting_as_bool(
|
|
||||||
"review", "end_of_screen"
|
|
||||||
):
|
|
||||||
self.env["runtime"]["OutputManager"].present_text(
|
|
||||||
_("start of screen"),
|
|
||||||
interrupt=True,
|
|
||||||
sound_icon="StartOfScreen",
|
|
||||||
)
|
|
||||||
if line_break:
|
|
||||||
if self.env["runtime"]["SettingsManager"].get_setting_as_bool(
|
|
||||||
"review", "line_break"
|
|
||||||
):
|
|
||||||
self.env["runtime"]["OutputManager"].present_text(
|
|
||||||
_("line break"), interrupt=False, sound_icon="EndOfLine"
|
|
||||||
)
|
|
||||||
|
|
||||||
def set_callback(self, callback):
|
|
||||||
pass
|
|
||||||
@@ -82,9 +82,6 @@ class FenrirManager:
|
|||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.environment["runtime"]["InputManager"].no_key_pressed():
|
|
||||||
self.environment["runtime"]["InputManager"].clear_last_deep_input()
|
|
||||||
|
|
||||||
if self.environment["runtime"]["ScreenManager"].is_ignored_screen():
|
if self.environment["runtime"]["ScreenManager"].is_ignored_screen():
|
||||||
self.environment["runtime"]["InputManager"].write_event_buffer()
|
self.environment["runtime"]["InputManager"].write_event_buffer()
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -196,8 +196,6 @@ class InputManager:
|
|||||||
self.env["input"]["curr_input"] = sorted(
|
self.env["input"]["curr_input"] = sorted(
|
||||||
self.env["input"]["curr_input"]
|
self.env["input"]["curr_input"]
|
||||||
)
|
)
|
||||||
elif len(self.env["input"]["curr_input"]) == 0:
|
|
||||||
self.env["input"]["shortcut_repeat"] = 1
|
|
||||||
self.lastInputTime = time.time()
|
self.lastInputTime = time.time()
|
||||||
elif event_data["event_state"] == 1:
|
elif event_data["event_state"] == 1:
|
||||||
if not event_data["event_name"] in self.env["input"]["curr_input"]:
|
if not event_data["event_name"] in self.env["input"]["curr_input"]:
|
||||||
@@ -206,19 +204,18 @@ class InputManager:
|
|||||||
self.env["input"]["curr_input"] = sorted(
|
self.env["input"]["curr_input"] = sorted(
|
||||||
self.env["input"]["curr_input"]
|
self.env["input"]["curr_input"]
|
||||||
)
|
)
|
||||||
if len(self.lastDeepestInput) < len(
|
if self.lastDeepestInput == self.env["input"]["curr_input"]:
|
||||||
self.env["input"]["curr_input"]
|
|
||||||
):
|
|
||||||
self.set_last_deepest_input(
|
|
||||||
self.env["input"]["curr_input"].copy()
|
|
||||||
)
|
|
||||||
elif self.lastDeepestInput == self.env["input"]["curr_input"]:
|
|
||||||
if time.time() - self.lastInputTime <= self.env["runtime"][
|
if time.time() - self.lastInputTime <= self.env["runtime"][
|
||||||
"SettingsManager"
|
"SettingsManager"
|
||||||
].get_setting_as_float("keyboard", "double_tap_timeout"):
|
].get_setting_as_float("keyboard", "double_tap_timeout"):
|
||||||
self.env["input"]["shortcut_repeat"] += 1
|
self.env["input"]["shortcut_repeat"] += 1
|
||||||
else:
|
else:
|
||||||
self.env["input"]["shortcut_repeat"] = 1
|
self.env["input"]["shortcut_repeat"] = 1
|
||||||
|
else:
|
||||||
|
self.env["input"]["shortcut_repeat"] = 1
|
||||||
|
self.set_last_deepest_input(
|
||||||
|
self.env["input"]["curr_input"].copy()
|
||||||
|
)
|
||||||
self.handle_led_states(event_data)
|
self.handle_led_states(event_data)
|
||||||
self.lastInputTime = time.time()
|
self.lastInputTime = time.time()
|
||||||
elif event_data["event_state"] == 2:
|
elif event_data["event_state"] == 2:
|
||||||
|
|||||||
@@ -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.08.12"
|
version = "2026.08.13"
|
||||||
code_name = "testing"
|
code_name = "testing"
|
||||||
|
|||||||
@@ -172,6 +172,7 @@ class driver(inputDriver):
|
|||||||
self.modifier_interrupt_state = 0
|
self.modifier_interrupt_state = 0
|
||||||
self.command_key_active = False
|
self.command_key_active = False
|
||||||
self.chord_modifiers = set()
|
self.chord_modifiers = set()
|
||||||
|
self.chord_keys = set()
|
||||||
|
|
||||||
def initialize(self, environment):
|
def initialize(self, environment):
|
||||||
self.env = environment
|
self.env = environment
|
||||||
@@ -306,6 +307,10 @@ class driver(inputDriver):
|
|||||||
|
|
||||||
def handle_x_event(self, event, event_queue):
|
def handle_x_event(self, event, event_queue):
|
||||||
event_type = getattr(event, "type", None)
|
event_type = getattr(event, "type", None)
|
||||||
|
if event_type in [X.FocusIn, X.FocusOut] and getattr(
|
||||||
|
event, "mode", X.NotifyNormal
|
||||||
|
) in [X.NotifyGrab, X.NotifyUngrab]:
|
||||||
|
return
|
||||||
if event_type == X.FocusIn:
|
if event_type == X.FocusIn:
|
||||||
self.active = True
|
self.active = True
|
||||||
self.clear_event_buffer()
|
self.clear_event_buffer()
|
||||||
@@ -329,6 +334,7 @@ class driver(inputDriver):
|
|||||||
if is_command_key and input_event["event_state"] == 1:
|
if is_command_key and input_event["event_state"] == 1:
|
||||||
self.start_command_chord(input_event, event_queue)
|
self.start_command_chord(input_event, event_queue)
|
||||||
elif self.command_key_active and not is_command_key:
|
elif self.command_key_active and not is_command_key:
|
||||||
|
self.track_chord_key(input_event)
|
||||||
self.track_chord_modifier(input_event)
|
self.track_chord_modifier(input_event)
|
||||||
self.write_debug(
|
self.write_debug(
|
||||||
"x11Driver key event "
|
"x11Driver key event "
|
||||||
@@ -361,6 +367,7 @@ class driver(inputDriver):
|
|||||||
|
|
||||||
def start_command_chord(self, input_event, event_queue):
|
def start_command_chord(self, input_event, event_queue):
|
||||||
self.command_key_active = True
|
self.command_key_active = True
|
||||||
|
self.chord_keys.clear()
|
||||||
raw_state = input_event.get("event_raw_state", 0)
|
raw_state = input_event.get("event_raw_state", 0)
|
||||||
current_input = self.env["input"]["curr_input"]
|
current_input = self.env["input"]["curr_input"]
|
||||||
for key_name, modifier_mask in self.canonical_modifier_masks:
|
for key_name, modifier_mask in self.canonical_modifier_masks:
|
||||||
@@ -368,7 +375,7 @@ class driver(inputDriver):
|
|||||||
continue
|
continue
|
||||||
self.chord_modifiers.add(key_name)
|
self.chord_modifiers.add(key_name)
|
||||||
if key_name not in current_input:
|
if key_name not in current_input:
|
||||||
self.queue_synthetic_modifier(
|
self.queue_synthetic_key(
|
||||||
key_name, 1, input_event, event_queue
|
key_name, 1, input_event, event_queue
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -381,6 +388,15 @@ class driver(inputDriver):
|
|||||||
elif input_event["event_state"] == 0:
|
elif input_event["event_state"] == 0:
|
||||||
self.chord_modifiers.discard(key_name)
|
self.chord_modifiers.discard(key_name)
|
||||||
|
|
||||||
|
def track_chord_key(self, input_event):
|
||||||
|
key_name = input_event["event_name"]
|
||||||
|
if key_name in self.modifier_key_names:
|
||||||
|
return
|
||||||
|
if input_event["event_state"] == 1:
|
||||||
|
self.chord_keys.add(key_name)
|
||||||
|
elif input_event["event_state"] == 0:
|
||||||
|
self.chord_keys.discard(key_name)
|
||||||
|
|
||||||
def canonical_modifier_name(self, key_name):
|
def canonical_modifier_name(self, key_name):
|
||||||
modifier_mask = self.modifier_masks.get(key_name, 0)
|
modifier_mask = self.modifier_masks.get(key_name, 0)
|
||||||
for canonical_name, canonical_mask in self.canonical_modifier_masks:
|
for canonical_name, canonical_mask in self.canonical_modifier_masks:
|
||||||
@@ -389,12 +405,15 @@ class driver(inputDriver):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def finish_command_chord(self, input_event, event_queue):
|
def finish_command_chord(self, input_event, event_queue):
|
||||||
|
for key_name in sorted(self.chord_keys):
|
||||||
|
self.queue_synthetic_key(key_name, 0, input_event, event_queue)
|
||||||
|
self.chord_keys.clear()
|
||||||
for key_name in sorted(self.chord_modifiers):
|
for key_name in sorted(self.chord_modifiers):
|
||||||
self.queue_synthetic_modifier(key_name, 0, input_event, event_queue)
|
self.queue_synthetic_key(key_name, 0, input_event, event_queue)
|
||||||
self.chord_modifiers.clear()
|
self.chord_modifiers.clear()
|
||||||
self.command_key_active = False
|
self.command_key_active = False
|
||||||
|
|
||||||
def queue_synthetic_modifier(
|
def queue_synthetic_key(
|
||||||
self, key_name, event_state, source_event, event_queue
|
self, key_name, event_state, source_event, event_queue
|
||||||
):
|
):
|
||||||
synthetic_event = {
|
synthetic_event = {
|
||||||
@@ -781,6 +800,7 @@ class driver(inputDriver):
|
|||||||
def reset_input_state(self):
|
def reset_input_state(self):
|
||||||
self.command_key_active = False
|
self.command_key_active = False
|
||||||
self.chord_modifiers.clear()
|
self.chord_modifiers.clear()
|
||||||
|
self.chord_keys.clear()
|
||||||
try:
|
try:
|
||||||
self.env["runtime"]["InputManager"].reset_input_state()
|
self.env["runtime"]["InputManager"].reset_input_state()
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|||||||
@@ -7,6 +7,42 @@ from fenrirscreenreader.core.fenrirManager import FenrirManager
|
|||||||
from fenrirscreenreader.core.inputManager import InputManager
|
from fenrirscreenreader.core.inputManager import InputManager
|
||||||
|
|
||||||
|
|
||||||
|
def create_input_manager():
|
||||||
|
input_driver = Mock(get_led_state=Mock(return_value=False))
|
||||||
|
settings_manager = Mock()
|
||||||
|
settings_manager.get_setting_as_float.return_value = 0.2
|
||||||
|
manager = InputManager()
|
||||||
|
manager.env = {
|
||||||
|
"input": {
|
||||||
|
"curr_input": [],
|
||||||
|
"prev_input": [],
|
||||||
|
"event_buffer": [object()],
|
||||||
|
"shortcut_repeat": 1,
|
||||||
|
"old_num_lock": False,
|
||||||
|
"new_num_lock": False,
|
||||||
|
"old_caps_lock": False,
|
||||||
|
"new_caps_lock": False,
|
||||||
|
"old_scroll_lock": False,
|
||||||
|
"new_scroll_lock": False,
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"DebugManager": Mock(),
|
||||||
|
"InputDriver": input_driver,
|
||||||
|
"SettingsManager": settings_manager,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
manager.lastDeepestInput = []
|
||||||
|
manager.lastInputTime = 0
|
||||||
|
manager.handle_led_states = Mock()
|
||||||
|
return manager
|
||||||
|
|
||||||
|
|
||||||
|
def send_input(manager, event_name, event_state):
|
||||||
|
manager.handle_input_event(
|
||||||
|
{"event_name": event_name, "event_state": event_state}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_handle_input_manager(no_key_pressed):
|
def create_handle_input_manager(no_key_pressed):
|
||||||
manager = FenrirManager.__new__(FenrirManager)
|
manager = FenrirManager.__new__(FenrirManager)
|
||||||
manager.modifierInput = False
|
manager.modifierInput = False
|
||||||
@@ -48,6 +84,100 @@ def test_input_manager_recognizes_conventional_modifier_prefix():
|
|||||||
assert input_manager.curr_input_is_modifier_prefix() is False
|
assert input_manager.curr_input_is_modifier_prefix() is False
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.unit
|
||||||
|
def test_bare_key_taps_advance_shortcut_repeat(monkeypatch):
|
||||||
|
manager = create_input_manager()
|
||||||
|
monkeypatch.setattr(
|
||||||
|
"fenrirscreenreader.core.inputManager.time.time", lambda: 1.0
|
||||||
|
)
|
||||||
|
|
||||||
|
send_input(manager, "KEY_KP5", 1)
|
||||||
|
assert manager.env["input"]["shortcut_repeat"] == 1
|
||||||
|
send_input(manager, "KEY_KP5", 0)
|
||||||
|
send_input(manager, "KEY_KP5", 1)
|
||||||
|
assert manager.env["input"]["shortcut_repeat"] == 2
|
||||||
|
send_input(manager, "KEY_KP5", 0)
|
||||||
|
send_input(manager, "KEY_KP5", 1)
|
||||||
|
assert manager.env["input"]["shortcut_repeat"] == 3
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.unit
|
||||||
|
def test_bare_key_taps_resolve_progressive_shortcuts(monkeypatch):
|
||||||
|
manager = create_input_manager()
|
||||||
|
monkeypatch.setattr(
|
||||||
|
"fenrirscreenreader.core.inputManager.time.time", lambda: 1.0
|
||||||
|
)
|
||||||
|
manager.env["runtime"]["CursorManager"] = Mock(
|
||||||
|
should_process_numpad_commands=Mock(return_value=True)
|
||||||
|
)
|
||||||
|
manager.env["bindings"] = {
|
||||||
|
str([1, ["KEY_KP5"]]): "REVIEW_CURR_WORD",
|
||||||
|
str([2, ["KEY_KP5"]]): "REVIEW_CURR_WORD_SPELL",
|
||||||
|
str([3, ["KEY_KP5"]]): "REVIEW_CURR_WORD_PHONETIC",
|
||||||
|
}
|
||||||
|
|
||||||
|
resolved_commands = []
|
||||||
|
for _tap in range(3):
|
||||||
|
send_input(manager, "KEY_KP5", 1)
|
||||||
|
shortcut = manager.get_curr_shortcut()
|
||||||
|
resolved_commands.append(manager.get_command_for_shortcut(shortcut))
|
||||||
|
send_input(manager, "KEY_KP5", 0)
|
||||||
|
|
||||||
|
assert resolved_commands == [
|
||||||
|
"REVIEW_CURR_WORD",
|
||||||
|
"REVIEW_CURR_WORD_SPELL",
|
||||||
|
"REVIEW_CURR_WORD_PHONETIC",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.unit
|
||||||
|
def test_different_bare_key_starts_new_repeat_sequence(monkeypatch):
|
||||||
|
manager = create_input_manager()
|
||||||
|
monkeypatch.setattr(
|
||||||
|
"fenrirscreenreader.core.inputManager.time.time", lambda: 1.0
|
||||||
|
)
|
||||||
|
|
||||||
|
send_input(manager, "KEY_KP5", 1)
|
||||||
|
send_input(manager, "KEY_KP5", 0)
|
||||||
|
send_input(manager, "KEY_KP5", 1)
|
||||||
|
assert manager.env["input"]["shortcut_repeat"] == 2
|
||||||
|
send_input(manager, "KEY_KP5", 0)
|
||||||
|
send_input(manager, "KEY_KP2", 1)
|
||||||
|
assert manager.env["input"]["shortcut_repeat"] == 1
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.unit
|
||||||
|
def test_bare_key_tap_after_timeout_starts_new_sequence(monkeypatch):
|
||||||
|
manager = create_input_manager()
|
||||||
|
current_time = [1.0]
|
||||||
|
monkeypatch.setattr(
|
||||||
|
"fenrirscreenreader.core.inputManager.time.time",
|
||||||
|
lambda: current_time[0],
|
||||||
|
)
|
||||||
|
|
||||||
|
send_input(manager, "KEY_KP5", 1)
|
||||||
|
send_input(manager, "KEY_KP5", 0)
|
||||||
|
current_time[0] = 2.0
|
||||||
|
send_input(manager, "KEY_KP5", 1)
|
||||||
|
|
||||||
|
assert manager.env["input"]["shortcut_repeat"] == 1
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.unit
|
||||||
|
def test_modifier_chord_taps_still_advance_shortcut_repeat(monkeypatch):
|
||||||
|
manager = create_input_manager()
|
||||||
|
monkeypatch.setattr(
|
||||||
|
"fenrirscreenreader.core.inputManager.time.time", lambda: 1.0
|
||||||
|
)
|
||||||
|
|
||||||
|
send_input(manager, "KEY_FENRIR", 1)
|
||||||
|
send_input(manager, "KEY_T", 1)
|
||||||
|
assert manager.env["input"]["shortcut_repeat"] == 1
|
||||||
|
send_input(manager, "KEY_T", 0)
|
||||||
|
send_input(manager, "KEY_T", 1)
|
||||||
|
assert manager.env["input"]["shortcut_repeat"] == 2
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.unit
|
@pytest.mark.unit
|
||||||
def test_first_conventional_modifier_starts_deferred_prefix():
|
def test_first_conventional_modifier_starts_deferred_prefix():
|
||||||
manager = FenrirManager.__new__(FenrirManager)
|
manager = FenrirManager.__new__(FenrirManager)
|
||||||
@@ -196,4 +326,5 @@ def test_modifier_prefix_is_forwarded_when_released_unused():
|
|||||||
)
|
)
|
||||||
|
|
||||||
input_manager.write_event_buffer.assert_called_once_with()
|
input_manager.write_event_buffer.assert_called_once_with()
|
||||||
|
input_manager.clear_last_deep_input.assert_not_called()
|
||||||
assert manager.modifier_prefix_input is False
|
assert manager.modifier_prefix_input is False
|
||||||
|
|||||||
@@ -0,0 +1,147 @@
|
|||||||
|
import importlib.util
|
||||||
|
from pathlib import Path
|
||||||
|
from unittest.mock import Mock
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from fenrirscreenreader.core.inputManager import InputManager
|
||||||
|
|
||||||
|
|
||||||
|
PROJECT_ROOT = Path(__file__).resolve().parents[2]
|
||||||
|
COMMANDS_DIR = (
|
||||||
|
PROJECT_ROOT / "src" / "fenrirscreenreader" / "commands" / "commands"
|
||||||
|
)
|
||||||
|
KEYBOARD_DIR = PROJECT_ROOT / "config" / "keyboard"
|
||||||
|
|
||||||
|
|
||||||
|
def load_command(name):
|
||||||
|
spec = importlib.util.spec_from_file_location(
|
||||||
|
f"fenrir_{name}", COMMANDS_DIR / f"{name}.py"
|
||||||
|
)
|
||||||
|
module = importlib.util.module_from_spec(spec)
|
||||||
|
spec.loader.exec_module(module)
|
||||||
|
return module.command()
|
||||||
|
|
||||||
|
|
||||||
|
def run_command(name, content, cursor_x=0, cursor_y=0):
|
||||||
|
output_manager = Mock()
|
||||||
|
settings_manager = Mock()
|
||||||
|
settings_manager.get_setting_as_bool.return_value = True
|
||||||
|
env = {
|
||||||
|
"punctuation": {"PUNCTDICT": {" ": "space"}},
|
||||||
|
"screen": {
|
||||||
|
"newCursorReview": {"x": cursor_x, "y": cursor_y},
|
||||||
|
"new_content_text": content,
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"CursorManager": Mock(),
|
||||||
|
"OutputManager": output_manager,
|
||||||
|
"SettingsManager": settings_manager,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
command = load_command(name)
|
||||||
|
command.initialize(env)
|
||||||
|
command.run()
|
||||||
|
return output_manager
|
||||||
|
|
||||||
|
|
||||||
|
def load_bindings(layout):
|
||||||
|
manager = InputManager()
|
||||||
|
manager.env = {
|
||||||
|
"bindings": {},
|
||||||
|
"rawBindings": {},
|
||||||
|
"runtime": {"DebugManager": Mock()},
|
||||||
|
}
|
||||||
|
manager.load_shortcuts(KEYBOARD_DIR / f"{layout}.conf")
|
||||||
|
return manager.env["bindings"]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.unit
|
||||||
|
def test_current_word_is_spelled_one_character_at_a_time():
|
||||||
|
output_manager = run_command(
|
||||||
|
"review_curr_word_spell", "hello world", cursor_x=2
|
||||||
|
)
|
||||||
|
|
||||||
|
calls = output_manager.present_text.call_args_list
|
||||||
|
assert [call.args[0] for call in calls] == list("hello")
|
||||||
|
assert calls[0].kwargs == {
|
||||||
|
"interrupt": True,
|
||||||
|
"ignore_punctuation": True,
|
||||||
|
"announce_capital": True,
|
||||||
|
"flush": False,
|
||||||
|
}
|
||||||
|
assert all(call.kwargs["interrupt"] is False for call in calls[1:])
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.unit
|
||||||
|
def test_current_word_spelling_preserves_capitals_and_punctuation():
|
||||||
|
output_manager = run_command("review_curr_word_spell", "Hi!", cursor_x=1)
|
||||||
|
|
||||||
|
assert [
|
||||||
|
call.args[0] for call in output_manager.present_text.call_args_list
|
||||||
|
] == ["H", "i", "!"]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.unit
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"command_name",
|
||||||
|
["review_curr_word_spell", "review_curr_word_phonetic"],
|
||||||
|
)
|
||||||
|
def test_current_word_spelling_announces_blank_when_no_word_exists(
|
||||||
|
command_name,
|
||||||
|
):
|
||||||
|
output_manager = run_command(command_name, " ")
|
||||||
|
|
||||||
|
output_manager.present_text.assert_called_once_with(
|
||||||
|
"blank", interrupt=True, flush=False
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.unit
|
||||||
|
def test_current_word_phonetic_spelling_uses_phonetic_names():
|
||||||
|
output_manager = run_command(
|
||||||
|
"review_curr_word_phonetic", "Az!", cursor_x=1
|
||||||
|
)
|
||||||
|
|
||||||
|
calls = output_manager.present_text.call_args_list
|
||||||
|
assert [call.args[0] for call in calls] == ["Alpha", "zulu", "!"]
|
||||||
|
assert calls[0].kwargs["interrupt"] is True
|
||||||
|
assert all(call.kwargs["interrupt"] is False for call in calls[1:])
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.unit
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("layout", "character_keys", "word_keys"),
|
||||||
|
[
|
||||||
|
("desktop", ["KEY_KP2"], ["KEY_KP5"]),
|
||||||
|
("laptop", ["KEY_COMMA", "KEY_FENRIR"], ["KEY_FENRIR", "KEY_K"]),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_progressive_review_bindings(layout, character_keys, word_keys):
|
||||||
|
bindings = load_bindings(layout)
|
||||||
|
|
||||||
|
assert bindings[str([1, character_keys])] == "REVIEW_CURR_CHAR"
|
||||||
|
assert bindings[str([2, character_keys])] == "REVIEW_CURR_CHAR_PHONETIC"
|
||||||
|
assert bindings[str([1, word_keys])] == "REVIEW_CURR_WORD"
|
||||||
|
assert bindings[str([2, word_keys])] == "REVIEW_CURR_WORD_SPELL"
|
||||||
|
assert bindings[str([3, word_keys])] == "REVIEW_CURR_WORD_PHONETIC"
|
||||||
|
|
||||||
|
removed_commands = {
|
||||||
|
"REVIEW_PREV_CHAR_PHONETIC",
|
||||||
|
"REVIEW_NEXT_CHAR_PHONETIC",
|
||||||
|
"REVIEW_PREV_WORD_PHONETIC",
|
||||||
|
"REVIEW_NEXT_WORD_PHONETIC",
|
||||||
|
}
|
||||||
|
assert removed_commands.isdisjoint(bindings.values())
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.unit
|
||||||
|
def test_obsolete_phonetic_navigation_commands_are_removed():
|
||||||
|
removed_commands = [
|
||||||
|
"review_prev_char_phonetic.py",
|
||||||
|
"review_next_char_phonetic.py",
|
||||||
|
"review_prev_word_phonetic.py",
|
||||||
|
"review_next_word_phonetic.py",
|
||||||
|
]
|
||||||
|
|
||||||
|
assert all(not (COMMANDS_DIR / name).exists() for name in removed_commands)
|
||||||
@@ -427,6 +427,43 @@ def test_x11_handle_key_event_keeps_event_buffer_for_input_manager():
|
|||||||
event_queue.put.assert_called_once()
|
event_queue.put.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.unit
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("event_type", "event_mode"),
|
||||||
|
[
|
||||||
|
(X.FocusOut, X.NotifyGrab),
|
||||||
|
(X.FocusIn, X.NotifyUngrab),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_x11_transient_grab_focus_events_preserve_input_state(
|
||||||
|
event_type, event_mode
|
||||||
|
):
|
||||||
|
x11 = X11Driver()
|
||||||
|
x11.active = True
|
||||||
|
x11.clear_event_buffer = Mock()
|
||||||
|
x11.reset_input_state = Mock()
|
||||||
|
event = Mock(type=event_type, mode=event_mode)
|
||||||
|
|
||||||
|
x11.handle_x_event(event, Mock())
|
||||||
|
|
||||||
|
assert x11.active is True
|
||||||
|
x11.clear_event_buffer.assert_not_called()
|
||||||
|
x11.reset_input_state.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.unit
|
||||||
|
def test_x11_normal_focus_out_resets_input_state():
|
||||||
|
x11 = X11Driver()
|
||||||
|
x11.active = True
|
||||||
|
x11.reset_input_state = Mock()
|
||||||
|
event = Mock(type=X.FocusOut, mode=X.NotifyNormal)
|
||||||
|
|
||||||
|
x11.handle_x_event(event, Mock())
|
||||||
|
|
||||||
|
assert x11.active is False
|
||||||
|
x11.reset_input_state.assert_called_once_with()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.unit
|
@pytest.mark.unit
|
||||||
def test_x11_fenrir_press_emits_modifiers_from_raw_state_first():
|
def test_x11_fenrir_press_emits_modifiers_from_raw_state_first():
|
||||||
x11 = X11Driver()
|
x11 = X11Driver()
|
||||||
@@ -485,3 +522,40 @@ def test_x11_fenrir_release_balances_synthesized_modifiers():
|
|||||||
assert fenrir_event["data"]["event_name"] == "KEY_KP0"
|
assert fenrir_event["data"]["event_name"] == "KEY_KP0"
|
||||||
assert modifier_event["data"]["event_name"] == "KEY_CTRL"
|
assert modifier_event["data"]["event_name"] == "KEY_CTRL"
|
||||||
assert modifier_event["data"]["event_state"] == 0
|
assert modifier_event["data"]["event_state"] == 0
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.unit
|
||||||
|
def test_x11_fenrir_release_balances_held_chord_key():
|
||||||
|
x11 = X11Driver()
|
||||||
|
x11.active = True
|
||||||
|
x11.fenrir_keys = {"KEY_KP0"}
|
||||||
|
x11.interesting_keys = {"KEY_KP0", "KEY_KP9"}
|
||||||
|
x11.env = {
|
||||||
|
"input": {
|
||||||
|
"curr_input": [],
|
||||||
|
"event_buffer": [],
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"InputManager": Mock(convert_event_name=lambda key: key),
|
||||||
|
"DebugManager": Mock(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
event_queue = Mock()
|
||||||
|
key_names = {90: "KEY_KP0", 81: "KEY_KP9"}
|
||||||
|
x11.keycode_to_key_name = Mock(
|
||||||
|
side_effect=lambda keycode, state=0: key_names[keycode]
|
||||||
|
)
|
||||||
|
|
||||||
|
x11.handle_x_event(
|
||||||
|
Mock(type=X.KeyPress, detail=90, state=0), event_queue
|
||||||
|
)
|
||||||
|
x11.handle_x_event(
|
||||||
|
Mock(type=X.KeyPress, detail=81, state=0), event_queue
|
||||||
|
)
|
||||||
|
x11.handle_x_event(
|
||||||
|
Mock(type=X.KeyRelease, detail=90, state=0), event_queue
|
||||||
|
)
|
||||||
|
|
||||||
|
synthetic_release = event_queue.put.call_args_list[-1].args[0]
|
||||||
|
assert synthetic_release["data"]["event_name"] == "KEY_KP9"
|
||||||
|
assert synthetic_release["data"]["event_state"] == 0
|
||||||
|
|||||||
+7
-26
@@ -108,13 +108,12 @@ msgstr ""
|
|||||||
#: ../src/fenrirscreenreader\commands\commands\review_curr_line.py:27
|
#: ../src/fenrirscreenreader\commands\commands\review_curr_line.py:27
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_curr_word.py:27
|
#: ../src/fenrirscreenreader\commands\commands\review_curr_word.py:27
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_curr_word_phonetic.py:27
|
#: ../src/fenrirscreenreader\commands\commands\review_curr_word_phonetic.py:27
|
||||||
|
#: ../src/fenrirscreenreader\commands\commands\review_curr_word_spell.py:43
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_line_begin.py:27
|
#: ../src/fenrirscreenreader\commands\commands\review_line_begin.py:27
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_next_line.py:29
|
#: ../src/fenrirscreenreader\commands\commands\review_next_line.py:29
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_next_word.py:29
|
#: ../src/fenrirscreenreader\commands\commands\review_next_word.py:29
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_next_word_phonetic.py:27
|
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_prev_line.py:27
|
#: ../src/fenrirscreenreader\commands\commands\review_prev_line.py:27
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_prev_word.py:27
|
#: ../src/fenrirscreenreader\commands\commands\review_prev_word.py:27
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_prev_word_phonetic.py:27
|
|
||||||
#: ../src/fenrirscreenreader\commands\onCursorChange\65000-present_line_if_cursor_change_vertical.py:37
|
#: ../src/fenrirscreenreader\commands\onCursorChange\65000-present_line_if_cursor_change_vertical.py:37
|
||||||
#: ../src/fenrirscreenreader\commands\onScreenUpdate\60000-history.py:59
|
#: ../src/fenrirscreenreader\commands\onScreenUpdate\60000-history.py:59
|
||||||
msgid "blank"
|
msgid "blank"
|
||||||
@@ -513,31 +512,25 @@ msgstr ""
|
|||||||
|
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_curr_word.py:32
|
#: ../src/fenrirscreenreader\commands\commands\review_curr_word.py:32
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_curr_word_phonetic.py:36
|
#: ../src/fenrirscreenreader\commands\commands\review_curr_word_phonetic.py:36
|
||||||
|
#: ../src/fenrirscreenreader\commands\commands\review_curr_word_spell.py:59
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_down.py:27
|
#: ../src/fenrirscreenreader\commands\commands\review_down.py:27
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_next_char.py:28
|
#: ../src/fenrirscreenreader\commands\commands\review_next_char.py:28
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_next_char_phonetic.py:30
|
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_next_line.py:34
|
#: ../src/fenrirscreenreader\commands\commands\review_next_line.py:34
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_next_word.py:34
|
#: ../src/fenrirscreenreader\commands\commands\review_next_word.py:34
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_next_word_phonetic.py:36
|
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_prev_char.py:31
|
#: ../src/fenrirscreenreader\commands\commands\review_prev_char.py:31
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_prev_char_phonetic.py:30
|
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_prev_line.py:32
|
#: ../src/fenrirscreenreader\commands\commands\review_prev_line.py:32
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_prev_word.py:32
|
#: ../src/fenrirscreenreader\commands\commands\review_prev_word.py:32
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_prev_word_phonetic.py:36
|
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_up.py:27
|
#: ../src/fenrirscreenreader\commands\commands\review_up.py:27
|
||||||
msgid "end of screen"
|
msgid "end of screen"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_curr_word.py:35
|
#: ../src/fenrirscreenreader\commands\commands\review_curr_word.py:35
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_curr_word_phonetic.py:39
|
#: ../src/fenrirscreenreader\commands\commands\review_curr_word_phonetic.py:39
|
||||||
|
#: ../src/fenrirscreenreader\commands\commands\review_curr_word_spell.py:68
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_next_char.py:31
|
#: ../src/fenrirscreenreader\commands\commands\review_next_char.py:31
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_next_char_phonetic.py:33
|
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_next_word.py:37
|
#: ../src/fenrirscreenreader\commands\commands\review_next_word.py:37
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_next_word_phonetic.py:39
|
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_prev_char.py:34
|
#: ../src/fenrirscreenreader\commands\commands\review_prev_char.py:34
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_prev_char_phonetic.py:33
|
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_prev_word.py:35
|
#: ../src/fenrirscreenreader\commands\commands\review_prev_word.py:35
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_prev_word_phonetic.py:39
|
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_up.py:30
|
#: ../src/fenrirscreenreader\commands\commands\review_up.py:30
|
||||||
msgid "line break"
|
msgid "line break"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -546,6 +539,10 @@ msgstr ""
|
|||||||
msgid "Phonetically spells the current word"
|
msgid "Phonetically spells the current word"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../src/fenrirscreenreader\commands\commands\review_curr_word_spell.py:23
|
||||||
|
msgid "Spells the current word"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_down.py:18
|
#: ../src/fenrirscreenreader\commands\commands\review_down.py:18
|
||||||
msgid "Move review to the character below the current position"
|
msgid "Move review to the character below the current position"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -590,10 +587,6 @@ msgstr ""
|
|||||||
msgid "Moves review to the next character "
|
msgid "Moves review to the next character "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_next_char_phonetic.py:18
|
|
||||||
msgid "phonetically presents the next character and set review to it"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_next_line.py:18
|
#: ../src/fenrirscreenreader\commands\commands\review_next_line.py:18
|
||||||
msgid "moves review to the next line "
|
msgid "moves review to the next line "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -602,18 +595,10 @@ msgstr ""
|
|||||||
msgid "moves review to the next word "
|
msgid "moves review to the next word "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_next_word_phonetic.py:19
|
|
||||||
msgid "Phonetically spells the next word and moves review to it"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_prev_char.py:18
|
#: ../src/fenrirscreenreader\commands\commands\review_prev_char.py:18
|
||||||
msgid "moves review to the previous character "
|
msgid "moves review to the previous character "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_prev_char_phonetic.py:18
|
|
||||||
msgid "phonetically presents the previous character and set review to it"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_prev_line.py:18
|
#: ../src/fenrirscreenreader\commands\commands\review_prev_line.py:18
|
||||||
msgid "moves review to the previous line "
|
msgid "moves review to the previous line "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -622,10 +607,6 @@ msgstr ""
|
|||||||
msgid "moves review focus to the previous word "
|
msgid "moves review focus to the previous word "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_prev_word_phonetic.py:19
|
|
||||||
msgid "Phonetically spells the previous word and moves review to it"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: ../src/fenrirscreenreader\commands\commands\review_top.py:18
|
#: ../src/fenrirscreenreader\commands\commands\review_top.py:18
|
||||||
msgid "move review to top of screen"
|
msgid "move review to top of screen"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
Reference in New Issue
Block a user