Skip to content
This repository has been archived by the owner on May 13, 2024. It is now read-only.

Commit

Permalink
Refactor SDL input code to fix menu exit (#146)
Browse files Browse the repository at this point in the history
  • Loading branch information
ndren authored Feb 18, 2023
1 parent 51dffc4 commit cd3e784
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 7 deletions.
107 changes: 100 additions & 7 deletions source/Irrlicht/CIrrDeviceSDL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

#include "CIrrDeviceSDL.h"
#include "IEventReceiver.h"
#include "IGUIElement.h"
#include "IGUIEnvironment.h"
#include "os.h"
#include "CTimer.h"
#include "irrString.h"
Expand Down Expand Up @@ -105,6 +107,98 @@ EM_BOOL CIrrDeviceSDL::MouseLeaveCallback(int eventType, const EmscriptenMouseEv
}
#endif


bool CIrrDeviceSDL::keyIsKnownSpecial(EKEY_CODE key)
{
switch ( key )
{
// keys which are known to have safe special character interpretation
// could need changes over time (removals and additions!)
case KEY_RETURN:
case KEY_PAUSE:
case KEY_ESCAPE:
case KEY_PRIOR:
case KEY_NEXT:
case KEY_HOME:
case KEY_END:
case KEY_LEFT:
case KEY_UP:
case KEY_RIGHT:
case KEY_DOWN:
case KEY_TAB:
case KEY_PRINT:
case KEY_SNAPSHOT:
case KEY_INSERT:
case KEY_BACK:
case KEY_DELETE:
case KEY_HELP:
case KEY_APPS:
case KEY_SLEEP:
case KEY_F1:
case KEY_F2:
case KEY_F3:
case KEY_F4:
case KEY_F5:
case KEY_F6:
case KEY_F7:
case KEY_F8:
case KEY_F9:
case KEY_F10:
case KEY_F11:
case KEY_F12:
case KEY_F13:
case KEY_F14:
case KEY_F15:
case KEY_F16:
case KEY_F17:
case KEY_F18:
case KEY_F19:
case KEY_F20:
case KEY_F21:
case KEY_F22:
case KEY_F23:
case KEY_F24:
case KEY_NUMLOCK:
case KEY_SCROLL:
case KEY_LCONTROL:
case KEY_RCONTROL:
return true;

default:
return false;
}
}

int CIrrDeviceSDL::findCharToPassToIrrlicht(int assumedChar, EKEY_CODE key) {
// SDL in-place ORs values with no character representation with 1<<30
// https://wiki.libsdl.org/SDL2/SDLKeycodeLookup
if (assumedChar & (1<<30))
return 0;

switch (key) {
case KEY_PRIOR:
case KEY_NEXT:
case KEY_HOME:
case KEY_END:
case KEY_LEFT:
case KEY_UP:
case KEY_RIGHT:
case KEY_DOWN:
case KEY_NUMLOCK:
return 0;
default:
return assumedChar;
}
}

void CIrrDeviceSDL::resetReceiveTextInputEvents() {
gui::IGUIElement *elem = GUIEnvironment->getFocus();
if (elem && elem->acceptsIME())
SDL_StartTextInput();
else
SDL_StopTextInput();
}

//! constructor
CIrrDeviceSDL::CIrrDeviceSDL(const SIrrlichtCreationParameters& param)
: CIrrDeviceStub(param),
Expand Down Expand Up @@ -611,6 +705,10 @@ bool CIrrDeviceSDL::run()
else
key = (EKEY_CODE)KeyMap[idx].Win32Key;

// Make sure to only input special characters if something is in focus, as SDL_TEXTINPUT handles normal unicode already
if (SDL_IsTextInputActive() && !keyIsKnownSpecial(key) && (SDL_event.key.keysym.mod & KMOD_CTRL) == 0)
break;

#ifdef _IRR_WINDOWS_API_
// handle alt+f4 in Windows, because SDL seems not to
if ( (SDL_event.key.keysym.mod & KMOD_LALT) && key == KEY_F4)
Expand All @@ -624,12 +722,7 @@ bool CIrrDeviceSDL::run()
irrevent.KeyInput.PressedDown = (SDL_event.type == SDL_KEYDOWN);
irrevent.KeyInput.Shift = (SDL_event.key.keysym.mod & KMOD_SHIFT) != 0;
irrevent.KeyInput.Control = (SDL_event.key.keysym.mod & KMOD_CTRL ) != 0;
// These keys are handled differently in CGUIEditBox.cpp (may become out of date!)
// Control key is used in special character combinations, so keep that too
// Pass through the keysym only then so no extra text gets input
irrevent.KeyInput.Char = 0;
if (mp.SDLKey == SDLK_DELETE || mp.SDLKey == SDLK_RETURN || mp.SDLKey == SDLK_BACKSPACE || irrevent.KeyInput.Control)
irrevent.KeyInput.Char = mp.SDLKey;
irrevent.KeyInput.Char = findCharToPassToIrrlicht(mp.SDLKey, key);
postEventFromUser(irrevent);
}
break;
Expand Down Expand Up @@ -663,7 +756,7 @@ bool CIrrDeviceSDL::run()
default:
break;
} // end switch

resetReceiveTextInputEvents();
} // end while

#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_)
Expand Down
9 changes: 9 additions & 0 deletions source/Irrlicht/CIrrDeviceSDL.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,15 @@ namespace irr
static EM_BOOL MouseLeaveCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData);

#endif
// Check if a key is a known special character with no side effects on text boxes.
static bool keyIsKnownSpecial(EKEY_CODE key);

// Return the Char that should be sent to Irrlicht for the given key (either the one passed in or 0).
static int findCharToPassToIrrlicht(int assumedChar, EKEY_CODE key);

// Check if a text box is in focus. Enable or disable SDL_TEXTINPUT events only if in focus.
void resetReceiveTextInputEvents();

//! create the driver
void createDriver();

Expand Down

0 comments on commit cd3e784

Please sign in to comment.