Windows: add StopMouseMovingWindow(), partial merge 80d78fa from docking.

This commit is contained in:
ocornut
2025-07-30 18:39:15 +09:00
parent 87d7f7744e
commit 2ab3946ecb
2 changed files with 27 additions and 10 deletions

View File

@@ -4503,15 +4503,6 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window)
// Clear previous active id
if (g.ActiveId != 0)
{
// While most behaved code would make an effort to not steal active id during window move/drag operations,
// we at least need to be resilient to it. Canceling the move is rather aggressive and users of 'master' branch
// may prefer the weird ill-defined half working situation ('docking' did assert), so may need to rework that.
if (g.MovingWindow != NULL && g.ActiveId == g.MovingWindow->MoveId)
{
IMGUI_DEBUG_LOG_ACTIVEID("SetActiveID() cancel MovingWindow\n");
g.MovingWindow = NULL;
}
// Store deactivate data
ImGuiDeactivatedItemData* deactivated_data = &g.DeactivatedItemData;
deactivated_data->ID = g.ActiveId;
@@ -4524,6 +4515,15 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window)
// One common scenario leading to this is: pressing Key ->NavMoveRequestApplyResult() -> ClearActiveID()
if (g.InputTextState.ID == g.ActiveId)
InputTextDeactivateHook(g.ActiveId);
// While most behaved code would make an effort to not steal active id during window move/drag operations,
// we at least need to be resilient to it. Canceling the move is rather aggressive and users of 'master' branch
// may prefer the weird ill-defined half working situation ('docking' did assert), so may need to rework that.
if (g.MovingWindow != NULL && g.ActiveId == g.MovingWindow->MoveId)
{
IMGUI_DEBUG_LOG_ACTIVEID("SetActiveID() cancel MovingWindow\n");
StopMouseMovingWindow();
}
}
// Set active id
@@ -5077,6 +5077,19 @@ void ImGui::StartMouseMovingWindow(ImGuiWindow* window)
g.MovingWindow = window;
}
// This is not 100% symetric with StartMouseMovingWindow().
// We do NOT clear ActiveID, because:
// - It would lead to rather confusing recursive code paths. Caller can call ClearActiveID() if desired.
// - Some code intentionally cancel moving but keep the ActiveID to lock inputs (e.g. code path taken when clicking a disabled item).
void ImGui::StopMouseMovingWindow()
{
ImGuiContext& g = *GImGui;
// [nb: docking branch has more stuff in this function]
g.MovingWindow = NULL;
}
// Handle mouse moving window
// Note: moving window with the navigation keys (Square + d-pad / CTRL+TAB + Arrows) are processed in NavUpdateWindowing()
// FIXME: We don't have strong guarantee that g.MovingWindow stay synced with g.ActiveId == g.MovingWindow->MoveId.
@@ -5100,7 +5113,7 @@ void ImGui::UpdateMouseMovingWindowNewFrame()
}
else
{
g.MovingWindow = NULL;
StopMouseMovingWindow();
ClearActiveID();
}
}
@@ -5142,6 +5155,9 @@ void ImGui::UpdateMouseMovingWindowEndFrame()
{
StartMouseMovingWindow(g.HoveredWindow); //-V595
// FIXME: In principal we might be able to call StopMouseMovingWindow() below.
// Please note how StartMouseMovingWindow() and StopMouseMovingWindow() and not entirely symetrical, at the later doesn't clear ActiveId.
// Cancel moving if clicked outside of title bar
if (g.IO.ConfigWindowsMoveFromTitleBarOnly)
if (!(root_window->Flags & ImGuiWindowFlags_NoTitleBar))

View File

@@ -3150,6 +3150,7 @@ namespace ImGui
IMGUI_API void UpdateHoveredWindowAndCaptureFlags(const ImVec2& mouse_pos);
IMGUI_API void FindHoveredWindowEx(const ImVec2& pos, bool find_first_and_in_any_viewport, ImGuiWindow** out_hovered_window, ImGuiWindow** out_hovered_window_under_moving_window);
IMGUI_API void StartMouseMovingWindow(ImGuiWindow* window);
IMGUI_API void StopMouseMovingWindow();
IMGUI_API void UpdateMouseMovingWindowNewFrame();
IMGUI_API void UpdateMouseMovingWindowEndFrame();