From f73170142cc5c2b51db8781c0a70afb231911537 Mon Sep 17 00:00:00 2001 From: "Alice R." Date: Sun, 3 Nov 2024 21:57:22 -0700 Subject: [PATCH] Enable SDL text events at window creation time. (#502) --- docs/changelog.txt | 2 ++ src/event.h | 1 + src/event_sdl.c | 62 ++++++++++++++++++++++++++++++++++------------ src/platform_sdl.c | 19 -------------- src/render_sdl.c | 4 +++ 5 files changed, 53 insertions(+), 35 deletions(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index 7ddcef2ea..67f4c817c 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -74,6 +74,8 @@ DEVELOPERS in places where "fix_viewport_ratio" previously was and also to convert mouse coordinates. Most renderers should use one of the two prefab implementations of this function. ++ SDL text event enablement now happens after the window is + created. This shouldn't really affect anything. + Added detection for LoongArch64. 64-bit architectures that platform_endian.h fails to identify as such should no longer abort in the software layer renderer. diff --git a/src/event.h b/src/event.h index f39315fac..06bf0e4c4 100644 --- a/src/event.h +++ b/src/event.h @@ -207,6 +207,7 @@ void __wait_event(void); void __warp_mouse(int x, int y); // "Driver" functions currently only supported by SDL. +void sdl_init_window_text_events(unsigned sdl_window_id); void gamepad_map_sym(const char *sym, const char *value); void gamepad_add_mapping(const char *mapping); diff --git a/src/event_sdl.c b/src/event_sdl.c index 1f2fbfd3c..918f61bb9 100644 --- a/src/event_sdl.c +++ b/src/event_sdl.c @@ -36,6 +36,14 @@ extern struct input_status input; +/* Enable converting keycodes to fake unicode presses when text input isn't + * active. Enabling text input also enables an onscreen keyboard in some + * ports, so it isn't always desired. + * + * SDL 1.2 builds will disable this automatically if unicode is detected. + */ +static boolean unicode_fallback; + static boolean numlock_status_initialized; static int joystick_instance_ids[MAX_JOYSTICKS]; static SDL_Joystick *joysticks[MAX_JOYSTICKS]; @@ -968,16 +976,6 @@ static boolean process_event(SDL_Event *event) struct buffered_status *status = store_status(); enum keycode ckey; -#if SDL_VERSION_ATLEAST(2,0,0) - /* Enable converting keycodes to fake unicode presses when text input isn't - * active. Enabling text input also enables an onscreen keyboard in some - * ports, so it isn't always desired. */ - boolean unicode_fallback = !SDL_IsTextInputActive(); -#else - /* SDL 1.2 might also need this (Pandora? doesn't generate unicode presses). */ - static boolean unicode_fallback = true; -#endif - /* SDL's numlock keyboard modifier handling seems to be broken on X11, * and it will only get numlock's status right on application init. We * can trust this value once, and then toggle based on user presses of @@ -1366,13 +1364,9 @@ static boolean process_event(SDL_Event *event) trace("--EVENT_SDL-- SDL_TEXTINPUT: %s\n", text); + // This should never happen; ignore. if(unicode_fallback) - { - // Clear any unicode keys on the buffer generated from the fallback... - status->unicode_length = 0; - status->unicode_repeat = 0; - unicode_fallback = false; - } + break; // Decode the input UTF-8 string into UTF-32 for the event buffer. while(*text) @@ -1664,6 +1658,42 @@ void __warp_mouse(int x, int y) SDL_WarpMouseInWindow(window, x, y); } +/** + * Enable text events for the provided window. + * Prior to SDL3, this was global, so the window ID isn't used. + */ +void sdl_init_window_text_events(unsigned sdl_window_id) +{ +#if SDL_VERSION_ATLEAST(2,0,0) + /* Most platforms want text input events always on so they can generate + * convenient unicode text values, but in Android this causes some problems: + * + * - On older versions the navigation bar will ALWAYS display, regardless + * of whether or not there's an attached keyboard. + * - Holding the space key no longer works, breaking built-in shooting (as + * recent as Android 10). + * - The onscreen keyboard Android pops up can be moved but not collapsed. + * + * TODO: Instead, enable text input on demand at text prompts. + */ + if(!SDL_HasScreenKeyboardSupport()) + { + SDL_StartTextInput(); + unicode_fallback = false; + } + else + { + SDL_StopTextInput(); + unicode_fallback = true; + } +#else + SDL_EnableUNICODE(1); + /* SDL 1.2 might also need this (Pandora? doesn't generate unicode presses). + * If it isn't required, real unicode events will turn this off. */ + unicode_fallback = true; +#endif +} + void platform_init_event(void) { #if !SDL_VERSION_ATLEAST(2,0,0) || defined(CONFIG_SWITCH) || defined(CONFIG_PSVITA) \ diff --git a/src/platform_sdl.c b/src/platform_sdl.c index dc7316f39..0cc1f5026 100644 --- a/src/platform_sdl.c +++ b/src/platform_sdl.c @@ -191,25 +191,6 @@ boolean platform_init(void) return false; } } - -#if SDL_VERSION_ATLEAST(2,0,0) - /* Most platforms want text input events always on so they can generate - * convenient unicode text values, but in Android this causes some problems: - * - * - On older versions the navigation bar will ALWAYS display, regardless - * of whether or not there's an attached keyboard. - * - Holding the space key no longer works, breaking built-in shooting (as - * recent as Android 10). - * - The onscreen keyboard Android pops up can be moved but not collapsed. - * - * TODO: Instead, enable text input on demand at text prompts. - * TODO: this probably redundant with behavior already in SDL. - */ - if(!SDL_HasScreenKeyboardSupport()) - SDL_StartTextInput(); -#else - SDL_EnableUNICODE(1); -#endif return true; } diff --git a/src/render_sdl.c b/src/render_sdl.c index 1e94ac389..2e7f9042d 100644 --- a/src/render_sdl.c +++ b/src/render_sdl.c @@ -19,6 +19,7 @@ */ #include "SDLmzx.h" +#include "event.h" #include "render.h" #include "render_sdl.h" #include "util.h" @@ -679,6 +680,7 @@ boolean sdl_create_window_soft(struct graphics_data *graphics, sdl_set_system_cursor(graphics); sdl_set_window_grab(render_data, window->grab_mouse); + sdl_init_window_text_events(window->platform_id); return true; #if SDL_VERSION_ATLEAST(2,0,0) @@ -991,6 +993,7 @@ boolean sdl_create_window_renderer(struct graphics_data *graphics, sdl_set_screensaver_enabled(graphics->disable_screensaver == SCREENSAVER_ENABLE); sdl_set_system_cursor(graphics); sdl_set_window_grab(render_data, window->grab_mouse); + sdl_init_window_text_events(window->platform_id); return true; err_free: @@ -1119,6 +1122,7 @@ boolean gl_create_window(struct graphics_data *graphics, sdl_set_system_cursor(graphics); sdl_set_window_grab(render_data, window->grab_mouse); + sdl_init_window_text_events(window->platform_id); return true; #if SDL_VERSION_ATLEAST(2,0,0)