Backends: SDL2: Update to use io.AddEventKey() will full key map (#2625, #4858) + created localized key (using keycode instead of scancode) (#456)
Legacy indexing stills uses Scancode
diff --git a/backends/imgui_impl_sdl.cpp b/backends/imgui_impl_sdl.cpp
index 3116d14..c50caab 100644
--- a/backends/imgui_impl_sdl.cpp
+++ b/backends/imgui_impl_sdl.cpp
@@ -4,10 +4,10 @@
// (Prefer SDL 2.0.5+ for full feature support.)
// Implemented features:
-// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// [X] Platform: Clipboard support.
-// [X] Platform: Keyboard arrays indexed using SDL_SCANCODE_* codes, e.g. ImGui::IsKeyPressed(SDL_SCANCODE_SPACE).
+// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
+// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// Missing features:
// [ ] Platform: SDL2 handling of IME under Windows appears to be broken and it explicitly disable the regular Windows IME. You can restore Windows IME by compiling SDL with SDL_DISABLE_WINDOWS_IME.
@@ -18,6 +18,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
+// 2022-01-10: Inputs: calling new io.AddKeyEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
// 2021-08-17: Calling io.AddFocusEvent() on SDL_WINDOWEVENT_FOCUS_GAINED/SDL_WINDOWEVENT_FOCUS_LOST.
// 2021-07-29: Inputs: MousePos is correctly reported when the host platform window is hovered but not focused (using SDL_GetMouseFocus() + SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, requires SDL 2.0.5+)
// 2021-06-29: *BREAKING CHANGE* Removed 'SDL_Window* window' parameter to ImGui_ImplSDL2_NewFrame() which was unnecessary.
@@ -105,6 +106,119 @@
SDL_SetClipboardText(text);
}
+static ImGuiKey ImGui_ImplSDL2_KeycodeToImGuiKey(int keycode)
+{
+ switch (keycode)
+ {
+ case SDLK_TAB: return ImGuiKey_Tab;
+ case SDLK_LEFT: return ImGuiKey_LeftArrow;
+ case SDLK_RIGHT: return ImGuiKey_RightArrow;
+ case SDLK_UP: return ImGuiKey_UpArrow;
+ case SDLK_DOWN: return ImGuiKey_DownArrow;
+ case SDLK_PAGEUP: return ImGuiKey_PageUp;
+ case SDLK_PAGEDOWN: return ImGuiKey_PageDown;
+ case SDLK_HOME: return ImGuiKey_Home;
+ case SDLK_END: return ImGuiKey_End;
+ case SDLK_INSERT: return ImGuiKey_Insert;
+ case SDLK_DELETE: return ImGuiKey_Delete;
+ case SDLK_BACKSPACE: return ImGuiKey_Backspace;
+ case SDLK_SPACE: return ImGuiKey_Space;
+ case SDLK_RETURN: return ImGuiKey_Enter;
+ case SDLK_ESCAPE: return ImGuiKey_Escape;
+ case SDLK_QUOTE: return ImGuiKey_Apostrophe;
+ case SDLK_COMMA: return ImGuiKey_Comma;
+ case SDLK_MINUS: return ImGuiKey_Minus;
+ case SDLK_PERIOD: return ImGuiKey_Period;
+ case SDLK_SLASH: return ImGuiKey_Slash;
+ case SDLK_SEMICOLON: return ImGuiKey_Semicolon;
+ case SDLK_EQUALS: return ImGuiKey_Equal;
+ case SDLK_LEFTBRACKET: return ImGuiKey_LeftBracket;
+ case SDLK_BACKSLASH: return ImGuiKey_Backslash;
+ case SDLK_RIGHTBRACKET: return ImGuiKey_RightBracket;
+ case SDLK_BACKQUOTE: return ImGuiKey_GraveAccent;
+ case SDLK_CAPSLOCK: return ImGuiKey_CapsLock;
+ case SDLK_SCROLLLOCK: return ImGuiKey_ScrollLock;
+ case SDLK_NUMLOCKCLEAR: return ImGuiKey_NumLock;
+ case SDLK_PRINTSCREEN: return ImGuiKey_PrintScreen;
+ case SDLK_PAUSE: return ImGuiKey_Pause;
+ case SDLK_KP_0: return ImGuiKey_Keypad0;
+ case SDLK_KP_1: return ImGuiKey_Keypad1;
+ case SDLK_KP_2: return ImGuiKey_Keypad2;
+ case SDLK_KP_3: return ImGuiKey_Keypad3;
+ case SDLK_KP_4: return ImGuiKey_Keypad4;
+ case SDLK_KP_5: return ImGuiKey_Keypad5;
+ case SDLK_KP_6: return ImGuiKey_Keypad6;
+ case SDLK_KP_7: return ImGuiKey_Keypad7;
+ case SDLK_KP_8: return ImGuiKey_Keypad8;
+ case SDLK_KP_9: return ImGuiKey_Keypad9;
+ case SDLK_KP_PERIOD: return ImGuiKey_KeypadDecimal;
+ case SDLK_KP_DIVIDE: return ImGuiKey_KeypadDivide;
+ case SDLK_KP_MULTIPLY: return ImGuiKey_KeypadMultiply;
+ case SDLK_KP_MINUS: return ImGuiKey_KeypadSubtract;
+ case SDLK_KP_PLUS: return ImGuiKey_KeypadAdd;
+ case SDLK_KP_ENTER: return ImGuiKey_KeypadEnter;
+ case SDLK_KP_EQUALS: return ImGuiKey_KeypadEqual;
+ case SDLK_LSHIFT: return ImGuiKey_LeftShift;
+ case SDLK_LCTRL: return ImGuiKey_LeftControl;
+ case SDLK_LALT: return ImGuiKey_LeftAlt;
+ case SDLK_LGUI: return ImGuiKey_LeftSuper;
+ case SDLK_RSHIFT: return ImGuiKey_RightShift;
+ case SDLK_RCTRL: return ImGuiKey_RightControl;
+ case SDLK_RALT: return ImGuiKey_RightAlt;
+ case SDLK_RGUI: return ImGuiKey_RightSuper;
+ case SDLK_MENU: return ImGuiKey_Menu;
+ case SDLK_0: return ImGuiKey_0;
+ case SDLK_1: return ImGuiKey_1;
+ case SDLK_2: return ImGuiKey_2;
+ case SDLK_3: return ImGuiKey_3;
+ case SDLK_4: return ImGuiKey_4;
+ case SDLK_5: return ImGuiKey_5;
+ case SDLK_6: return ImGuiKey_6;
+ case SDLK_7: return ImGuiKey_7;
+ case SDLK_8: return ImGuiKey_8;
+ case SDLK_9: return ImGuiKey_9;
+ case SDLK_a: return ImGuiKey_A;
+ case SDLK_b: return ImGuiKey_B;
+ case SDLK_c: return ImGuiKey_C;
+ case SDLK_d: return ImGuiKey_D;
+ case SDLK_e: return ImGuiKey_E;
+ case SDLK_f: return ImGuiKey_F;
+ case SDLK_g: return ImGuiKey_G;
+ case SDLK_h: return ImGuiKey_H;
+ case SDLK_i: return ImGuiKey_I;
+ case SDLK_j: return ImGuiKey_J;
+ case SDLK_k: return ImGuiKey_K;
+ case SDLK_l: return ImGuiKey_L;
+ case SDLK_m: return ImGuiKey_M;
+ case SDLK_n: return ImGuiKey_N;
+ case SDLK_o: return ImGuiKey_O;
+ case SDLK_p: return ImGuiKey_P;
+ case SDLK_q: return ImGuiKey_Q;
+ case SDLK_r: return ImGuiKey_R;
+ case SDLK_s: return ImGuiKey_S;
+ case SDLK_t: return ImGuiKey_T;
+ case SDLK_u: return ImGuiKey_U;
+ case SDLK_v: return ImGuiKey_V;
+ case SDLK_w: return ImGuiKey_W;
+ case SDLK_x: return ImGuiKey_X;
+ case SDLK_y: return ImGuiKey_Y;
+ case SDLK_z: return ImGuiKey_Z;
+ case SDLK_F1: return ImGuiKey_F1;
+ case SDLK_F2: return ImGuiKey_F2;
+ case SDLK_F3: return ImGuiKey_F3;
+ case SDLK_F4: return ImGuiKey_F4;
+ case SDLK_F5: return ImGuiKey_F5;
+ case SDLK_F6: return ImGuiKey_F6;
+ case SDLK_F7: return ImGuiKey_F7;
+ case SDLK_F8: return ImGuiKey_F8;
+ case SDLK_F9: return ImGuiKey_F9;
+ case SDLK_F10: return ImGuiKey_F10;
+ case SDLK_F11: return ImGuiKey_F11;
+ case SDLK_F12: return ImGuiKey_F12;
+ }
+ return ImGuiKey_None;
+}
+
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
@@ -140,17 +254,9 @@
case SDL_KEYDOWN:
case SDL_KEYUP:
{
- int key = event->key.keysym.scancode;
- IM_ASSERT(key >= 0 && key < IM_ARRAYSIZE(io.KeysDown));
- io.KeysDown[key] = (event->type == SDL_KEYDOWN);
- io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0);
- io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0);
- io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0);
-#ifdef _WIN32
- io.KeySuper = false;
-#else
- io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0);
-#endif
+ ImGuiKey key = ImGui_ImplSDL2_KeycodeToImGuiKey(event->key.keysym.sym);
+ io.AddKeyEvent(key, (event->type == SDL_KEYDOWN));
+ io.SetKeyEventNativeData(key, event->key.keysym.sym, event->key.keysym.scancode, event->key.keysym.scancode); // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions.
return true;
}
case SDL_WINDOWEVENT:
@@ -191,30 +297,6 @@
bd->Window = window;
bd->MouseCanUseGlobalState = mouse_can_use_global_state;
- // Keyboard mapping. Dear ImGui will use those indices to peek into the io.KeysDown[] array.
- io.KeyMap[ImGuiKey_Tab] = SDL_SCANCODE_TAB;
- io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT;
- io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT;
- io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP;
- io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN;
- io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP;
- io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN;
- io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME;
- io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END;
- io.KeyMap[ImGuiKey_Insert] = SDL_SCANCODE_INSERT;
- io.KeyMap[ImGuiKey_Delete] = SDL_SCANCODE_DELETE;
- io.KeyMap[ImGuiKey_Backspace] = SDL_SCANCODE_BACKSPACE;
- io.KeyMap[ImGuiKey_Space] = SDL_SCANCODE_SPACE;
- io.KeyMap[ImGuiKey_Enter] = SDL_SCANCODE_RETURN;
- io.KeyMap[ImGuiKey_Escape] = SDL_SCANCODE_ESCAPE;
- io.KeyMap[ImGuiKey_KeypadEnter] = SDL_SCANCODE_KP_ENTER;
- io.KeyMap[ImGuiKey_A] = SDL_SCANCODE_A;
- io.KeyMap[ImGuiKey_C] = SDL_SCANCODE_C;
- io.KeyMap[ImGuiKey_V] = SDL_SCANCODE_V;
- io.KeyMap[ImGuiKey_X] = SDL_SCANCODE_X;
- io.KeyMap[ImGuiKey_Y] = SDL_SCANCODE_Y;
- io.KeyMap[ImGuiKey_Z] = SDL_SCANCODE_Z;
-
io.SetClipboardTextFn = ImGui_ImplSDL2_SetClipboardText;
io.GetClipboardTextFn = ImGui_ImplSDL2_GetClipboardText;
io.ClipboardUserData = NULL;
@@ -419,6 +501,17 @@
#undef MAP_ANALOG
}
+static void ImGui_ImplSDL2_UpdateKeyModifiers()
+{
+ SDL_Keymod keymod = SDL_GetModState();
+
+ ImGuiIO& io = ImGui::GetIO();
+ io.KeyShift = (keymod & KMOD_SHIFT) != 0;
+ io.KeyCtrl = (keymod & KMOD_CTRL) != 0;
+ io.KeyAlt = (keymod & KMOD_ALT) != 0;
+ io.KeySuper = (keymod & KMOD_GUI) != 0;
+}
+
void ImGui_ImplSDL2_NewFrame()
{
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
@@ -442,6 +535,9 @@
io.DeltaTime = bd->Time > 0 ? (float)((double)(current_time - bd->Time) / frequency) : (float)(1.0f / 60.0f);
bd->Time = current_time;
+ // Update key modifiers
+ ImGui_ImplSDL2_UpdateKeyModifiers();
+
ImGui_ImplSDL2_UpdateMousePosAndButtons();
ImGui_ImplSDL2_UpdateMouseCursor();
diff --git a/backends/imgui_impl_sdl.h b/backends/imgui_impl_sdl.h
index d2439eb..3db454c 100644
--- a/backends/imgui_impl_sdl.h
+++ b/backends/imgui_impl_sdl.h
@@ -3,10 +3,10 @@
// (Info: SDL2 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.)
// Implemented features:
-// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// [X] Platform: Clipboard support.
-// [X] Platform: Keyboard arrays indexed using SDL_SCANCODE_* codes, e.g. ImGui::IsKeyPressed(SDL_SCANCODE_SPACE).
+// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
+// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// Missing features:
// [ ] Platform: SDL2 handling of IME under Windows appears to be broken and it explicitly disable the regular Windows IME. You can restore Windows IME by compiling SDL with SDL_DISABLE_WINDOWS_IME.
diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt
index e5070d2..3153a67 100644
--- a/docs/CHANGELOG.txt
+++ b/docs/CHANGELOG.txt
@@ -93,9 +93,10 @@
- Platform IME: add ImGuiPlatformImeData::WantVisible, hide IME composition window when not used. (#2589) [@actboy168]
- Platform IME: add ImGuiPlatformImeData::InputLineHeight. (#3113) [@liuliu]
- Platform IME: [windows] call ImmSetCandidateWindow() to position candidate window.
-- Backends: GLFW: fix CTRL+A, CTRL+Z, CTRL+Y shortcuts to match user keyboard layout. We are now converting GLFW
- untranslated keycodes back to translated keycodes in order to match the behavior of every other backend, and
- facilitate the use of GLFW with lettered-shortcuts API. (#456, #2625)
+- Backends: GLFW: Pass localized keys (matching keyboard layout). Fix e.g. CTRL+A, CTRL+Z, CTRL+Y shortcuts.
+ We are now converting GLFW untranslated keycodes back to translated keycodes in order to match the behavior of every
+ other backend, and facilitate the use of GLFW with lettered-shortcuts API. (#456, #2625)
+- Backends: SDL: Pass localized keys (matching keyboard layout). Fix e.g. CTRL+A, CTRL+Z, CTRL+Y shortcuts.
- Backends: Allegro5, GLFW, GLUT, SDL, OSX, Win32, Android: Updated to use io.AddKeyEvent() with full key range. (#2625) [@thedmd]
- Backends: OpenGL3: Fixed a buffer overflow in imgui_impl_opengl3_loader.h init (added in 1.86). (#4468, #4830) [@dymk]
It would generally not have noticeable side-effect at runtime but would be detected by runtime checkers.