Skip to content

Commit 6b77668

Browse files
committed
Viewports: Fixed a crash while a window owning its viewport disappear while being dragged.
t would manifest when e.g. reconfiguring dock nodes while dragging.
1 parent 9a49c1d commit 6b77668

File tree

2 files changed

+21
-12
lines changed

2 files changed

+21
-12
lines changed

docs/CHANGELOG.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,9 @@ Docking+Viewports Branch:
148148
- Docking: fixed settings load issue when mouse wheeling. (#4310)
149149
- Docking + Drag and Drop: Fixed using BeginDragDropSource() or BeginDragDropTarget() inside a Begin()
150150
that returned false because the window is docked. (#4515)
151-
- Viewports: Viewports: fixed unnecessary creation of temporary viewports when multiple docked windows
151+
- Viewports: Fixed a crash while a window owning its viewport disappear while being dragged.
152+
It would manifest when e.g. reconfiguring dock nodes while dragging.
153+
- Viewports: Fixed unnecessary creation of temporary viewports when multiple docked windows
152154
got reassigned to a new node (created mid-frame) which already has a HostWindow.
153155

154156

imgui.cpp

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3690,7 +3690,10 @@ void ImGui::UpdateMouseMovingWindowNewFrame()
36903690
KeepAliveID(g.ActiveId);
36913691
IM_ASSERT(g.MovingWindow && g.MovingWindow->RootWindowDockTree);
36923692
ImGuiWindow* moving_window = g.MovingWindow->RootWindowDockTree;
3693-
if (g.IO.MouseDown[0] && IsMousePosValid(&g.IO.MousePos))
3693+
3694+
// When a window stop being submitted while being dragged, it may will its viewport until next Begin()
3695+
const bool window_disappared = (!moving_window->WasActive || moving_window->Viewport == NULL);
3696+
if (g.IO.MouseDown[0] && IsMousePosValid(&g.IO.MousePos) && !window_disappared)
36943697
{
36953698
ImVec2 pos = g.IO.MousePos - g.ActiveIdClickOffset;
36963699
if (moving_window->Pos.x != pos.x || moving_window->Pos.y != pos.y)
@@ -3707,17 +3710,20 @@ void ImGui::UpdateMouseMovingWindowNewFrame()
37073710
}
37083711
else
37093712
{
3710-
// Try to merge the window back into the main viewport.
3711-
// This works because MouseViewport should be != MovingWindow->Viewport on release (as per code in UpdateViewports)
3712-
if (g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable)
3713-
UpdateTryMergeWindowIntoHostViewport(moving_window, g.MouseViewport);
3713+
if (!window_disappared)
3714+
{
3715+
// Try to merge the window back into the main viewport.
3716+
// This works because MouseViewport should be != MovingWindow->Viewport on release (as per code in UpdateViewports)
3717+
if (g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable)
3718+
UpdateTryMergeWindowIntoHostViewport(moving_window, g.MouseViewport);
37143719

3715-
// Restore the mouse viewport so that we don't hover the viewport _under_ the moved window during the frame we released the mouse button.
3716-
if (!IsDragDropPayloadBeingAccepted())
3717-
g.MouseViewport = moving_window->Viewport;
3720+
// Restore the mouse viewport so that we don't hover the viewport _under_ the moved window during the frame we released the mouse button.
3721+
if (!IsDragDropPayloadBeingAccepted())
3722+
g.MouseViewport = moving_window->Viewport;
37183723

3719-
// Clear the NoInput window flag set by the Viewport system
3720-
moving_window->Viewport->Flags &= ~ImGuiViewportFlags_NoInputs; // FIXME-VIEWPORT: Test engine managed to crash here because Viewport was NULL.
3724+
// Clear the NoInput window flag set by the Viewport system
3725+
moving_window->Viewport->Flags &= ~ImGuiViewportFlags_NoInputs; // FIXME-VIEWPORT: Test engine managed to crash here because Viewport was NULL.
3726+
}
37213727

37223728
g.MovingWindow = NULL;
37233729
ClearActiveID();
@@ -11855,7 +11861,8 @@ static void ImGui::UpdateViewportsNewFrame()
1185511861

1185611862
// Update mouse reference viewport
1185711863
// (when moving a window we aim at its viewport, but this will be overwritten below if we go in drag and drop mode)
11858-
if (g.MovingWindow)
11864+
// (MovingViewport->Viewport will be NULL in the rare situation where the window disappared while moving, set UpdateMouseMovingWindowNewFrame() for details)
11865+
if (g.MovingWindow && g.MovingWindow->Viewport)
1185911866
g.MouseViewport = g.MovingWindow->Viewport;
1186011867
else
1186111868
g.MouseViewport = g.MouseLastHoveredViewport;

0 commit comments

Comments
 (0)