From 888ee0497f046c51100416e0a033ec35d77fb45c Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Tue, 14 Jul 2020 23:03:10 +0200 Subject: [PATCH] fixed text event handling for newer SDL versions on Android Using the previous code with newer SDL versions on Android, when entering text using the screen keyboard, all keys were processed twice, because of different handling of text events and modifier keys in recent SDL versions. The new, more generic approach should work for all SDL versions on all platforms. --- src/events.c | 28 ++++++++++------------------ src/libgame/sdl.h | 11 +++++++++-- src/libgame/system.c | 5 +++++ src/libgame/system.h | 1 + 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/events.c b/src/events.c index c32f35e9..2678fa28 100644 --- a/src/events.c +++ b/src/events.c @@ -1380,13 +1380,9 @@ static void HandleButtonOrFinger(int mx, int my, int button) } } -static boolean checkTextInputKeyModState(void) +static boolean checkTextInputKey(Key key) { - // when playing, only handle raw key events and ignore text input - if (game_status == GAME_MODE_PLAYING) - return FALSE; - - return ((GetKeyModState() & KMOD_TextInput) != KMOD_None); + return (textinput_status && KSYM_PRINTABLE(key)); } void HandleTextEvent(TextEvent *event) @@ -1404,16 +1400,12 @@ void HandleTextEvent(TextEvent *event) GetKeyModState()); #endif -#if !defined(HAS_SCREEN_KEYBOARD) - // non-mobile devices: only handle key input with modifier keys pressed here - // (every other key input is handled directly as physical key input event) - if (!checkTextInputKeyModState()) - return; -#endif - - // process text input as "classic" (with uppercase etc.) key input event - HandleKey(key, KEY_PRESSED); - HandleKey(key, KEY_RELEASED); + if (checkTextInputKey(key)) + { + // process printable keys (with uppercase etc.) in text input mode + HandleKey(key, KEY_PRESSED); + HandleKey(key, KEY_RELEASED); + } } void HandlePauseResumeEvent(PauseResumeEvent *event) @@ -1470,8 +1462,8 @@ void HandleKeyEvent(KeyEvent *event) HandleKeyModState(keymod, key_status); - // only handle raw key input without text modifier keys pressed - if (!checkTextInputKeyModState()) + // process all keys if not in text input mode or if non-printable keys + if (!checkTextInputKey(key)) HandleKey(key, key_status); } diff --git a/src/libgame/sdl.h b/src/libgame/sdl.h index ad7dca8c..c49894f6 100644 --- a/src/libgame/sdl.h +++ b/src/libgame/sdl.h @@ -350,6 +350,15 @@ typedef struct UserEventInfo UserEvent; #define KSYM_FKEY_LAST KSYM_F12 #define KSYM_NUM_FKEYS (KSYM_FKEY_LAST - KSYM_FKEY_FIRST + 1) +#define KSYM_PRINTABLE(k) (((k) >= KSYM_space && \ + (k) <= KSYM_z) || \ + (k) == KSYM_Adiaeresis || \ + (k) == KSYM_Odiaeresis || \ + (k) == KSYM_Udiaeresis || \ + (k) == KSYM_adiaeresis || \ + (k) == KSYM_odiaeresis || \ + (k) == KSYM_udiaeresis) + #define KMOD_None KMOD_NONE #define KMOD_Shift_L KMOD_LSHIFT #define KMOD_Shift_R KMOD_RSHIFT @@ -371,8 +380,6 @@ typedef struct UserEventInfo UserEvent; KMOD_Meta | \ KMOD_Alt) -#define KMOD_TextInput (KMOD_Shift | KMOD_Alt_R) - // SDL function definitions boolean SDLSetNativeSurface(SDL_Surface **); diff --git a/src/libgame/system.c b/src/libgame/system.c index af3e0536..9a8d117b 100644 --- a/src/libgame/system.c +++ b/src/libgame/system.c @@ -57,6 +57,7 @@ int button_status = MB_NOT_PRESSED; boolean motion_status = FALSE; int wheel_steps = DEFAULT_WHEEL_STEPS; boolean keyrepeat_status = TRUE; +boolean textinput_status = FALSE; int redraw_mask = REDRAW_NONE; @@ -1753,6 +1754,8 @@ KeyMod GetKeyModStateFromEvents(void) void StartTextInput(int x, int y, int width, int height) { + textinput_status = TRUE; + #if defined(HAS_SCREEN_KEYBOARD) SDL_StartTextInput(); @@ -1767,6 +1770,8 @@ void StartTextInput(int x, int y, int width, int height) void StopTextInput(void) { + textinput_status = FALSE; + #if defined(HAS_SCREEN_KEYBOARD) SDL_StopTextInput(); diff --git a/src/libgame/system.h b/src/libgame/system.h index 221d1eef..02f396d7 100644 --- a/src/libgame/system.h +++ b/src/libgame/system.h @@ -1760,6 +1760,7 @@ extern int button_status; extern boolean motion_status; extern int wheel_steps; extern boolean keyrepeat_status; +extern boolean textinput_status; extern int redraw_mask; -- 2.34.1