Skip to content

Commit 7d7a3a3

Browse files
committed
showing the error of the selected mapping, no useless error for empty mapping
1 parent a5f992a commit 7d7a3a3

File tree

4 files changed

+62
-20
lines changed

4 files changed

+62
-20
lines changed

inputremapper/configs/mapping.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,10 @@ def output_matches_input(cls, values: Dict[str, Any]) -> Dict[str, Any]:
486486
output_symbol = values.get("output_symbol")
487487
output_key_set = output_symbol or (output_type == EV_KEY and output_code)
488488

489+
if mapping_type is None:
490+
# Empty mapping most likely
491+
return values
492+
489493
if not defines_analog_input and mapping_type != MappingType.KEY_MACRO.value:
490494
raise WrongMappingTypeForKeyError()
491495

inputremapper/gui/controller.py

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -163,17 +163,27 @@ def _format_status_bar_validation_errors(self) -> Optional[Tuple[str, str]]:
163163
self.message_broker.publish(StatusData(CTX_MAPPING))
164164
return None
165165

166-
for mapping in self.data_manager.active_preset:
167-
if not mapping.get_error():
166+
mappings = list(self.data_manager.active_preset)
167+
168+
# Move the selected (active) mapping to the front, so that it is checked first.
169+
active_mapping = self.data_manager.active_mapping
170+
if active_mapping is not None:
171+
mappings.remove(active_mapping)
172+
mappings.insert(0, active_mapping)
173+
174+
for mapping in mappings:
175+
if not mapping.has_input_defined():
176+
# Empty mapping, nothing recorded yet so nothing can be configured,
177+
# therefore there isn't anything to validate.
168178
continue
169179

170180
position = mapping.format_name()
171181
error_strings = self._get_ui_error_strings(mapping)
182+
172183
if len(error_strings) == 0:
173-
# shouldn't be possible to get to this point
174-
logger.error("Expected an error")
175-
return None
176-
elif len(error_strings) > 1:
184+
continue
185+
186+
if len(error_strings) > 1:
177187
msg = _('%d Mapping errors at "%s", hover for info') % (
178188
len(error_strings),
179189
position,
@@ -661,12 +671,12 @@ def start_injecting(self):
661671
_('Failed to apply preset "%s"') % self.data_manager.active_preset.name,
662672
)
663673

664-
def show_injector_result(self, msg: InjectorStateMessage):
674+
def show_injector_result(self, msg: InjectorStateMessage) -> None:
665675
"""Show if the injection was successfully started."""
666676
self.message_broker.unsubscribe(self.show_injector_result)
667677
state = msg.state
668678

669-
def running():
679+
def running() -> None:
670680
msg = _('Applied preset "%s"') % self.data_manager.active_preset.name
671681
if self.data_manager.active_preset.dangerously_mapped_btn_left():
672682
msg += _(", CTRL + DEL to stop")
@@ -675,14 +685,13 @@ def running():
675685
'Group "%s" is currently mapped', self.data_manager.active_group.key
676686
)
677687

678-
def no_grab():
688+
def no_grab() -> None:
679689
msg = (
680690
_('Failed to apply preset "%s"') % self.data_manager.active_preset.name
681691
)
682692
tooltip = (
683-
"Your preset might contain errors, or "
684-
"your preset doesn't contain anything that is sent by the "
685-
"device or another device is already grabbing it",
693+
"Maybe your preset doesn't contain anything that is sent by the "
694+
"device or another device is already grabbing it"
686695
)
687696

688697
# InjectorState.NO_GRAB also happens when all mappings have validation

tests/integration/test_components.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -905,11 +905,12 @@ def test_placeholder(self):
905905

906906
def focus():
907907
self.gui.grab_focus()
908-
gtk_iteration(5)
908+
# Do as many iterations as needed to make it work.
909+
gtk_iteration(15)
909910

910911
def unfocus():
911912
window.set_focus(None)
912-
gtk_iteration(5)
913+
gtk_iteration(15)
913914

914915
# clears the input when we enter the editor widget
915916
focus()

tests/integration/test_gui.py

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1489,40 +1489,56 @@ def save():
14891489
self.assertFalse(os.path.exists(preset_path))
14901490

