diff --git a/backends/imgui_impl_allegro5.cpp b/backends/imgui_impl_allegro5.cpp index ac03b3c1e..25e2d1489 100644 --- a/backends/imgui_impl_allegro5.cpp +++ b/backends/imgui_impl_allegro5.cpp @@ -17,6 +17,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2022-01-17: Inputs: always calling io.AddKeyModsEvent() next and before key event (not in NewFrame) to fix input queue with very low framerates. // 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. // 2021-12-08: Renderer: Fixed mishandling of the the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86. // 2021-08-17: Calling io.AddFocusEvent() on ALLEGRO_EVENT_DISPLAY_SWITCH_OUT/ALLEGRO_EVENT_DISPLAY_SWITCH_IN events. @@ -440,6 +441,20 @@ void ImGui_ImplAllegro5_Shutdown() IM_DELETE(bd); } +// ev->keyboard.modifiers seems always zero so using that... +static void ImGui_ImplAllegro5_UpdateKeyModifiers() +{ + ImGuiIO& io = ImGui::GetIO(); + ALLEGRO_KEYBOARD_STATE keys; + al_get_keyboard_state(&keys); + ImGuiKeyModFlags key_mods = + ((al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL)) ? ImGuiKeyModFlags_Ctrl : 0) | + ((al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT)) ? ImGuiKeyModFlags_Shift : 0) | + ((al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR)) ? ImGuiKeyModFlags_Alt : 0) | + ((al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN)) ? ImGuiKeyModFlags_Super : 0); + io.AddKeyModsEvent(key_mods); +} + // 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. @@ -487,6 +502,7 @@ bool ImGui_ImplAllegro5_ProcessEvent(ALLEGRO_EVENT* ev) case ALLEGRO_EVENT_KEY_UP: if (ev->keyboard.display == bd->Display) { + ImGui_ImplAllegro5_UpdateKeyModifiers(); ImGuiKey key = ImGui_ImplAllegro5_KeyCodeToImGuiKey(ev->keyboard.keycode); io.AddKeyEvent(key, (ev->type == ALLEGRO_EVENT_KEY_DOWN)); io.SetKeyEventNativeData(key, ev->keyboard.keycode, -1); // To support legacy indexing (<1.87 user code) @@ -560,15 +576,6 @@ void ImGui_ImplAllegro5_NewFrame() io.DeltaTime = bd->Time > 0.0 ? (float)(current_time - bd->Time) : (float)(1.0f / 60.0f); bd->Time = current_time; - // Setup inputs - ALLEGRO_KEYBOARD_STATE keys; - al_get_keyboard_state(&keys); - ImGuiKeyModFlags key_mods = - ((al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL)) ? ImGuiKeyModFlags_Ctrl : 0) | - ((al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT)) ? ImGuiKeyModFlags_Shift : 0) | - ((al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR)) ? ImGuiKeyModFlags_Alt : 0) | - ((al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN)) ? ImGuiKeyModFlags_Super : 0); - io.AddKeyModsEvent(key_mods); - + // Setup mouse cursor shape ImGui_ImplAllegro5_UpdateMouseCursor(); } diff --git a/backends/imgui_impl_glfw.cpp b/backends/imgui_impl_glfw.cpp index 83d4bd626..b10bab89b 100644 --- a/backends/imgui_impl_glfw.cpp +++ b/backends/imgui_impl_glfw.cpp @@ -16,6 +16,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2022-01-17: Inputs: always calling io.AddKeyModsEvent() next and before key event (not in NewFrame) to fix input queue with very low framerates. // 2022-01-12: *BREAKING CHANGE*: Now using glfwSetCursorPosCallback(). If you called ImGui_ImplGlfw_InitXXX() with install_callbacks = false, you MUST install glfwSetCursorPosCallback() and forward it to the backend via ImGui_ImplGlfw_CursorPosCallback(). // 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. // 2022-01-05: Inputs: Converting GLFW untranslated keycodes back to translated keycodes (in the ImGui_ImplGlfw_KeyCallback() function) in order to match the behavior of every other backend, and facilitate the use of GLFW with lettered-shortcuts API. @@ -238,12 +239,24 @@ static ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int key) } } +static void ImGui_ImplGlfw_UpdateKeyModifiers(int mods) +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiKeyModFlags key_mods = + ((mods & GLFW_MOD_CONTROL) ? ImGuiKeyModFlags_Ctrl : 0) | + ((mods & GLFW_MOD_SHIFT) ? ImGuiKeyModFlags_Shift : 0) | + ((mods & GLFW_MOD_ALT) ? ImGuiKeyModFlags_Alt : 0) | + ((mods & GLFW_MOD_SUPER) ? ImGuiKeyModFlags_Super : 0); + io.AddKeyModsEvent(key_mods); +} + void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods) { ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); if (bd->PrevUserCallbackMousebutton != NULL && window == bd->Window) bd->PrevUserCallbackMousebutton(window, button, action, mods); + ImGui_ImplGlfw_UpdateKeyModifiers(mods); if (action == GLFW_PRESS && button >= 0 && button < IM_ARRAYSIZE(bd->MouseJustPressed)) bd->MouseJustPressed[button] = true; } @@ -293,6 +306,8 @@ void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int keycode, int scancode, i if (action != GLFW_PRESS && action != GLFW_RELEASE) return; + ImGui_ImplGlfw_UpdateKeyModifiers(mods); + keycode = ImGui_ImplGlfw_TranslateUntranslatedKey(keycode, scancode); ImGuiIO& io = ImGui::GetIO(); @@ -557,18 +572,6 @@ static void ImGui_ImplGlfw_UpdateGamepads() io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad; } -static void ImGui_ImplGlfw_UpdateKeyModifiers() -{ - ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); - ImGuiIO& io = ImGui::GetIO(); - ImGuiKeyModFlags key_mods = - (((glfwGetKey(bd->Window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS) || (glfwGetKey(bd->Window, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS)) ? ImGuiKeyModFlags_Ctrl : 0) | - (((glfwGetKey(bd->Window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) || (glfwGetKey(bd->Window, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS)) ? ImGuiKeyModFlags_Shift : 0) | - (((glfwGetKey(bd->Window, GLFW_KEY_LEFT_ALT) == GLFW_PRESS) || (glfwGetKey(bd->Window, GLFW_KEY_RIGHT_ALT) == GLFW_PRESS)) ? ImGuiKeyModFlags_Alt : 0) | - (((glfwGetKey(bd->Window, GLFW_KEY_LEFT_SUPER) == GLFW_PRESS) || (glfwGetKey(bd->Window, GLFW_KEY_RIGHT_SUPER) == GLFW_PRESS)) ? ImGuiKeyModFlags_Super : 0); - io.AddKeyModsEvent(key_mods); -} - void ImGui_ImplGlfw_NewFrame() { ImGuiIO& io = ImGui::GetIO(); @@ -589,7 +592,6 @@ void ImGui_ImplGlfw_NewFrame() io.DeltaTime = bd->Time > 0.0 ? (float)(current_time - bd->Time) : (float)(1.0f / 60.0f); bd->Time = current_time; - ImGui_ImplGlfw_UpdateKeyModifiers(); ImGui_ImplGlfw_UpdateMouseData(); ImGui_ImplGlfw_UpdateMouseCursor(); diff --git a/backends/imgui_impl_glut.cpp b/backends/imgui_impl_glut.cpp index 6eec280e3..91185372a 100644 --- a/backends/imgui_impl_glut.cpp +++ b/backends/imgui_impl_glut.cpp @@ -202,7 +202,7 @@ void ImGui_ImplGLUT_NewFrame() ImGui::NewFrame(); } -static void ImGui_ImplGLUT_UpdateKeyboardMods() +static void ImGui_ImplGLUT_UpdateKeyModifiers() { ImGuiIO& io = ImGui::GetIO(); int glut_key_mods = glutGetModifiers(); @@ -230,7 +230,7 @@ void ImGui_ImplGLUT_KeyboardFunc(unsigned char c, int x, int y) ImGuiKey key = ImGui_ImplGLUT_KeyToImGuiKey(c); ImGui_ImplGLUT_AddKeyEvent(key, true, c); - ImGui_ImplGLUT_UpdateKeyboardMods(); + ImGui_ImplGLUT_UpdateKeyModifiers(); (void)x; (void)y; // Unused } @@ -239,7 +239,7 @@ void ImGui_ImplGLUT_KeyboardUpFunc(unsigned char c, int x, int y) //printf("char_up_func %d '%c'\n", c, c); ImGuiKey key = ImGui_ImplGLUT_KeyToImGuiKey(c); ImGui_ImplGLUT_AddKeyEvent(key, false, c); - ImGui_ImplGLUT_UpdateKeyboardMods(); + ImGui_ImplGLUT_UpdateKeyModifiers(); (void)x; (void)y; // Unused } @@ -248,7 +248,7 @@ void ImGui_ImplGLUT_SpecialFunc(int key, int x, int y) //printf("key_down_func %d\n", key); ImGuiKey imgui_key = ImGui_ImplGLUT_KeyToImGuiKey(key + 256); ImGui_ImplGLUT_AddKeyEvent(imgui_key, true, key + 256); - ImGui_ImplGLUT_UpdateKeyboardMods(); + ImGui_ImplGLUT_UpdateKeyModifiers(); (void)x; (void)y; // Unused } @@ -257,7 +257,7 @@ void ImGui_ImplGLUT_SpecialUpFunc(int key, int x, int y) //printf("key_up_func %d\n", key); ImGuiKey imgui_key = ImGui_ImplGLUT_KeyToImGuiKey(key + 256); ImGui_ImplGLUT_AddKeyEvent(imgui_key, false, key + 256); - ImGui_ImplGLUT_UpdateKeyboardMods(); + ImGui_ImplGLUT_UpdateKeyModifiers(); (void)x; (void)y; // Unused } diff --git a/backends/imgui_impl_osx.mm b/backends/imgui_impl_osx.mm index 55f269d18..648840dd8 100644 --- a/backends/imgui_impl_osx.mm +++ b/backends/imgui_impl_osx.mm @@ -53,7 +53,6 @@ static NSCursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {}; static bool g_MouseCursorHidden = false; static bool g_MouseJustPressed[ImGuiMouseButton_COUNT] = {}; static bool g_MouseDown[ImGuiMouseButton_COUNT] = {}; -static ImGuiKeyModFlags g_KeyModifiers = ImGuiKeyModFlags_None; static ImFocusObserver* g_FocusObserver = nil; static KeyEventResponder* g_KeyEventResponder = nil; static NSTextInputContext* g_InputContext = nil; @@ -535,12 +534,6 @@ static void ImGui_ImplOSX_UpdateGamepads() io.BackendFlags |= ImGuiBackendFlags_HasGamepad; } -static void ImGui_ImplOSX_UpdateKeyModifiers() -{ - ImGuiIO& io = ImGui::GetIO(); - io.AddKeyModsEvent(g_KeyModifiers); -} - static void ImGui_ImplOSX_UpdateImePosWithView(NSView* view) { ImGuiIO& io = ImGui::GetIO(); @@ -569,7 +562,6 @@ void ImGui_ImplOSX_NewFrame(NSView* view) io.DeltaTime = (float)(current_time - g_Time); g_Time = current_time; - ImGui_ImplOSX_UpdateKeyModifiers(); ImGui_ImplOSX_UpdateMouseCursorAndButtons(); ImGui_ImplOSX_UpdateGamepads(); ImGui_ImplOSX_UpdateImePosWithView(view); @@ -666,17 +658,16 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view) unsigned short key_code = [event keyCode]; unsigned int flags = [event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask; - ImGuiKeyModFlags imgui_flags = ImGuiKeyModFlags_None; + ImGuiKeyModFlags imgui_key_mods = ImGuiKeyModFlags_None; if (flags & NSEventModifierFlagShift) - imgui_flags |= ImGuiKeyModFlags_Shift; + imgui_key_mods |= ImGuiKeyModFlags_Shift; if (flags & NSEventModifierFlagControl) - imgui_flags |= ImGuiKeyModFlags_Ctrl; + imgui_key_mods |= ImGuiKeyModFlags_Ctrl; if (flags & NSEventModifierFlagOption) - imgui_flags |= ImGuiKeyModFlags_Alt; + imgui_key_mods |= ImGuiKeyModFlags_Alt; if (flags & NSEventModifierFlagCommand) - imgui_flags |= ImGuiKeyModFlags_Super; - - g_KeyModifiers = imgui_flags; + imgui_key_mods |= ImGuiKeyModFlags_Super; + io.AddKeyModsEvent(imgui_key_mods); ImGuiKey key = ImGui_ImplOSX_KeyCodeToImGuiKey(key_code); if (key != ImGuiKey_None) @@ -705,7 +696,7 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view) } else if (imgui_mask) { - io.AddKeyEvent(key, (imgui_flags & imgui_mask) != 0); + io.AddKeyEvent(key, (imgui_key_mods & imgui_mask) != 0); } io.SetKeyEventNativeData(key, key_code, -1); // To support legacy indexing (<1.87 user code) } diff --git a/backends/imgui_impl_sdl.cpp b/backends/imgui_impl_sdl.cpp index 8feef9c25..941acaec3 100644 --- a/backends/imgui_impl_sdl.cpp +++ b/backends/imgui_impl_sdl.cpp @@ -18,6 +18,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2022-01-17: Inputs: always calling io.AddKeyModsEvent() next and before key event (not in NewFrame) to fix input queue with very low framerates. // 2022-01-12: Update mouse inputs using SDL_MOUSEMOTION/SDL_WINDOWEVENT_LEAVE + fallback to provide it when focused but not hovered/captured. More standard and will allow us to pass it to future input queue API. // 2022-01-12: Maintain our own copy of MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted. // 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. @@ -222,6 +223,17 @@ static ImGuiKey ImGui_ImplSDL2_KeycodeToImGuiKey(int keycode) return ImGuiKey_None; } +static void ImGui_ImplSDL2_UpdateKeyModifiers(SDL_Keymod sdl_key_mods) +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiKeyModFlags key_mods = + ((sdl_key_mods & KMOD_CTRL) ? ImGuiKeyModFlags_Ctrl : 0) | + ((sdl_key_mods & KMOD_SHIFT) ? ImGuiKeyModFlags_Shift : 0) | + ((sdl_key_mods & KMOD_ALT) ? ImGuiKeyModFlags_Alt : 0) | + ((sdl_key_mods & KMOD_GUI) ? ImGuiKeyModFlags_Super : 0); + io.AddKeyModsEvent(key_mods); +} + // 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. @@ -269,6 +281,7 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event) case SDL_KEYDOWN: case SDL_KEYUP: { + ImGui_ImplSDL2_UpdateKeyModifiers((SDL_Keymod)event->key.keysym.mod); 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. @@ -499,18 +512,6 @@ static void ImGui_ImplSDL2_UpdateGamepads() #undef MAP_ANALOG } -static void ImGui_ImplSDL2_UpdateKeyModifiers() -{ - ImGuiIO& io = ImGui::GetIO(); - SDL_Keymod sdl_key_mods = SDL_GetModState(); - ImGuiKeyModFlags key_mods = - ((sdl_key_mods & KMOD_CTRL) ? ImGuiKeyModFlags_Ctrl : 0) | - ((sdl_key_mods & KMOD_SHIFT) ? ImGuiKeyModFlags_Shift : 0) | - ((sdl_key_mods & KMOD_ALT) ? ImGuiKeyModFlags_Alt : 0) | - ((sdl_key_mods & KMOD_GUI) ? ImGuiKeyModFlags_Super : 0); - io.AddKeyModsEvent(key_mods); -} - void ImGui_ImplSDL2_NewFrame() { ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData(); @@ -534,7 +535,6 @@ void ImGui_ImplSDL2_NewFrame() io.DeltaTime = bd->Time > 0 ? (float)((double)(current_time - bd->Time) / frequency) : (float)(1.0f / 60.0f); bd->Time = current_time; - ImGui_ImplSDL2_UpdateKeyModifiers(); ImGui_ImplSDL2_UpdateMouseData(); ImGui_ImplSDL2_UpdateMouseCursor(); diff --git a/backends/imgui_impl_win32.cpp b/backends/imgui_impl_win32.cpp index bd3d54784..379434651 100644 --- a/backends/imgui_impl_win32.cpp +++ b/backends/imgui_impl_win32.cpp @@ -34,8 +34,9 @@ typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*); // CHANGELOG // (minor and older changes stripped away, please see git history for details) -// 2022-01-12: Update mouse inputs using WM_MOUSEMOVE/WM_MOUSELEAVE + fallback to provide it when focused but not hovered/captured. More standard and will allow us to pass it to future input queue API. -// 2022-01-12: Maintain our own copy of MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted. +// 2022-01-17: Inputs: always calling io.AddKeyModsEvent() next and before a key event (not in NewFrame) to fix input queue with very low framerates. +// 2022-01-12: Inputs: Update mouse inputs using WM_MOUSEMOVE/WM_MOUSELEAVE + fallback to provide it when focused but not hovered/captured. More standard and will allow us to pass it to future input queue API. +// 2022-01-12: Inputs: Maintain our own copy of MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted. // 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. // 2021-12-16: Inputs: Fill VK_LCONTROL/VK_RCONTROL/VK_LSHIFT/VK_RSHIFT/VK_LMENU/VK_RMENU for completeness. // 2021-08-17: Calling io.AddFocusEvent() on WM_SETFOCUS/WM_KILLFOCUS messages. @@ -235,10 +236,10 @@ static void ImGui_ImplWin32_UpdateKeyModifiers() { ImGuiIO& io = ImGui::GetIO(); ImGuiKeyModFlags key_mods = - ((IsVkDown(VK_LCONTROL) || IsVkDown(VK_RCONTROL)) ? ImGuiKeyModFlags_Ctrl : 0) | - ((IsVkDown(VK_LSHIFT) || IsVkDown(VK_RSHIFT)) ? ImGuiKeyModFlags_Shift : 0) | - ((IsVkDown(VK_LMENU) || IsVkDown(VK_RMENU)) ? ImGuiKeyModFlags_Alt : 0) | - ((IsVkDown(VK_LWIN) || IsVkDown(VK_RWIN)) ? ImGuiKeyModFlags_Super : 0); + ((IsVkDown(VK_CONTROL)) ? ImGuiKeyModFlags_Ctrl : 0) | + ((IsVkDown(VK_SHIFT) ) ? ImGuiKeyModFlags_Shift : 0) | + ((IsVkDown(VK_MENU)) ? ImGuiKeyModFlags_Alt : 0) | + ((IsVkDown(VK_APPS)) ? ImGuiKeyModFlags_Super : 0); io.AddKeyModsEvent(key_mods); } @@ -342,9 +343,6 @@ void ImGui_ImplWin32_NewFrame() // Process workarounds for known Windows key handling issues ImGui_ImplWin32_ProcessKeyEventsWorkarounds(); - // Update key modifiers - ImGui_ImplWin32_UpdateKeyModifiers(); - // Update OS mouse cursor with the cursor requested by imgui ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor(); if (bd->LastMouseCursor != mouse_cursor) @@ -564,9 +562,11 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA case WM_SYSKEYUP: { const bool is_key_down = (msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN); - if (wParam < 256) { + // Submit modifiers + ImGui_ImplWin32_UpdateKeyModifiers(); + // Obtain virtual key code // (keypad enter doesn't have its own... VK_RETURN with KF_EXTENDED flag means keypad enter, see IM_VK_KEYPAD_ENTER definition for details, it is mapped to ImGuiKey_KeyPadEnter.) int vk = (int)wParam; diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index a4e4a1392..d60c83651 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -103,13 +103,17 @@ Other Changes: - 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: GLFW: Submit keys using io.AddKeyEvent(). Submit keymods using io.AddKeyModsEvent() at the same time. (#2625) - Backends: GLFW: Update mouse position using glfwSetCursorPosCallback() + fallback when focused but not hovered/captured. +- Backends: Win32: Submit keys using io.AddKeyEvent(). Submit keymods using io.AddKeyModsEvent() at the same time. (#2625) - Backends: Win32: Update mouse position using WM_MOUSEMOVE/WM_MOUSELEAVE + fallback when focused but not hovered/captured. - Backends: Win32: Maintain a MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted. - Backends: SDL: Pass localized keys (matching keyboard layout). Fix e.g. CTRL+A, CTRL+Z, CTRL+Y shortcuts. +- Backends: SDL: Submit keys using io.AddKeyEvent(). Submit keymods using io.AddKeyModsEvent() at the same time. (#2625) - Backends: SDL: Update mouse position using SDL_MOUSEMOTION/SDL_WINDOWEVENT_LEAVE + fallback when focused but not hovered/captured. - Backends: SDL: Maintain a MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted. -- Backends: Allegro5, GLFW, GLUT, SDL, OSX, Win32, Android: Updated to use io.AddKeyEvent() with full key range. (#2625) [@thedmd] +- Backends: Allegro5: Submit keys using io.AddKeyEvent(). Submit keymods using io.AddKeyModsEvent() at the same time. (#2625) +- Backends: Android, GLUT, OSX: Submit keys using io.AddKeyEvent(). Submit keymods using io.AddKeyModsEvent() at the same time. (#2625) - 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. - Backends: Metal: Added Apple Metal C++ API support. (#4824, #4746) [@luigifcruz]