From 2cc8fe63e5edc6f554d950b0dd940faaac16fe5d Mon Sep 17 00:00:00 2001 From: Lephenixnoir Date: Sun, 4 Dec 2022 14:42:32 +0100 Subject: [PATCH] ports/sh: fix AC/ON locking after some time The Python program being run is in charge of keyboard events with the gint module. Most programs don't care though, and simply let events accumulate until the queue is full. The async filter is able to receive events even when the queue is full. However, it filtered only AC/ON presses, not releases, so the releases were sent back to the driver to queue. This was impossible as the queue was full, so the release was never recorded. This failure then repeated at every tick, forever. Since the key was never properly released, further presses were just seen as a continuation of the current press and thus did not produce any new event, so the async filter was no longer called and the Python program could no longer be interrupted. --- README.md | 2 ++ ports/sh/main.c | 14 +++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 06d0f57fd..cfac4f2eb 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,8 @@ Bugs to fix: - Fix not resetting the shell when importing a file from command-line - Fix current working directory not changing during a module import (for relative imports) +- Fix accumulated events being processed when the program "ends" (if we can + detect that) Python features: - Compare features with existing implementations and other brands diff --git a/ports/sh/main.c b/ports/sh/main.c index d4776c00d..04ce943ab 100644 --- a/ports/sh/main.c +++ b/ports/sh/main.c @@ -113,13 +113,17 @@ static char *path_to_module(char const *path) interrupt MicroPython instead. */ static bool async_filter(key_event_t ev) { - if(mp_interrupt_char < 0) - return true; - if(ev.type == KEYEV_DOWN && ev.key == KEY_ACON) { - /* This function is designed to be called asynchronously. */ - mp_sched_keyboard_interrupt(); + /* Gobble all events related to AC/ON to make sure that the keyboard driver + treats them as handled. Otherwise, we'd run the risk of filling the + event queue (if the user doesn't read from it) thus preventing the + driver from handling AC/ON releases, which disables further presses. */ + if(mp_interrupt_char >= 0 && ev.key == KEY_ACON) { + /* This function supports asynchronous calls, by design. */ + if(ev.type == KEYEV_DOWN) + mp_sched_keyboard_interrupt(); return false; } + return true; }