diff --git a/Quake/in_sdl.c b/Quake/in_sdl.c index 89ae569df..1701a5a6a 100644 --- a/Quake/in_sdl.c +++ b/Quake/in_sdl.c @@ -584,14 +584,46 @@ static void Joy_Flick_f (cvar_t *cvar) IN_ResetFlickState (); } +/* +================ +IN_UpdateSDLTextInput + +Calls SDL_StartTextInput/StopTextInput as needed +based on textmode and the device type +================ +*/ +static void IN_UpdateSDLTextInput (void) +{ + if (SDL_HasScreenKeyboardSupport ()) + { + // Devices with an on-screen keyboard (e.g. Steam Deck) don't receive text input events by default. + // In order to have a functional console we need to call SDL_StartTextInput when text mode is explicitly requested. + // When text mode is optional, but we'd rather not have an on-screen keyboard pop up (e.g. maps & options menus), + // we need call SDL_StopTextInput. + if (textmode == TEXTMODE_ON) + SDL_StartTextInput (); + else + SDL_StopTextInput (); + } + else + { + // Desktop devices (without on-screen keyboards) receive text inputs by default. + // We only call SDL_StartTextInput if for some reason text input got deactivated + // (which shouldn't happen if SDL_StopTextInput is not called). + if (textmode == TEXTMODE_ON && !SDL_IsTextInputActive ()) + SDL_StartTextInput (); + } +} + +/* +================ +IN_Init +================ +*/ void IN_Init (void) { textmode = Key_TextEntry(); - - if (textmode == TEXTMODE_ON) - SDL_StartTextInput(); - else - SDL_StopTextInput(); + IN_UpdateSDLTextInput (); if (safemode || COM_CheckParm("-nomouse")) { @@ -1228,24 +1260,13 @@ void IN_UpdateInputMode (void) if (textmode != want_textmode) { textmode = want_textmode; - if (textmode == TEXTMODE_ON) - { - SDL_StartTextInput(); - if (in_debugkeys.value) - Con_Printf("SDL_StartTextInput time: %g\n", Sys_DoubleTime()); - } - else - { - SDL_StopTextInput(); - if (in_debugkeys.value) - Con_Printf("SDL_StopTextInput time: %g\n", Sys_DoubleTime()); - } + IN_UpdateSDLTextInput (); } } -textmode_t IN_GetTextMode (void) +qboolean IN_EmulatedCharEvents (void) { - return textmode; + return textmode == TEXTMODE_NOPOPUP && !SDL_IsTextInputActive (); } keydevice_t IN_GetLastActiveDeviceType (void) diff --git a/Quake/input.h b/Quake/input.h index e7a2272a4..6e23878bc 100644 --- a/Quake/input.h +++ b/Quake/input.h @@ -77,7 +77,7 @@ void IN_SendKeyEvents (void); void IN_UpdateInputMode (void); // do stuff if input mode (text/non-text) changes matter to the keyboard driver -enum textmode_t IN_GetTextMode (void); +qboolean IN_EmulatedCharEvents (void); enum keydevice_t IN_GetLastActiveDeviceType (void); diff --git a/Quake/keys.c b/Quake/keys.c index d22e14e6d..2efd3328f 100644 --- a/Quake/keys.c +++ b/Quake/keys.c @@ -1193,8 +1193,9 @@ void Key_EventWithKeycode (int key, qboolean down, int keycode) } // generate char events if we want text input without popping up an on-screen keyboard -// when a physical one isn't present, e.g. when using a searchable menu on the Steam Deck - if (down && IN_GetTextMode () == TEXTMODE_NOPOPUP) +// when a physical one isn't present, e.g. when using a searchable menu on the Steam Deck. +// Note: shift modifier is currently not supported for emulated char events. + if (down && !keydown[K_SHIFT] && IN_EmulatedCharEvents ()) Char_Event (keycode); // handle escape specialy, so the user can never unbind it