Version/Branch of Dear ImGui:
Version 1.92.8, Branch: docking
Back-ends:
imgui_impl_glfw.cpp + imgui_impl_opengl3.cpp
Compiler, OS:
Linux/X11, observed with GLFW + OpenGL3. This is easiest to reproduce with a window manager that clamps programmatic window positions near monitor edges, such as GNOME Shell/Mutter.
I have confirmed the issue across Dear ImGui versions from at least 1.90 through current docking HEAD, using GCC 13 and GCC 14. It has been reproduced on Debian 13, Ubuntu 24.04, Ubuntu under WSL, Red Hat Enterprise Linux 8, Red Hat Enterprise Linux 9, Rocky Linux 8, and Rocky Linux 9.
Full config/build information:
The repro enables:
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;The detached test window uses ImGuiViewportFlags_NoAutoMerge through ImGuiWindowClass so only that window becomes a secondary platform viewport.
Details:
When a secondary GLFW platform viewport is moved or programmatically requested near a monitor edge, the window manager may clamp the actual platform window position. Dear ImGui may continue to store the requested position in viewport->Pos, while glfwGetWindowPos() reports the actual clamped position.
Once those positions diverge, hit-testing/rendering in the secondary viewport can appear offset from the mouse cursor. Moving the viewport back into the interior of the monitor usually clears the mismatch.
The relevant backend behavior appears to be in ImGui_ImplGlfw_WindowPosCallback(). The backend intentionally ignores window-position callbacks for one frame after glfwSetWindowPos() so it does not process ordinary echo events. That makes sense when GLFW reports the same position Dear ImGui requested. But on X11, the callback may report a different position because the window manager clamped the platform window. Ignoring that callback leaves Dear ImGui synchronized to the requested position instead of the real platform position.
I opened a small PR that keeps the existing ignore behavior for exact echo events, but treats a different reported position as a real platform move:
https://github.com/ocornut/imgui/pull/9441
Related reports/discussion:
- https://github.com/ocornut/imgui/issues/9356
- https://github.com/ocornut/imgui/issues/9398
- https://github.com/ocornut/imgui/issues/8330
- https://github.com/ocornut/imgui/issues/8251
Screenshots/Video:
The repro displays both Dear ImGui's cached viewport position and the actual GLFW platform window position, which makes the mismatch visible numerically.
Normal expected layout: the main controls viewport and detached secondary viewport are both visible, and the secondary viewport reports Delta: (0, 0) / OK.
Bottom/left edge clamp on the affected backend: the detached viewport is clamped by the window manager, while Dear ImGui still has the requested position cached. The table shows MISMATCH, cached (-61, 1224), platform (0, 1128), delta (61, 96).
Top edge clamp on the affected backend: the same mismatch appears with a smaller top-edge delta, cached (958, -9), platform (959, 0).
Expected corrected behavior: after synchronizing to the actual platform position, the cached and GLFW platform positions match again and the status returns to OK.
Minimal, Complete and Verifiable Example code:
Minimal repro repository:
https://github.com/KBentley57/imgui-viewport-edge-repro
Build it against an unmodified v1.92.8-docking checkout:
cmake -S . \
-B /tmp/imgui_viewport_edge_repro_build \
-DIMGUI_SOURCE_DIR=/path/to/imgui \
-DCMAKE_PREFIX_PATH=/path/to/glfw/prefix
cmake --build /tmp/imgui_viewport_edge_repro_build -j"$(nproc)"
/tmp/imgui_viewport_edge_repro_build/imgui_viewport_edge_reproSteps:
- Leave
Apply platform position sync workaroundunchecked. - Click
Spawn / reset detached viewport. - Click
Request bottom-edge clampor drag the detached OS window into a monitor edge. - Compare
Cached viewport poswithGLFW platform pos. - Build the same repro against the PR branch and repeat.
With the affected backend, the cached and platform positions can diverge near the edge. With the PR branch, the backend should accept the clamped/different callback and converge back to the actual platform position.
Activity
0No activity yet.