From 01ea89ab3b30eba8a8128cbb4748ef77ad53a2e2 Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Mon, 7 Oct 2024 21:15:22 +0200 Subject: [PATCH] SDL3: Fix textinput; print available displays and their fullscreen modes --- neo/renderer/tr_local.h | 1 + neo/sys/events.cpp | 26 ++++++++++++++++---------- neo/sys/glimp.cpp | 20 ++++++++++++++++++-- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/neo/renderer/tr_local.h b/neo/renderer/tr_local.h index 55183e99..3719c039 100644 --- a/neo/renderer/tr_local.h +++ b/neo/renderer/tr_local.h @@ -1119,6 +1119,7 @@ void GLimp_DeactivateContext( void ); const int GRAB_GRABMOUSE = (1 << 0); const int GRAB_HIDECURSOR = (1 << 1); const int GRAB_RELATIVEMOUSE = (1 << 2); +const int GRAB_ENABLETEXTINPUT = (1 << 3); // only used with SDL3, where textinput must be explicitly activated void GLimp_GrabInput(int flags); diff --git a/neo/sys/events.cpp b/neo/sys/events.cpp index 9f2d97be..6884eb0f 100644 --- a/neo/sys/events.cpp +++ b/neo/sys/events.cpp @@ -115,10 +115,6 @@ If you have questions concerning this license or the applicable additional terms #define SDL_CONTROLLER_AXIS_RIGHTY SDL_GAMEPAD_AXIS_RIGHTY #define SDL_CONTROLLER_AXIS_TRIGGERLEFT SDL_GAMEPAD_AXIS_LEFT_TRIGGER #define SDL_CONTROLLER_AXIS_TRIGGERRIGHT SDL_GAMEPAD_AXIS_RIGHT_TRIGGER - //#define SDL_CONTROLLER_BINDTYPE_AXIS SDL_GAMEPAD_BINDTYPE_AXIS - //#define SDL_CONTROLLER_BINDTYPE_BUTTON SDL_GAMEPAD_BINDTYPE_BUTTON - //#define SDL_CONTROLLER_BINDTYPE_HAT SDL_GAMEPAD_BINDTYPE_HAT - //#define SDL_CONTROLLER_BINDTYPE_NONE SDL_GAMEPAD_BINDTYPE_NONE #define SDL_CONTROLLER_BUTTON_A SDL_GAMEPAD_BUTTON_SOUTH #define SDL_CONTROLLER_BUTTON_B SDL_GAMEPAD_BUTTON_EAST #define SDL_CONTROLLER_BUTTON_X SDL_GAMEPAD_BUTTON_WEST @@ -525,13 +521,14 @@ static const char* getLocalizedScancodeName( int key, bool useUtf8 ) } } else if ( k != SDLK_UNKNOWN ) { const char *ret = SDL_GetKeyName( k ); - // the keyname from SDL2 is in UTF-8, which Doom3 can't print, - // so only return the name if it's ASCII, otherwise fall back to "SC_bla" if ( ret && *ret != '\0' ) { if( useUtf8 ) { return ret; } + // the keyname from SDL2 is in UTF-8, which Doom3 can't print (except with ImGui), + // so only return the name directly if it's ASCII, otherwise try to translate it + // to ISO8859-1, and if that fails fall back to SC_* if( isAscii( ret ) ) { return ret; } @@ -1264,7 +1261,6 @@ sysEvent_t Sys_GetEvent() { SDL_SetModState((SDL_Keymod)newmod); } // new context because visual studio complains about newmod and currentmod not initialized because of the case SDL_WINDOWEVENT_FOCUS_LOST - in_hasFocus = true; // start playing the game sound world again (when coming from editor) @@ -1295,7 +1291,6 @@ sysEvent_t Sys_GetEvent() { SDL_SetModState((SDL_Keymod)newmod); } // new context because visual studio complains about newmod and currentmod not initialized because of the case SDL_WINDOWEVENT_FOCUS_LOST - in_hasFocus = true; // start playing the game sound world again (when coming from editor) @@ -1349,7 +1344,7 @@ sysEvent_t Sys_GetEvent() { // fall through case SDL_KEYUP: -#if !SDL_VERSION_ATLEAST(2, 0, 0) +#if !SDL_VERSION_ATLEAST(2, 0, 0) // SDL1.2 key = mapkey(ev.key.keysym.sym); if (!key) { if ( !in_ignoreConsoleKey.GetBool() ) { @@ -1737,9 +1732,12 @@ static void handleMouseGrab() { bool showCursor = true; bool grabMouse = false; bool relativeMouse = false; + bool enableTextInput = false; + + const bool imguiHasFocus = D3::ImGuiHooks::ShouldShowCursor(); // if com_editorActive, release everything, just like when we have no focus - if ( in_hasFocus && !com_editorActive && !D3::ImGuiHooks::ShouldShowCursor() ) { + if ( in_hasFocus && !com_editorActive && !imguiHasFocus ) { // Note: this generally handles fullscreen menus, but not the PDA, because the PDA // is an ugly hack in gamecode that doesn't go through sessLocal.guiActive. // It goes through weapon input code or sth? That's also the reason only @@ -1751,9 +1749,11 @@ static void handleMouseGrab() { showCursor = false; relativeMouse = false; grabMouse = false; // TODO: or still grab to window? (maybe only if in exclusive fullscreen mode?) + enableTextInput = true; } else if ( console->Active() ) { showCursor = true; relativeMouse = grabMouse = false; + enableTextInput = true; } else { // in game showCursor = false; grabMouse = relativeMouse = true; @@ -1769,6 +1769,10 @@ static void handleMouseGrab() { } } else { in_relativeMouseMode = false; + // if an ImGui window has focus, enable text input so one can write in there + // TODO: add explicit GRAB_DISABLETEXTINPUT and don't set it at all here for ImGui? + // in theory, ImGui handles that itself, but currently GLimp_GrabInput() seems to override it + enableTextInput = imguiHasFocus; } int flags = 0; @@ -1778,6 +1782,8 @@ static void handleMouseGrab() { flags |= GRAB_GRABMOUSE; if ( relativeMouse ) flags |= GRAB_RELATIVEMOUSE; + if ( enableTextInput ) + flags |= GRAB_ENABLETEXTINPUT; GLimp_GrabInput( flags ); } diff --git a/neo/sys/glimp.cpp b/neo/sys/glimp.cpp index 78c88df3..223f08f7 100644 --- a/neo/sys/glimp.cpp +++ b/neo/sys/glimp.cpp @@ -346,15 +346,26 @@ try_again: common->Printf("SDL detected %d displays: \n", numDisplays); bool found = false; for ( int j=0; jPrintf( " Display %d (ID %u) has the following modes:\n", j, displayId_x ); + for ( int dmIdx=0; dmIdx < numModes; ++dmIdx ) { + SDL_DisplayMode* mode = modes[dmIdx]; + common->Printf( " - %d x %d @ %g Hz, density %g \n", mode->w, mode->h, mode->refresh_rate, mode->pixel_density ); + } + SDL_free( modes ); + if ( SDL_GetDisplayBounds(displayId_x, &rect) ) { + common->Printf(" Currently: %dx%d at (%d, %d) to (%d, %d)\n", rect.w, rect.h, + rect.x, rect.y, rect.x+rect.w, rect.y+rect.h); #else // SDL2 int displayId_x = j; - #endif - SDL_Rect rect; if (SDL_GetDisplayBounds(displayId_x, &rect) == 0) { common->Printf(" %d: %dx%d at (%d, %d) to (%d, %d)\n", j, rect.w, rect.h, rect.x, rect.y, rect.x+rect.w, rect.y+rect.h); + #endif if ( !found && x >= rect.x && x < rect.x + rect.w && y >= rect.y && y < rect.y + rect.h ) { @@ -1130,6 +1141,11 @@ void GLimp_GrabInput(int flags) { SDL_SetWindowMouseGrab( window, false ); SDL_SetWindowKeyboardGrab( window, false ); } + if (flags & GRAB_ENABLETEXTINPUT) { + SDL_StartTextInput( window ); + } else { + SDL_StopTextInput( window ); + } #elif SDL_VERSION_ATLEAST(2, 0, 0) SDL_ShowCursor( (flags & GRAB_HIDECURSOR) ? SDL_DISABLE : SDL_ENABLE ); SDL_SetRelativeMouseMode( (flags & GRAB_RELATIVEMOUSE) ? SDL_TRUE : SDL_FALSE );