14911491
def test_check_for_unknown_symbols(self):
1492+
first_input = InputCombination([InputConfig(type=1, code=1)])
1493+
second_input = InputCombination([InputConfig(type=1, code=2)])
14921494
status = self.user_interface.get("status_bar")
14931495
error_icon = self.user_interface.get("error_status_icon")
14941496
warning_icon = self.user_interface.get("warning_status_icon")
14951497

14961498
self.controller.load_preset("preset1")
14971499
self.throttle(20)
1498-
self.controller.load_mapping(InputCombination([InputConfig(type=1, code=1)]))
1500+
1501+
# Switch to the first mapping, and change it
1502+
self.controller.load_mapping(first_input)
14991503
gtk_iteration()
15001504
self.controller.update_mapping(output_symbol="foo")
15011505
gtk_iteration()
1502-
self.controller.load_mapping(InputCombination([InputConfig(type=1, code=2)]))
1506+
1507+
# Switch to the second mapping, and change it
1508+
self.controller.load_mapping(second_input)
15031509
gtk_iteration()
15041510
self.controller.update_mapping(output_symbol="qux")
15051511
gtk_iteration()
15061512

1513+
# The tooltip should show the error of the currently selected mapping
15071514
tooltip = status.get_tooltip_text().lower()
15081515
self.assertIn("qux", tooltip)
15091516
self.assertTrue(error_icon.get_visible())
15101517
self.assertFalse(warning_icon.get_visible())
15111518

1512-
# it will still save it though
1519+
# So switching to the other mapping changes the tooltip
1520+
self.controller.load_mapping(first_input)
1521+
gtk_iteration()
1522+
tooltip = status.get_tooltip_text().lower()
1523+
self.assertIn("foo", tooltip)
1524+
1525+
# It will still save it though
15131526
with open(PathUtils.get_preset_path("Foo Device", "preset1")) as f:
15141527
content = f.read()
15151528
self.assertIn("qux", content)
15161529
self.assertIn("foo", content)
15171530

1531+
# Fix the current active mapping.
1532+
# It should show the error of the other mapping now.
15181533
self.controller.update_mapping(output_symbol="a")
15191534
gtk_iteration()
15201535
tooltip = status.get_tooltip_text().lower()
1521-
self.assertIn("foo", tooltip)
1536+
self.assertIn("qux", tooltip)
15221537
self.assertTrue(error_icon.get_visible())
15231538
self.assertFalse(warning_icon.get_visible())
15241539

1525-
self.controller.load_mapping(InputCombination([InputConfig(type=1, code=1)]))
1540+
# Fix the other mapping as well. No tooltip should be shown afterward.
1541+
self.controller.load_mapping(second_input)
15261542
gtk_iteration()
15271543
self.controller.update_mapping(output_symbol="b")
15281544
gtk_iteration()
@@ -1531,6 +1547,18 @@ def test_check_for_unknown_symbols(self):
15311547
self.assertFalse(error_icon.get_visible())
15321548
self.assertFalse(warning_icon.get_visible())
15331549

1550+
def test_no_validation_tooltip_for_empty_mappings(self):
1551+
self.controller.load_preset("preset1")
1552+
self.throttle(20)
1553+
1554+
status = self.user_interface.get("status_bar")
1555+
self.assertIsNone(status.get_tooltip_text())
1556+
1557+
self.controller.create_mapping()
1558+
gtk_iteration()
1559+
self.assertTrue(self.controller.is_empty_mapping())
1560+
self.assertIsNone(status.get_tooltip_text())
1561+
15341562
def test_check_macro_syntax(self):
15351563
status = self.status_bar
15361564
error_icon = self.user_interface.get("error_status_icon")
@@ -1702,7 +1730,7 @@ def wait():
17021730
self.assertFalse(error_icon.get_visible())
17031731
wait()
17041732
text = self.get_status_text()
1705-
self.assertIn("not grabbed", text)
1733+
self.assertIn("Failed to apply preset", text)
17061734
self.assertTrue(error_icon.get_visible())
17071735
self.assertNotEqual(
17081736
self.daemon.get_state("Foo Device 2"), InjectorState.RUNNING

0 commit comments

Comments
 (0)