fixed text event handling for newer SDL versions on Android
authorHolger Schemel <info@artsoft.org>
Tue, 14 Jul 2020 21:03:10 +0000 (23:03 +0200)
committerHolger Schemel <info@artsoft.org>
Tue, 14 Jul 2020 21:18:32 +0000 (23:18 +0200)
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
src/libgame/sdl.h
src/libgame/system.c
src/libgame/system.h

index c32f35e91356cf6800d7a9a50a56c5ab028bda74..2678fa28b94c227855bd4f772ae5bcc57615f31c 100644 (file)
@@ -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);
 }
 
index ad7dca8c1a95ee9cdf4535838be523469ead2c0f..c49894f6836deb17a4ad7f0a883cfbc3da74a3fb 100644 (file)
@@ -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 **);
index af3e053607781e7e1b83ed5dfb911396584f6441..9a8d117b85f1f2c7e6f78c3b35d8b582d0e9f311 100644 (file)
@@ -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();
 
index 221d1eefd0a2e190a554b31c313a6abed15c1b29..02f396d773bf79c30544e4fa26d53276732e328d 100644 (file)
@@ -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;