From dfc215d0c07ebfc990304a3f6544420eb717e8ef Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Sat, 6 Apr 2019 10:45:40 +0100 Subject: [PATCH] Remove ASCII fallback in format_numeric_keypad_key(). TranslateKey() on Windows passed all numeric-keypad key events to this function in terminal.c, and accepted whatever it gave back. That included the handling for the trivial case of the numeric keypad, when Num Lock is on and application keypad mode hasn't overridden it, so that the keypad should be returning actual digits. In that case, format_numeric_keypad_key() itself was returning the same ASCII character I had passed in to it as a keypad identifier, and TranslateKey was returning that in turn as the final translation. Unfortunately, that means that with Num Lock on, the numeric keypad translates into what _I_ used as the logical keypad codes inside the source code, not what the local keyboard layout thinks are the right codes. In particular, the key I identified as keypad '.' would render as '.' even on a German keyboard where it ought to produce ','. Fixed by removing the fallback case in format_numeric_keypad_key() itself, so now it returns the empty string if it didn't produce an escape sequence as its translation. Instead, the special case is in window.c, which checks for a zero-length output string and handles it by falling through to the keyboard-layout specific ToUnicode code further down TranslateKey(). On the GTK side, no change is needed here: the GTK keyboard handler does things in the opposite order, by trying the local input method _first_ (unless it can see a reason up front to override it), and only calling format_numeric_keypad_key() if that didn't provide a translation. So the fallback ASCII translation in the latter was already not used. --- terminal.c | 6 ------ windows/window.c | 24 ++++++++++++++++++++---- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/terminal.c b/terminal.c index 0ab7768d..242207cc 100644 --- a/terminal.c +++ b/terminal.c @@ -6836,12 +6836,6 @@ int format_numeric_keypad_key(char *buf, Terminal *term, char key, } } - if (p == buf && !app_keypad && key != 'G') { - /* Fallback: numeric keypad keys decode as their ASCII - * representation. */ - p += sprintf(p, "%c", key); - } - return p - buf; } diff --git a/windows/window.c b/windows/window.c index 9e60f32c..3fc51974 100644 --- a/windows/window.c +++ b/windows/window.c @@ -4515,10 +4515,26 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, break; } - p += format_numeric_keypad_key( - (char *)p, term, keypad_key, - shift_state & 1, shift_state & 2); - return p - output; + { + int nchars = format_numeric_keypad_key( + (char *)p, term, keypad_key, + shift_state & 1, shift_state & 2); + if (!nchars) { + /* If we didn't get an escape sequence out of the + * numeric keypad key, then that must be because + * we're in Num Lock mode without application + * keypad enabled. In that situation we leave this + * keypress to the ToUnicode/ToAsciiEx handler + * below, which will translate it according to the + * appropriate keypad layout (e.g. so that what a + * Brit thinks of as keypad '.' can become ',' in + * the German layout). */ + break; + } + + p += nchars; + return p - output; + } int fkey_number; case VK_F1: fkey_number = 1; goto numbered_function_key;