mirror of
https://github.com/ocornut/imgui.git
synced 2025-09-05 19:08:19 +00:00
Windows, Viewport: fixed an issue where interrupting a viewport move with e.g. a ClearActiveID() call would leave the dragged viewport with the ImGuiViewportFlags_NoInputs flag.
Amend6b7766817
,36055213c5
, #5324. Next would be good to amend the ImGuiViewportFlags_NoInputs clear to match the set logic.
This commit is contained in:
@@ -62,6 +62,13 @@ Other Changes:
|
||||
- Backends: Vulkan: Fixed texture update corruption introduced in 1.92.0,
|
||||
affecting some drivers/setups. (#8801, #8755, #8840) [@Retro52, @Miolith]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Windows, Viewport: fixed an issue where interrupting a viewport move with
|
||||
e.g. a ClearActiveID() call would leave the dragged viewport with the
|
||||
normally temporary ImGuiViewportFlags_NoInputs flag, preventing further
|
||||
interactions with the viewport. (#5324) (thanks @mdelaharpe)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.92.1 (Released 2025-07-09)
|
||||
|
71
imgui.cpp
71
imgui.cpp
@@ -4606,15 +4606,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;
|
||||
@@ -4627,6 +4618,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
|
||||
@@ -5207,6 +5207,34 @@ void ImGui::StartMouseMovingWindowOrNode(ImGuiWindow* window, ImGuiDockNode* nod
|
||||
StartMouseMovingWindow(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;
|
||||
ImGuiWindow* window = g.MovingWindow;
|
||||
|
||||
// Ref commits 6b7766817, 36055213c for some partial history on checking if viewport != NULL.
|
||||
if (window && window->Viewport)
|
||||
{
|
||||
// Try to merge the window back into the main viewport.
|
||||
// This works because MouseViewport should be != MovingWindow->Viewport on release (as per code in UpdateViewports)
|
||||
if (g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable)
|
||||
UpdateTryMergeWindowIntoHostViewport(window, g.MouseViewport);
|
||||
|
||||
// Restore the mouse viewport so that we don't hover the viewport _under_ the moved window during the frame we released the mouse button.
|
||||
if (!IsDragDropPayloadBeingAccepted())
|
||||
g.MouseViewport = window->Viewport;
|
||||
|
||||
// Clear the NoInputs window flag set by the Viewport system in AddUpdateViewport()
|
||||
window->Viewport->Flags &= ~ImGuiViewportFlags_NoInputs;
|
||||
}
|
||||
|
||||
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.
|
||||
@@ -5224,8 +5252,8 @@ void ImGui::UpdateMouseMovingWindowNewFrame()
|
||||
ImGuiWindow* moving_window = g.MovingWindow->RootWindowDockTree;
|
||||
|
||||
// When a window stop being submitted while being dragged, it may will its viewport until next Begin()
|
||||
const bool window_disappared = (!moving_window->WasActive && !moving_window->Active);
|
||||
if (g.IO.MouseDown[0] && IsMousePosValid(&g.IO.MousePos) && !window_disappared)
|
||||
const bool window_disappeared = (!moving_window->WasActive && !moving_window->Active);
|
||||
if (g.IO.MouseDown[0] && IsMousePosValid(&g.IO.MousePos) && !window_disappeared)
|
||||
{
|
||||
ImVec2 pos = g.IO.MousePos - g.ActiveIdClickOffset;
|
||||
if (moving_window->Pos.x != pos.x || moving_window->Pos.y != pos.y)
|
||||
@@ -5241,23 +5269,7 @@ void ImGui::UpdateMouseMovingWindowNewFrame()
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!window_disappared)
|
||||
{
|
||||
// Try to merge the window back into the main viewport.
|
||||
// This works because MouseViewport should be != MovingWindow->Viewport on release (as per code in UpdateViewports)
|
||||
if (g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable)
|
||||
UpdateTryMergeWindowIntoHostViewport(moving_window, g.MouseViewport);
|
||||
|
||||
// Restore the mouse viewport so that we don't hover the viewport _under_ the moved window during the frame we released the mouse button.
|
||||
if (moving_window->Viewport && !IsDragDropPayloadBeingAccepted())
|
||||
g.MouseViewport = moving_window->Viewport;
|
||||
|
||||
// Clear the NoInput window flag set by the Viewport system
|
||||
if (moving_window->Viewport)
|
||||
moving_window->Viewport->Flags &= ~ImGuiViewportFlags_NoInputs;
|
||||
}
|
||||
|
||||
g.MovingWindow = NULL;
|
||||
StopMouseMovingWindow();
|
||||
ClearActiveID();
|
||||
}
|
||||
}
|
||||
@@ -5299,6 +5311,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) || root_window->DockIsActive)
|
||||
|
@@ -3382,6 +3382,7 @@ namespace ImGui
|
||||
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 StartMouseMovingWindowOrNode(ImGuiWindow* window, ImGuiDockNode* node, bool undock);
|
||||
IMGUI_API void StopMouseMovingWindow();
|
||||
IMGUI_API void UpdateMouseMovingWindowNewFrame();
|
||||
IMGUI_API void UpdateMouseMovingWindowEndFrame();
|
||||
|
||||
|
Reference in New Issue
Block a user