Need advice for dealing with "global mouse" stuff being unreliable with SDL2
Version/Branch of Dear ImGui:
Version 1.91,5 Branch: master
Back-ends:
imgui_impl_sdl2.cpp + imgui_impl_opengl3.cpp
Compiler, OS:
Linux, GCC 14, SDL 2.30.9
Full config/build information:
Dear ImGui 1.91.5 (19150)
--------------------------------
sizeof(size_t): 8, sizeof(ImDrawIdx): 2, sizeof(ImDrawVert): 20
define: __cplusplus=202002
define: IMGUI_DISABLE_OBSOLETE_FUNCTIONS
define: __linux__
define: __GNUC__=14
--------------------------------
io.BackendPlatformName: imgui_impl_sdl2
io.BackendRendererName: imgui_impl_opengl3
io.ConfigFlags: 0x00000001
NavEnableKeyboard
io.ConfigNavCaptureKeyboard
io.ConfigInputTextCursorBlink
io.ConfigWindowsResizeFromEdges
io.ConfigMemoryCompactTimer = 60.0
io.BackendFlags: 0x0000000E
HasMouseCursors
HasSetMousePos
RendererHasVtxOffset
--------------------------------
io.Fonts: 4 fonts, Flags: 0x00000000, TexSize: 512,128
io.DisplaySize: 956.00,509.00
io.DisplayFramebufferScale: 1.00,1.00
--------------------------------
style.WindowPadding: 8.00,8.00
style.WindowBorderSize: 1.00
style.FramePadding: 5.00,3.00
style.FrameRounding: 3.00
style.FrameBorderSize: 0.00
style.ItemSpacing: 6.00,6.00
style.ItemInnerSpacing: 3.00,3.00
Details:
My Issue/Question:
I'm trying to use ImGui in a child window of an existing X11 window. The "host" code gives me the parent window, I create a new window with SDL2 and call XReparentWindow(). The side effect of this is that the result of SDL_GetWindowPosition() seems to no longer be valid (I assume a child window does not receive the messages required for updating position) and this causes this function to generate mouse events with incorrect position:
static void ImGui_ImplSDL2_UpdateMouseData()
{
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
ImGuiIO& io = ImGui::GetIO();
// We forward mouse input when hovered or captured (via SDL_MOUSEMOTION) or when focused (below)
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
// 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
SDL_CaptureMouse((bd->MouseButtonsDown != 0) ? SDL_TRUE : SDL_FALSE);
SDL_Window* focused_window = SDL_GetKeyboardFocus();
const bool is_app_focused = (bd->Window == focused_window);
#else
const bool is_app_focused = (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_INPUT_FOCUS) != 0; // SDL 2.0.3 and non-windowed systems: single-viewport only
#endif
if (is_app_focused)
{
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when io.ConfigNavMoveSetMousePos is enabled by user)
if (io.WantSetMousePos)
SDL_WarpMouseInWindow(bd->Window, (int)io.MousePos.x, (int)io.MousePos.y);
// (Optional) Fallback to provide mouse position when focused (SDL_MOUSEMOTION already provides this when hovered or captured)
if (bd->MouseCanUseGlobalState && bd->MouseButtonsDown == 0)
{
int window_x, window_y, mouse_x_global, mouse_y_global;
SDL_GetGlobalMouseState(&mouse_x_global, &mouse_y_global);
SDL_GetWindowPosition(bd->Window, &window_x, &window_y);
io.AddMousePosEvent((float)(mouse_x_global - window_x), (float)(mouse_y_global - window_y));
}
}
}
- What would be the right workaround? Naively, I'd just want to set
bd->MouseCanUseGlobalStatetofalseand let the mouse motion events track the mouse pointer. Can I do it without patching ImGui source code? - Or maybe there is a way to fix window position stuff after reparenting?
Screenshots/Video:
No response
Minimal, Complete and Verifiable Example code:
No response
Note that f61a7ef22 (Sept 2025) has reduced the scope of using SDL_GetGlobalMouseState() to situation where your application window is NOT hovered only. So it should largely mitigate the issue.
I don't quite understand your child/reparenting thing (please post a video with Debug Log->IO values visible) but there is a possibility that updating to latest would fix the issue.
Thanks for looking into it.
I haven't touched this topic for a while; I'll try to see what changes with the update. Looking at the diff I would think it indeed fixes most issues.
The original issue is that after reparenting, the return value of SDL_GetWindowPosition() is wrong.