SDL3: Fix textinput; print available displays and their fullscreen modes

This commit is contained in:
Daniel Gibson 2024-10-07 21:15:22 +02:00
parent b3be9f7b31
commit 01ea89ab3b
3 changed files with 35 additions and 12 deletions

View file

@ -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);

View file

@ -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 );
}

View file

@ -346,15 +346,26 @@ try_again:
common->Printf("SDL detected %d displays: \n", numDisplays);
bool found = false;
for ( int j=0; j<numDisplays; ++j ) {
SDL_Rect rect;
#if SDL_VERSION_ATLEAST(3, 0, 0)
SDL_DisplayID displayId_x = displayIDs[j];
int numModes = 0;
SDL_DisplayMode** modes = SDL_GetFullscreenDisplayModes(displayId_x, &numModes);
common->Printf( " 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 );