From 044fd0cd2d976b31962689afa73c9824a6a08146 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 29 Jul 2021 18:59:45 +0200 Subject: [PATCH] Backends: GLFW: Mouse position is correctly reported when the host platform window is hovered but not focused. (#3751, #4377, #2445) --- backends/imgui_impl_glfw.cpp | 41 ++++++++++++++++++++++++------------ backends/imgui_impl_glfw.h | 3 ++- docs/CHANGELOG.txt | 17 ++++++++++----- imgui.h | 2 +- 4 files changed, 43 insertions(+), 20 deletions(-) diff --git a/backends/imgui_impl_glfw.cpp b/backends/imgui_impl_glfw.cpp index bcd25f16f..6e2e7fde3 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) +// 2021-07-29: *BREAKING CHANGE*: Inputs: MousePos is correctly reported when the host platform window is hovered but not focused (using glfwSetCursorEnterCallback). If you called ImGui_ImplGlfw_InitXXX() with install_callbacks = false, you MUST install the glfwSetCursorEnterCallback() callback and the forward to the backend via ImGui_ImplGlfw_CursorEnterCallback(). // 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). // 2020-01-17: Inputs: Disable error callback while assigning mouse cursors because some X11 setup don't have them and it generates errors. // 2019-12-05: Inputs: Added support for new mouse cursors added in GLFW 3.4+ (resizing cursors, not allowed cursor). @@ -73,11 +74,13 @@ struct ImGui_ImplGlfw_Data GLFWwindow* Window; GlfwClientApi ClientApi; double Time; + GLFWwindow* MouseWindow; bool MouseJustPressed[ImGuiMouseButton_COUNT]; GLFWcursor* MouseCursors[ImGuiMouseCursor_COUNT]; bool InstalledCallbacks; // Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any. + GLFWcursorenterfun PrevUserCallbackCursorEnter; GLFWmousebuttonfun PrevUserCallbackMousebutton; GLFWscrollfun PrevUserCallbackScroll; GLFWkeyfun PrevUserCallbackKey; @@ -157,6 +160,17 @@ void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int a #endif } +void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered) +{ + ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); + if (bd->PrevUserCallbackCursorEnter != NULL) + bd->PrevUserCallbackCursorEnter(window, entered); + if (entered) + bd->MouseWindow = window; + if (!entered && bd->MouseWindow == window) + bd->MouseWindow = NULL; +} + void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c) { ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); @@ -250,6 +264,7 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw if (install_callbacks) { bd->InstalledCallbacks = true; + bd->PrevUserCallbackCursorEnter = glfwSetCursorEnterCallback(window, ImGui_ImplGlfw_CursorEnterCallback); bd->PrevUserCallbackMousebutton = glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); bd->PrevUserCallbackScroll = glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); bd->PrevUserCallbackKey = glfwSetKeyCallback(window, ImGui_ImplGlfw_KeyCallback); @@ -311,26 +326,26 @@ static void ImGui_ImplGlfw_UpdateMousePosAndButtons() bd->MouseJustPressed[i] = false; } - // Update mouse position - const ImVec2 mouse_pos_backup = io.MousePos; - io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); #ifdef __EMSCRIPTEN__ const bool focused = true; // Emscripten #else const bool focused = glfwGetWindowAttrib(bd->Window, GLFW_FOCUSED) != 0; #endif - if (focused) + GLFWwindow* mouse_window = (bd->MouseWindow == bd->Window || focused) ? bd->Window : NULL; + + // Update mouse position + const ImVec2 mouse_pos_backup = io.MousePos; + io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); + if (io.WantSetMousePos) { - if (io.WantSetMousePos) - { + if (focused) glfwSetCursorPos(bd->Window, (double)mouse_pos_backup.x, (double)mouse_pos_backup.y); - } - else - { - double mouse_x, mouse_y; - glfwGetCursorPos(bd->Window, &mouse_x, &mouse_y); - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); - } + } + else if (mouse_window != NULL) + { + double mouse_x, mouse_y; + glfwGetCursorPos(mouse_window, &mouse_x, &mouse_y); + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); } } diff --git a/backends/imgui_impl_glfw.h b/backends/imgui_impl_glfw.h index 6d8a8cecb..4d718f0ac 100644 --- a/backends/imgui_impl_glfw.h +++ b/backends/imgui_impl_glfw.h @@ -8,7 +8,7 @@ // [x] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. FIXME: 3 cursors types are missing from GLFW. // [X] Platform: Keyboard arrays indexed using GLFW_KEY_* codes, e.g. ImGui::IsKeyPressed(GLFW_KEY_SPACE). -// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. // Read online: https://github.com/ocornut/imgui/tree/master/docs @@ -32,6 +32,7 @@ IMGUI_IMPL_API void ImGui_ImplGlfw_NewFrame(); // GLFW callbacks // - When calling Init with 'install_callbacks=true': GLFW callbacks will be installed for you. They will call user's previously installed callbacks, if any. // - When calling Init with 'install_callbacks=false': GLFW callbacks won't be installed. You will need to call those function yourself from your own GLFW callbacks. +IMGUI_IMPL_API void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered); IMGUI_IMPL_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); IMGUI_IMPL_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); IMGUI_IMPL_API void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 112fd8b6f..c960c3434 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -37,6 +37,13 @@ HOW TO UPDATE? Breaking Changes: +- Commented out redirecting functions/enums names that were marked obsolete in 1.67 and 1.69 (March 2019): + - ImGui::GetOverlayDrawList() -> use ImGui::GetForegroundDrawList() + - ImFont::GlyphRangesBuilder -> use ImFontGlyphRangesBuilder +- Backends: GLFW: backend now needs to use glfwSetCursorEnterCallback(). (#3751, #4377, #2445) + - If calling ImGui_ImplGlfw_InitXXX with install_callbacks=true: this is already done for you. + - If calling ImGui_ImplGlfw_InitXXX with install_callbacks=false: you WILL NEED to register the GLFW callback + with glfwSetCursorEnterCallback(), and forward events to the backend via ImGui_ImplGlfw_CursorEnterCallback(). - Backends: SDL2: removed unnecessary SDL_Window* parameter from ImGui_ImplSDL2_NewFrame(). (#3244) [@funchal] Kept inline redirection function (will obsolete). - Backends: SDL2: backend needs to set 'SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1")' in order to @@ -44,9 +51,6 @@ Breaking Changes: This is unfortunately a global SDL setting, so enabling it _might_ have a side-effect on your application. It is unlikely to make a difference, but if your app absolutely needs to ignore the initial on-focus click: you can ignore SDL_MOUSEBUTTONDOWN that events coming right after a SDL_WINDOWEVENT_FOCUS_GAINED event). -- Commented out redirecting functions/enums names that were marked obsolete in 1.67 and 1.69 (March 2019): - - ImGui::GetOverlayDrawList() -> use ImGui::GetForegroundDrawList() - - ImFont::GlyphRangesBuilder -> use ImFontGlyphRangesBuilder - Internals: (for custom widgets): because disabled items now sets HoveredId, if you want custom widgets to not react as hovered when disabled, in the majority of use cases it is preferable to check the "hovered" return value of ButtonBehavior() rather than (HoveredId == id). @@ -93,8 +97,11 @@ Other Changes: - ImGui_ImplWin32_EnableDpiAwareness() will call SetProcessDpiAwareness() fallback on Windows 8.1 without a manifest. - Backends: Win32: IME functions are disabled by default for non-Visual Studio compilers (MinGW etc.). Enable with '#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS' for those compilers. Undo change from 1.82. (#2590, #738, #4185, #4301) -- Backends: SDL2: Mouse position is correctly reported when the host platform window is hovered but not focused. - (requires SDL 2.0.5+ as SDL_GetMouseFocus() is only usable with SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH). (#3751, #4377, #2445) +- Backends: GLFW: Mouse position is correctly reported when the host window is hovered but not focused. (#3751, #4377, #2445) + (backend now uses glfwSetCursorEnterCallback(). If you called ImGui_ImplGlfw_InitXXX with install_callbacks=false, you will + need to install this callback and forward the data to the backend via ImGui_ImplGlfw_CursorEnterCallback). +- Backends: SDL2: Mouse position is correctly reported when the host window is hovered but not focused. (#3751, #4377, #2445) + (requires SDL 2.0.5+ as SDL_GetMouseFocus() is only usable with SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH). - Backends: DX9: Explicitly disable texture state stages after >= 1. (#4268) [@NZJenkins] - Backends: DX12: Fix texture casting crash on 32-bit systems (introduced on 2021/05/19 and v1.83) + added comments about building on 32-bit systems. (#4225) [@kingofthebongo2008] diff --git a/imgui.h b/imgui.h index 84e8a6b72..182c46a55 100644 --- a/imgui.h +++ b/imgui.h @@ -61,7 +61,7 @@ Index of this file: // Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens) #define IMGUI_VERSION "1.84 WIP" -#define IMGUI_VERSION_NUM 18312 +#define IMGUI_VERSION_NUM 18313 #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) #define IMGUI_HAS_TABLE