diff options
author | ndren <andreien@proton.me> | 2023-02-18 15:16:17 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-02-18 16:16:17 +0100 |
commit | cd3e7845344a413a73d2649e3e99d51f14eb12fb (patch) | |
tree | d91f22f00ecd5e5c9070766c774f1237026f3546 | |
parent | 51dffc416a30417aedb533cb9fb817bca1c7a81c (diff) | |
download | irrlicht-cd3e7845344a413a73d2649e3e99d51f14eb12fb.tar.xz |
Refactor SDL input code to fix menu exit (#146)
-rw-r--r-- | source/Irrlicht/CIrrDeviceSDL.cpp | 107 | ||||
-rw-r--r-- | source/Irrlicht/CIrrDeviceSDL.h | 9 |
2 files changed, 109 insertions, 7 deletions
diff --git a/source/Irrlicht/CIrrDeviceSDL.cpp b/source/Irrlicht/CIrrDeviceSDL.cpp index 83c763c..23f00d2 100644 --- a/source/Irrlicht/CIrrDeviceSDL.cpp +++ b/source/Irrlicht/CIrrDeviceSDL.cpp @@ -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"
@@ -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),
@@ -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)
@@ -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;
@@ -663,7 +756,7 @@ bool CIrrDeviceSDL::run() default:
break;
} // end switch
-
+ resetReceiveTextInputEvents();
} // end while
#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_)
diff --git a/source/Irrlicht/CIrrDeviceSDL.h b/source/Irrlicht/CIrrDeviceSDL.h index 2992718..7657718 100644 --- a/source/Irrlicht/CIrrDeviceSDL.h +++ b/source/Irrlicht/CIrrDeviceSDL.h @@ -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();
|