diff options
| author | Robin Haberkorn <rhaberkorn@fmsbw.de> | 2026-04-04 13:48:45 +0200 |
|---|---|---|
| committer | Robin Haberkorn <rhaberkorn@fmsbw.de> | 2026-04-04 14:04:48 +0200 |
| commit | 0f39109d6bb4ed14b51164791621620cc6b5d461 (patch) | |
| tree | f7b974b4f244b3e370c8955a6ecc3c7df1472afa /src/interface-curses | |
| parent | b286ad5334eaad82f85c759ee00a36678db7cb17 (diff) | |
Curses: handle window resizes when blocking in `^T` and don't return function keys
* There was a logic error in teco_interface_getch() that caused Curses function key
codes to be returned directly. These codes however are useless to macro authors and
can be confused with codepoints. You cannot report function keys in the same "namespace"
along with Unicode codepoints.
They are now filtered out.
* Also make sure that Backspace and Return are reported as 8 and 10 respectively
in all Curses variants.
All control codes reported by Curses are passed down unmodified - in contrast to
the command-line input handling. I.e. 13 is not normalized to 10.
* PDCursesMod/WinGUI may return bogus key presses, that also have to be filtered out
as we already did in the main input handling.
A function teco_interface_check_key() has been introduced.
* NOTE: teco_interface_blocking_getch() already makes sure that recovery files are dumped
even when blocking in `^T`.
Diffstat (limited to 'src/interface-curses')
| -rw-r--r-- | src/interface-curses/interface.c | 75 |
1 files changed, 52 insertions, 23 deletions
diff --git a/src/interface-curses/interface.c b/src/interface-curses/interface.c index 45821f9..b49540b 100644 --- a/src/interface-curses/interface.c +++ b/src/interface-curses/interface.c @@ -137,6 +137,7 @@ teco_console_ctrl_handler(DWORD type) static gint teco_xterm_version(void) G_GNUC_UNUSED; static gint teco_interface_blocking_getch(void); +static inline gboolean teco_interface_check_key(gint key); /** * Get bright variant of one of the 8 standard @@ -1004,15 +1005,30 @@ teco_interface_getch(gboolean widechar) gint32 cp; do { - cp = teco_interface_blocking_getch(); - if (cp == TECO_CTL_KEY('C')) - teco_interrupted = TRUE; - if (cp == TECO_CTL_KEY('C') || cp == TECO_CTL_KEY('D')) { - cp = -1; - break; - } - if (cp < 0 || cp > 0xFF) - continue; + do { + cp = teco_interface_blocking_getch(); + switch (cp) { +#ifdef KEY_RESIZE + case KEY_RESIZE: + teco_interface_resize_all_windows(); + teco_interface_refresh(FALSE); + /* cursor was moved by the resize */ + wmove(teco_interface.msg_window, 0, 0); + wrefresh(teco_interface.msg_window); + break; +#endif + case KEY_BACKSPACE: + return TECO_CTL_KEY('H'); + case KEY_ENTER: + return '\n'; + case TECO_CTL_KEY('C'): + teco_interrupted = TRUE; + /* fall through */ + case TECO_CTL_KEY('D'): + /* emulates EOF on stdin */ + return -1; + } + } while (cp < 0 || cp > 0xFF || !teco_interface_check_key(cp)); if (!widechar || !cp) break; @@ -2122,6 +2138,31 @@ teco_interface_blocking_getch(void) return key; } +#ifdef __PDCURSES__ + +/* + * Especially PDCurses/WinGUI likes to report two keypresses, + * e.g. for CTRL+Shift+6 (CTRL+^). + * Make sure we don't filter out AltGr, which may be reported as CTRL+ALT. + */ +static inline gboolean +teco_interface_check_key(gint key) +{ + return (PDC_get_key_modifiers() & + (PDC_KEY_MODIFIER_CONTROL | PDC_KEY_MODIFIER_ALT)) != PDC_KEY_MODIFIER_CONTROL || + TECO_IS_CTL(key); +} + +#else /* __PDCURSES__ */ + +static inline gboolean +teco_interface_check_key(gint key) +{ + return TRUE; +} + +#endif + /** * One iteration of the event loop. * @@ -2227,22 +2268,10 @@ teco_interface_event_loop_iter(void) * Control keys and keys with printable representation */ default: - if (key > 0xFF) - /* unhandled function key */ + if (key > 0xFF || !teco_interface_check_key(key)) + /* unhandled function key or bogus key press */ return; -#ifdef __PDCURSES__ - /* - * Especially PDCurses/WinGUI likes to report two keypresses, - * e.g. for CTRL+Shift+6 (CTRL+^). - * Make sure we don't filter out AltGr, which may be reported as CTRL+ALT. - */ - if ((PDC_get_key_modifiers() & - (PDC_KEY_MODIFIER_CONTROL | PDC_KEY_MODIFIER_ALT)) == PDC_KEY_MODIFIER_CONTROL && - !TECO_IS_CTL(key)) - return; -#endif - /* * NOTE: There's also wget_wch(), but it requires * a widechar version of Curses. |
