Version/Branch of Dear ImGui:
Version 1.92.8 WIP, Branch: docking
Back-ends:
imgui_impl_glfw.cpp + imgui_impl_opengl3.cpp
Compiler, OS:
Linux Ubuntu 22.04, GCC 11.4.0, X11/GNOME Shell, kernel 6.8.0
Full config/build information:
ImGuiConfigFlags_NavEnableKeyboard | ImGuiConfigFlags_DockingEnable | ImGuiConfigFlags_ViewportsEnable
Details:
My Issue / Question:
When a window is undocked into a secondary viewport (a separate OS window), it
cannot be dragged beyond the monitor edge — it hits an invisible wall — even
though the main GLFW window and other native apps (e.g. VSCode) can freely cross
that boundary.
Additionally, while the secondary viewport is at or near the monitor edge, the
rendered content (e.g. a crosshair drawn at mouse coordinates) appears visually
offset from the actual cursor position.
Root cause (traced in source):
-
Monitor-edge wall — ClampWindowPos in imgui.cpp (around the
window->ViewportOwned branch, ~line 8257–8272) limits the window position to
monitor->WorkPos + monitor->WorkSize expanded by -visibility_padding
(default DisplayWindowPadding = {19, 19}). The PlatformMonitorsFullWorkRect
path that allows straddling (#7299, #3071) is only entered when
g.MovingWindow != NULL && window->RootWindowDockTree == g.MovingWindow->RootWindowDockTree.
During a viewport-owned drag this condition is met, but visibility_rect is
then expanded by -visibility_padding which still applies 19 px of clamping —
the window can get close to the edge but not past it.
-
Content shift — NewFrame() sets viewport->Pos to the desired position
(cursor − grab delta, which may be beyond the monitor edge).
TranslateWindowsInViewport has already shifted imgui child windows to
LastPlatformPos (the actual OS position, clamped by the WM).
So after NewFrame():
- ImGui child-window global coordinates are based on
P_actual
viewport->Pos (== DisplayPos) equals P_desired
- Result: every pixel in the viewport is rendered with a
P_actual − P_desired offset → crosshair and mouse-position overlays
appear shifted by the "overshoot" amount.
Expected behavior:
Secondary viewports should be draggable beyond the monitor edge the same way the
main window is (the OS/WM ultimately controls whether the window actually moves).
Rendered content should never appear shifted relative to the cursor while dragging
near a monitor boundary.
Steps to reproduce:
- Enable
ImGuiConfigFlags_ViewportsEnable.
- Undock any window so it becomes a secondary OS window.
- Drag the secondary window toward and past the monitor edge.
→ Window stops at ~19 px from the edge (the DisplayWindowPadding limit).
- While it is stopped at the edge, content rendered at
io.MousePos (e.g. a
crosshair) appears shifted by the amount the drag "wanted" to move the window
further.
Screenshots/Video:
No response
Minimal, Complete and Verifiable Example code:
// Standard docking+viewports example (Dear ImGui demo is sufficient to reproduce).
// 1. Run imgui_demo with viewports enabled on Linux/X11.
// 2. Undock "Dear ImGui Demo" window (drag it out of the main window).
// 3. Draw a crosshair at io.MousePos inside the secondary window's Begin/End.
// 4. Drag the secondary window to a monitor edge.
// Observe: window stops moving before the edge; crosshair shifts from cursor.
ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Once);
ImGui::Begin("Viewport test");
ImVec2 p = ImGui::GetMousePos();
ImGui::GetForegroundDrawList()->AddLine({p.x - 10, p.y}, {p.x + 10, p.y},
IM_COL32(255, 0, 0, 255));
ImGui::GetForegroundDrawList()->AddLine({p.x, p.y - 10}, {p.x, p.y + 10},
IM_COL32(255, 0, 0, 255));
ImGui::End();
Version/Branch of Dear ImGui:
Version 1.92.8 WIP, Branch: docking
Back-ends:
imgui_impl_glfw.cpp + imgui_impl_opengl3.cpp
Compiler, OS:
Linux Ubuntu 22.04, GCC 11.4.0, X11/GNOME Shell, kernel 6.8.0
Full config/build information:
ImGuiConfigFlags_NavEnableKeyboard | ImGuiConfigFlags_DockingEnable | ImGuiConfigFlags_ViewportsEnable
Details:
My Issue / Question:
When a window is undocked into a secondary viewport (a separate OS window), it
cannot be dragged beyond the monitor edge — it hits an invisible wall — even
though the main GLFW window and other native apps (e.g. VSCode) can freely cross
that boundary.
Additionally, while the secondary viewport is at or near the monitor edge, the
rendered content (e.g. a crosshair drawn at mouse coordinates) appears visually
offset from the actual cursor position.
Root cause (traced in source):
Monitor-edge wall —
ClampWindowPosinimgui.cpp(around thewindow->ViewportOwnedbranch, ~line 8257–8272) limits the window position tomonitor->WorkPos + monitor->WorkSizeexpanded by-visibility_padding(default
DisplayWindowPadding = {19, 19}). ThePlatformMonitorsFullWorkRectpath that allows straddling (
#7299, #3071) is only entered wheng.MovingWindow != NULL && window->RootWindowDockTree == g.MovingWindow->RootWindowDockTree.During a viewport-owned drag this condition is met, but
visibility_rectisthen expanded by
-visibility_paddingwhich still applies 19 px of clamping —the window can get close to the edge but not past it.
Content shift —
NewFrame()setsviewport->Posto the desired position(cursor − grab delta, which may be beyond the monitor edge).
TranslateWindowsInViewporthas already shifted imgui child windows toLastPlatformPos(the actual OS position, clamped by the WM).So after
NewFrame():P_actualviewport->Pos(==DisplayPos) equalsP_desiredP_actual − P_desiredoffset → crosshair and mouse-position overlaysappear shifted by the "overshoot" amount.
Expected behavior:
Secondary viewports should be draggable beyond the monitor edge the same way the
main window is (the OS/WM ultimately controls whether the window actually moves).
Rendered content should never appear shifted relative to the cursor while dragging
near a monitor boundary.
Steps to reproduce:
ImGuiConfigFlags_ViewportsEnable.→ Window stops at ~19 px from the edge (the
DisplayWindowPaddinglimit).io.MousePos(e.g. acrosshair) appears shifted by the amount the drag "wanted" to move the window
further.
Screenshots/Video:
No response
Minimal, Complete and Verifiable Example code:
// Standard docking+viewports example (Dear ImGui demo is sufficient to reproduce).
// 1. Run imgui_demo with viewports enabled on Linux/X11.
// 2. Undock "Dear ImGui Demo" window (drag it out of the main window).
// 3. Draw a crosshair at io.MousePos inside the secondary window's Begin/End.
// 4. Drag the secondary window to a monitor edge.
// Observe: window stops moving before the edge; crosshair shifts from cursor.
ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Once);
ImGui::Begin("Viewport test");
ImVec2 p = ImGui::GetMousePos();
ImGui::GetForegroundDrawList()->AddLine({p.x - 10, p.y}, {p.x + 10, p.y},
IM_COL32(255, 0, 0, 255));
ImGui::GetForegroundDrawList()->AddLine({p.x, p.y - 10}, {p.x, p.y + 10},
IM_COL32(255, 0, 0, 255));
ImGui::End();