mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-31 21:21:06 +01:00 
			
		
		
		
	Backends: Win32, SDL, GLFW: only honor io.WantSetMousePos when focused + fix GLFW uninstalling handler + tweaks to reduce branch drift with docking. (#787, #2445, #2696, #3751, #4377)
This commit is contained in:
		| @@ -55,7 +55,7 @@ | |||||||
| #define GLFW_HAS_WINDOW_ALPHA         (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ glfwSetWindowOpacity | #define GLFW_HAS_WINDOW_ALPHA         (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ glfwSetWindowOpacity | ||||||
| #define GLFW_HAS_PER_MONITOR_DPI      (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ glfwGetMonitorContentScale | #define GLFW_HAS_PER_MONITOR_DPI      (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ glfwGetMonitorContentScale | ||||||
| #define GLFW_HAS_VULKAN               (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3200) // 3.2+ glfwCreateWindowSurface | #define GLFW_HAS_VULKAN               (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3200) // 3.2+ glfwCreateWindowSurface | ||||||
| #ifdef GLFW_RESIZE_NESW_CURSOR  // let's be nice to people who pulled GLFW between 2019-04-16 (3.4 define) and 2019-11-29 (cursors defines) // FIXME: Remove when GLFW 3.4 is released? | #ifdef GLFW_RESIZE_NESW_CURSOR        // Let's be nice to people who pulled GLFW between 2019-04-16 (3.4 define) and 2019-11-29 (cursors defines) // FIXME: Remove when GLFW 3.4 is released? | ||||||
| #define GLFW_HAS_NEW_CURSORS          (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3400) // 3.4+ GLFW_RESIZE_ALL_CURSOR, GLFW_RESIZE_NESW_CURSOR, GLFW_RESIZE_NWSE_CURSOR, GLFW_NOT_ALLOWED_CURSOR | #define GLFW_HAS_NEW_CURSORS          (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3400) // 3.4+ GLFW_RESIZE_ALL_CURSOR, GLFW_RESIZE_NESW_CURSOR, GLFW_RESIZE_NWSE_CURSOR, GLFW_NOT_ALLOWED_CURSOR | ||||||
| #else | #else | ||||||
| #define GLFW_HAS_NEW_CURSORS          (0) | #define GLFW_HAS_NEW_CURSORS          (0) | ||||||
| @@ -116,7 +116,7 @@ static void ImGui_ImplGlfw_SetClipboardText(void* user_data, const char* text) | |||||||
| void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods) | void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods) | ||||||
| { | { | ||||||
|     ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); |     ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); | ||||||
|     if (bd->PrevUserCallbackMousebutton != NULL) |     if (bd->PrevUserCallbackMousebutton != NULL && window == bd->Window) | ||||||
|         bd->PrevUserCallbackMousebutton(window, button, action, mods); |         bd->PrevUserCallbackMousebutton(window, button, action, mods); | ||||||
|  |  | ||||||
|     if (action == GLFW_PRESS && button >= 0 && button < IM_ARRAYSIZE(bd->MouseJustPressed)) |     if (action == GLFW_PRESS && button >= 0 && button < IM_ARRAYSIZE(bd->MouseJustPressed)) | ||||||
| @@ -126,7 +126,7 @@ void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int acti | |||||||
| void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset) | void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset) | ||||||
| { | { | ||||||
|     ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); |     ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); | ||||||
|     if (bd->PrevUserCallbackScroll != NULL) |     if (bd->PrevUserCallbackScroll != NULL && window == bd->Window) | ||||||
|         bd->PrevUserCallbackScroll(window, xoffset, yoffset); |         bd->PrevUserCallbackScroll(window, xoffset, yoffset); | ||||||
|  |  | ||||||
|     ImGuiIO& io = ImGui::GetIO(); |     ImGuiIO& io = ImGui::GetIO(); | ||||||
| @@ -137,7 +137,7 @@ void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yo | |||||||
| void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) | void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) | ||||||
| { | { | ||||||
|     ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); |     ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); | ||||||
|     if (bd->PrevUserCallbackKey != NULL) |     if (bd->PrevUserCallbackKey != NULL && window == bd->Window) | ||||||
|         bd->PrevUserCallbackKey(window, key, scancode, action, mods); |         bd->PrevUserCallbackKey(window, key, scancode, action, mods); | ||||||
|  |  | ||||||
|     ImGuiIO& io = ImGui::GetIO(); |     ImGuiIO& io = ImGui::GetIO(); | ||||||
| @@ -174,7 +174,7 @@ void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered) | |||||||
| void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c) | void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c) | ||||||
| { | { | ||||||
|     ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); |     ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); | ||||||
|     if (bd->PrevUserCallbackChar != NULL) |     if (bd->PrevUserCallbackChar != NULL && window == bd->Window) | ||||||
|         bd->PrevUserCallbackChar(window, c); |         bd->PrevUserCallbackChar(window, c); | ||||||
|  |  | ||||||
|     ImGuiIO& io = ImGui::GetIO(); |     ImGuiIO& io = ImGui::GetIO(); | ||||||
| @@ -298,6 +298,7 @@ void ImGui_ImplGlfw_Shutdown() | |||||||
|  |  | ||||||
|     if (bd->InstalledCallbacks) |     if (bd->InstalledCallbacks) | ||||||
|     { |     { | ||||||
|  |         glfwSetCursorEnterCallback(bd->Window, bd->PrevUserCallbackCursorEnter); | ||||||
|         glfwSetMouseButtonCallback(bd->Window, bd->PrevUserCallbackMousebutton); |         glfwSetMouseButtonCallback(bd->Window, bd->PrevUserCallbackMousebutton); | ||||||
|         glfwSetScrollCallback(bd->Window, bd->PrevUserCallbackScroll); |         glfwSetScrollCallback(bd->Window, bd->PrevUserCallbackScroll); | ||||||
|         glfwSetKeyCallback(bd->Window, bd->PrevUserCallbackKey); |         glfwSetKeyCallback(bd->Window, bd->PrevUserCallbackKey); | ||||||
| @@ -316,32 +317,32 @@ void ImGui_ImplGlfw_Shutdown() | |||||||
| static void ImGui_ImplGlfw_UpdateMousePosAndButtons() | static void ImGui_ImplGlfw_UpdateMousePosAndButtons() | ||||||
| { | { | ||||||
|     ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); |     ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); | ||||||
|  |  | ||||||
|     // Update buttons |  | ||||||
|     ImGuiIO& io = ImGui::GetIO(); |     ImGuiIO& io = ImGui::GetIO(); | ||||||
|  |  | ||||||
|  |     const ImVec2 mouse_pos_prev = io.MousePos; | ||||||
|  |     io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); | ||||||
|  |  | ||||||
|  |     // Update mouse buttons | ||||||
|  |     // (if a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame) | ||||||
|     for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) |     for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) | ||||||
|     { |     { | ||||||
|         // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. |  | ||||||
|         io.MouseDown[i] = bd->MouseJustPressed[i] || glfwGetMouseButton(bd->Window, i) != 0; |         io.MouseDown[i] = bd->MouseJustPressed[i] || glfwGetMouseButton(bd->Window, i) != 0; | ||||||
|         bd->MouseJustPressed[i] = false; |         bd->MouseJustPressed[i] = false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| #ifdef __EMSCRIPTEN__ | #ifdef __EMSCRIPTEN__ | ||||||
|     const bool focused = true; // Emscripten |     const bool focused = true; | ||||||
| #else | #else | ||||||
|     const bool focused = glfwGetWindowAttrib(bd->Window, GLFW_FOCUSED) != 0; |     const bool focused = glfwGetWindowAttrib(bd->Window, GLFW_FOCUSED) != 0; | ||||||
| #endif | #endif | ||||||
|     GLFWwindow* mouse_window = (bd->MouseWindow == bd->Window || focused) ? bd->Window : NULL; |     GLFWwindow* mouse_window = (bd->MouseWindow == bd->Window || focused) ? bd->Window : NULL; | ||||||
|  |  | ||||||
|     // Update mouse position |     // Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) | ||||||
|     const ImVec2 mouse_pos_backup = io.MousePos; |     if (io.WantSetMousePos && focused) | ||||||
|     io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); |         glfwSetCursorPos(bd->Window, (double)mouse_pos_prev.x, (double)mouse_pos_prev.y); | ||||||
|     if (io.WantSetMousePos) |  | ||||||
|     { |     // Set Dear ImGui mouse position from OS position | ||||||
|         if (focused) |     if (mouse_window != NULL) | ||||||
|             glfwSetCursorPos(bd->Window, (double)mouse_pos_backup.x, (double)mouse_pos_backup.y); |  | ||||||
|     } |  | ||||||
|     else if (mouse_window != NULL) |  | ||||||
|     { |     { | ||||||
|         double mouse_x, mouse_y; |         double mouse_x, mouse_y; | ||||||
|         glfwGetCursorPos(mouse_window, &mouse_x, &mouse_y); |         glfwGetCursorPos(mouse_window, &mouse_x, &mouse_y); | ||||||
|   | |||||||
| @@ -59,10 +59,11 @@ | |||||||
| #include "TargetConditionals.h" | #include "TargetConditionals.h" | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE    SDL_VERSION_ATLEAST(2,0,4) | #define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE    (SDL_VERSION_ATLEAST(2,0,4) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS)) | ||||||
| #define SDL_HAS_MOUSE_FOCUS_CLICKTHROUGH    SDL_VERSION_ATLEAST(2,0,5) | #define SDL_HAS_MOUSE_FOCUS_CLICKTHROUGH    SDL_VERSION_ATLEAST(2,0,5) | ||||||
| #define SDL_HAS_VULKAN                      SDL_VERSION_ATLEAST(2,0,6) | #define SDL_HAS_VULKAN                      SDL_VERSION_ATLEAST(2,0,6) | ||||||
|  |  | ||||||
|  | // SDL Data | ||||||
| struct ImGui_ImplSDL2_Data | struct ImGui_ImplSDL2_Data | ||||||
| { | { | ||||||
|     SDL_Window* Window; |     SDL_Window* Window; | ||||||
| @@ -156,6 +157,17 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window) | |||||||
|     ImGuiIO& io = ImGui::GetIO(); |     ImGuiIO& io = ImGui::GetIO(); | ||||||
|     IM_ASSERT(io.BackendPlatformUserData == NULL && "Already initialized a platform backend!"); |     IM_ASSERT(io.BackendPlatformUserData == NULL && "Already initialized a platform backend!"); | ||||||
|  |  | ||||||
|  |     // Check and store if we are on a SDL backend that supports global mouse position | ||||||
|  |     // ("wayland" and "rpi" don't support it, but we chose to use a white-list instead of a black-list) | ||||||
|  |     const char* sdl_backend = SDL_GetCurrentVideoDriver(); | ||||||
|  |     const char* global_mouse_whitelist[] = { "windows", "cocoa", "x11", "DIVE", "VMAN" }; | ||||||
|  |     bool mouse_can_use_global_state = false; | ||||||
|  | #if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE | ||||||
|  |     for (int n = 0; n < IM_ARRAYSIZE(global_mouse_whitelist); n++) | ||||||
|  |         if (strncmp(sdl_backend, global_mouse_whitelist[n], strlen(global_mouse_whitelist[n])) == 0) | ||||||
|  |             mouse_can_use_global_state = true; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|     // Setup backend capabilities flags |     // Setup backend capabilities flags | ||||||
|     ImGui_ImplSDL2_Data* bd = IM_NEW(ImGui_ImplSDL2_Data)(); |     ImGui_ImplSDL2_Data* bd = IM_NEW(ImGui_ImplSDL2_Data)(); | ||||||
|     io.BackendPlatformUserData = (void*)bd; |     io.BackendPlatformUserData = (void*)bd; | ||||||
| @@ -164,6 +176,7 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window) | |||||||
|     io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos;        // We can honor io.WantSetMousePos requests (optional, rarely used) |     io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos;        // We can honor io.WantSetMousePos requests (optional, rarely used) | ||||||
|  |  | ||||||
|     bd->Window = window; |     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. |     // 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_Tab] = SDL_SCANCODE_TAB; | ||||||
| @@ -204,20 +217,11 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window) | |||||||
|     bd->MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND); |     bd->MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND); | ||||||
|     bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO); |     bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO); | ||||||
|  |  | ||||||
|     // Check and store if we are on a SDL backend that supports global mouse position |  | ||||||
|     // ("wayland" and "rpi" don't support it, but we chose to use a white-list instead of a black-list) |  | ||||||
|     const char* sdl_backend = SDL_GetCurrentVideoDriver(); |  | ||||||
|     const char* global_mouse_whitelist[] = { "windows", "cocoa", "x11", "DIVE", "VMAN" }; |  | ||||||
|     bd->MouseCanUseGlobalState = false; |  | ||||||
|     for (int n = 0; n < IM_ARRAYSIZE(global_mouse_whitelist); n++) |  | ||||||
|         if (strncmp(sdl_backend, global_mouse_whitelist[n], strlen(global_mouse_whitelist[n])) == 0) |  | ||||||
|             bd->MouseCanUseGlobalState = true; |  | ||||||
|  |  | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
|     SDL_SysWMinfo wmInfo; |     SDL_SysWMinfo info; | ||||||
|     SDL_VERSION(&wmInfo.version); |     SDL_VERSION(&info.version); | ||||||
|     SDL_GetWindowWMInfo(window, &wmInfo); |     if (SDL_GetWindowWMInfo(window, &info)) | ||||||
|     io.ImeWindowHandle = wmInfo.info.win.window; |         io.ImeWindowHandle = info.info.win.window; | ||||||
| #else | #else | ||||||
|     (void)window; |     (void)window; | ||||||
| #endif | #endif | ||||||
| @@ -278,55 +282,59 @@ void ImGui_ImplSDL2_Shutdown() | |||||||
|  |  | ||||||
| static void ImGui_ImplSDL2_UpdateMousePosAndButtons() | static void ImGui_ImplSDL2_UpdateMousePosAndButtons() | ||||||
| { | { | ||||||
|     ImGuiIO& io = ImGui::GetIO(); |  | ||||||
|     ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData(); |     ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData(); | ||||||
|  |     ImGuiIO& io = ImGui::GetIO(); | ||||||
|  |  | ||||||
|     // Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) |     ImVec2 mouse_pos_prev = io.MousePos; | ||||||
|     if (io.WantSetMousePos) |     io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); | ||||||
|         SDL_WarpMouseInWindow(bd->Window, (int)io.MousePos.x, (int)io.MousePos.y); |  | ||||||
|     else |  | ||||||
|         io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); |  | ||||||
|  |  | ||||||
|     int mx, my; |     // Update mouse buttons | ||||||
|     Uint32 mouse_buttons = SDL_GetMouseState(&mx, &my); |     int mouse_x_local, mouse_y_local; | ||||||
|  |     Uint32 mouse_buttons = SDL_GetMouseState(&mouse_x_local, &mouse_y_local); | ||||||
|     io.MouseDown[0] = bd->MousePressed[0] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0;  // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. |     io.MouseDown[0] = bd->MousePressed[0] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0;  // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. | ||||||
|     io.MouseDown[1] = bd->MousePressed[1] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; |     io.MouseDown[1] = bd->MousePressed[1] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; | ||||||
|     io.MouseDown[2] = bd->MousePressed[2] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; |     io.MouseDown[2] = bd->MousePressed[2] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; | ||||||
|     bd->MousePressed[0] = bd->MousePressed[1] = bd->MousePressed[2] = false; |     bd->MousePressed[0] = bd->MousePressed[1] = bd->MousePressed[2] = false; | ||||||
|  |  | ||||||
| #if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS) |     // Obtain focused and hovered window. We forward mouse input when focused or when hovered (and no other window is capturing) | ||||||
|     SDL_Window* focused_window = SDL_GetKeyboardFocus(); // Mouse position won't be reported unless window is focused. | #if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE | ||||||
| #if SDL_HAS_MOUSE_FOCUS_CLICKTHROUGH |     SDL_Window* focused_window = SDL_GetKeyboardFocus(); | ||||||
|     SDL_Window* hovered_window = SDL_GetMouseFocus();    // This is better but is only reliably useful with SDL 2.0.5+ and SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH enabled. |     SDL_Window* hovered_window = SDL_HAS_MOUSE_FOCUS_CLICKTHROUGH ? SDL_GetMouseFocus() : NULL; // This is better but is only reliably useful with SDL 2.0.5+ and SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH. | ||||||
|     SDL_Window* mouse_window = (bd->Window == focused_window || bd->Window == hovered_window) ? bd->Window : NULL; |     SDL_Window* mouse_window = NULL; | ||||||
| #else |     if (hovered_window && bd->Window == hovered_window) | ||||||
|     SDL_Window* mouse_window = (bd->Window == focused_window) ? bd->Window : NULL; |         mouse_window = hovered_window; | ||||||
| #endif |     else if (focused_window && bd->Window == focused_window) | ||||||
|     if (mouse_window != NULL) |         mouse_window = focused_window; | ||||||
|     { |  | ||||||
|         if (bd->MouseCanUseGlobalState) |  | ||||||
|         { |  | ||||||
|             // SDL_GetMouseState() gives mouse position seemingly based on the last window entered/focused(?) |  | ||||||
|             // The creation of a new windows at runtime and SDL_CaptureMouse both seems to severely mess up with that, so we retrieve that position globally. |  | ||||||
|             // Won't use this workaround on SDL backends that have no global mouse position, like Wayland or RPI |  | ||||||
|             int wx, wy; |  | ||||||
|             SDL_GetWindowPosition(mouse_window, &wx, &wy); |  | ||||||
|             SDL_GetGlobalMouseState(&mx, &my); |  | ||||||
|             mx -= wx; |  | ||||||
|             my -= wy; |  | ||||||
|         } |  | ||||||
|         io.MousePos = ImVec2((float)mx, (float)my); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. trigger the OS window resize cursor. |     // SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. trigger other operations outside | ||||||
|     // The function is only supported from SDL 2.0.4 (released Jan 2016) |     SDL_CaptureMouse(ImGui::IsAnyMouseDown() ? SDL_TRUE : SDL_FALSE); | ||||||
|     bool any_mouse_button_down = ImGui::IsAnyMouseDown(); |  | ||||||
|     SDL_CaptureMouse(any_mouse_button_down ? SDL_TRUE : SDL_FALSE); |  | ||||||
| #else | #else | ||||||
|     // SDL 2.0.3 and non-windowed systems |     // SDL 2.0.3 and non-windowed systems: single-viewport only | ||||||
|     if (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_INPUT_FOCUS) |     SDL_Window* mouse_window = (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_INPUT_FOCUS) ? bd->Window : NULL; | ||||||
|         io.MousePos = ImVec2((float)mx, (float)my); |  | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  |     if (mouse_window == NULL) | ||||||
|  |        return; | ||||||
|  |  | ||||||
|  |     // Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) | ||||||
|  |     if (io.WantSetMousePos) | ||||||
|  |         SDL_WarpMouseInWindow(bd->Window, (int)mouse_pos_prev.x, (int)mouse_pos_prev.y); | ||||||
|  |  | ||||||
|  |     // Set Dear ImGui mouse position from OS position + get buttons. (this is the common behavior) | ||||||
|  |     if (bd->MouseCanUseGlobalState) | ||||||
|  |     { | ||||||
|  |         // Single-viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window) | ||||||
|  |         // Unlike local position obtained earlier this will be valid when straying out of bounds. | ||||||
|  |         int mouse_x_global, mouse_y_global; | ||||||
|  |         SDL_GetGlobalMouseState(&mouse_x_global, &mouse_y_global); | ||||||
|  |         int window_x, window_y; | ||||||
|  |         SDL_GetWindowPosition(mouse_window, &window_x, &window_y); | ||||||
|  |         io.MousePos = ImVec2((float)(mouse_x_global - window_x), (float)(mouse_y_global - window_y)); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         io.MousePos = ImVec2((float)mouse_x_local, (float)mouse_y_local); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| static void ImGui_ImplSDL2_UpdateMouseCursor() | static void ImGui_ImplSDL2_UpdateMouseCursor() | ||||||
| @@ -393,9 +401,9 @@ static void ImGui_ImplSDL2_UpdateGamepads() | |||||||
|  |  | ||||||
| void ImGui_ImplSDL2_NewFrame() | void ImGui_ImplSDL2_NewFrame() | ||||||
| { | { | ||||||
|     ImGuiIO& io = ImGui::GetIO(); |  | ||||||
|     ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData(); |     ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData(); | ||||||
|     IM_ASSERT(bd != NULL && "Did you call ImGui_ImplSDL2_Init()?"); |     IM_ASSERT(bd != NULL && "Did you call ImGui_ImplSDL2_Init()?"); | ||||||
|  |     ImGuiIO& io = ImGui::GetIO(); | ||||||
|  |  | ||||||
|     // Setup display size (every frame to accommodate for window resizing) |     // Setup display size (every frame to accommodate for window resizing) | ||||||
|     int w, h; |     int w, h; | ||||||
|   | |||||||
| @@ -219,31 +219,36 @@ static bool ImGui_ImplWin32_UpdateMouseCursor() | |||||||
|  |  | ||||||
| static void ImGui_ImplWin32_UpdateMousePos() | static void ImGui_ImplWin32_UpdateMousePos() | ||||||
| { | { | ||||||
|     ImGuiIO& io = ImGui::GetIO(); |  | ||||||
|     ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(); |     ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(); | ||||||
|  |     ImGuiIO& io = ImGui::GetIO(); | ||||||
|     IM_ASSERT(bd->hWnd != 0); |     IM_ASSERT(bd->hWnd != 0); | ||||||
|  |  | ||||||
|     // Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) |     const ImVec2 mouse_pos_prev = io.MousePos; | ||||||
|  |     io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); | ||||||
|  |  | ||||||
|  |     // Obtain focused and hovered window. We forward mouse input when focused or when hovered (and no other window is capturing) | ||||||
|  |     HWND focused_window = ::GetForegroundWindow(); | ||||||
|  |     HWND hovered_window = bd->MouseHwnd; | ||||||
|  |     HWND mouse_window = NULL; | ||||||
|  |     if (hovered_window && (hovered_window == bd->hWnd || ::IsChild(hovered_window, bd->hWnd))) | ||||||
|  |         mouse_window = hovered_window; | ||||||
|  |     else if (focused_window && (focused_window == bd->hWnd || ::IsChild(focused_window, bd->hWnd))) | ||||||
|  |         mouse_window = focused_window; | ||||||
|  |     if (mouse_window == NULL) | ||||||
|  |         return; | ||||||
|  |  | ||||||
|  |     // Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) | ||||||
|     if (io.WantSetMousePos) |     if (io.WantSetMousePos) | ||||||
|     { |     { | ||||||
|         POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y }; |         POINT pos = { (int)mouse_pos_prev.x, (int)mouse_pos_prev.y }; | ||||||
|         if (::ClientToScreen(bd->hWnd, &pos)) |         if (::ClientToScreen(bd->hWnd, &pos)) | ||||||
|             ::SetCursorPos(pos.x, pos.y); |             ::SetCursorPos(pos.x, pos.y); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Set mouse position |     // Set Dear ImGui mouse position from OS position | ||||||
|     io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); |  | ||||||
|     HWND focused_window = ::GetForegroundWindow(); |  | ||||||
|     HWND hovered_window = bd->MouseHwnd; |  | ||||||
|     HWND mouse_window = NULL; |  | ||||||
|     if (hovered_window && (hovered_window == bd->hWnd) || ::IsChild(hovered_window, bd->hWnd)) |  | ||||||
|         mouse_window = hovered_window; |  | ||||||
|     else if (focused_window && (focused_window == bd->hWnd) || ::IsChild(focused_window, bd->hWnd)) |  | ||||||
|         mouse_window = focused_window; |  | ||||||
|     POINT pos; |     POINT pos; | ||||||
|     if (mouse_window) |     if (::GetCursorPos(&pos) && ::ScreenToClient(mouse_window, &pos)) | ||||||
|         if (::GetCursorPos(&pos) && ::ScreenToClient(mouse_window, &pos)) |         io.MousePos = ImVec2((float)pos.x, (float)pos.y); | ||||||
|             io.MousePos = ImVec2((float)pos.x, (float)pos.y); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // Gamepad navigation mapping | // Gamepad navigation mapping | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user