Backends: GLFW: Mouse position is correctly reported when the host platform window is hovered but not focused. (#3751, #4377, #2445)

This commit is contained in:
ocornut 2021-07-29 18:59:45 +02:00
parent 1cdd110eb4
commit 044fd0cd2d
4 changed files with 43 additions and 20 deletions

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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]

View File

@ -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