Skip to content

Lost input events on long preview #99

@mbriand

Description

@mbriand

Hi,

I'm having an issue when the preview function takes a bit of time to return: any key pressed while the rendering is in progress is lost. In addition, a key pressed while rendering (such as key down) and not released will not be taken into account even after the preview has been rendered. Key has to be released and pressed again to work as expected.

Reproducer

This can be reproduced easily with the example code and a few modifications:

diff --git i/simple_term_menu.py w/simple_term_menu.py
index c91b48227eda..03d6c29d04ad 100755
--- i/simple_term_menu.py
+++ w/simple_term_menu.py
@@ -1998,6 +1998,13 @@ def parse_arguments() -> AttributeDict:
     return args
 
 
+def preview_cmd(s):
+    import time
+    if s == "entry2":
+        time.sleep(.1)
+    return f"preview: {s}"
+
+
 def main() -> None:
     try:
         args = parse_arguments()
@@ -2029,7 +2036,7 @@ def main() -> None:
             multi_select_select_on_accept=args.multi_select_select_on_accept,
             preselected_entries=args.preselected,
             preview_border=args.preview_border,
-            preview_command=args.preview_command,
+            preview_command=preview_cmd,
             preview_size=args.preview_size,
             preview_title=args.preview_title,
             search_case_sensitive=args.case_sensitive,

Then you can run the demo code with a few entries:

./simple_term_menu.py entry1 entry2 entry3 entry4

And on the menu, keep key down pressed without releasing it:

  • Menu entry selection will stop on "entry2".
  • If you release the key and press it again, selection will go over all entries as expected, but stop again on "entry2".

Analysis

Adding a bit of debug code in _read_next_key(), you can see:

  • On key down event, some event is generated. Here I have (in hexadecimal value) 1b4f42.
  • When the selection is stopped on "entry2", longer events are generated, such as 1b4f421b4f421b4f421b4f42. This is just a repetition of the key down event.
  • Even after the preview function is done, these longer events are generated.

Now the issue is, these long sequences do not match any key in self._terminal_code_to_codename, so they are returned as basic keys instead of being interpreted correctly.

I'm not sure about what would be the best fix for this. A solution would be to extract the first key from these sequences and keep the reminder for the next call of _read_next_key(). I will open a PR with such a fix as a POC, but I'm open to other suggestions.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions