Docking: Fixed faulty undocking of windows with the _NoMove flag. (#2325, #2109)

Whereas BeginAsDockableDragDropTarget could be reworked to filter, we simply set g.HoveredWindowUnderMovingWindow to be NULL when MovingWindow is not set, which was the initial intent.
Also fixed some comments and removed unused braces in TabItemEx().
This commit is contained in:
omar 2019-01-31 14:59:45 +01:00
parent 578e15f006
commit 5536edede9
3 changed files with 20 additions and 22 deletions

View File

@ -3638,11 +3638,11 @@ void ImGui::NewFrame()
g.IO.Framerate = (g.FramerateSecPerFrameAccum > 0.0f) ? (1.0f / (g.FramerateSecPerFrameAccum / (float)IM_ARRAYSIZE(g.FramerateSecPerFrame))) : FLT_MAX; g.IO.Framerate = (g.FramerateSecPerFrameAccum > 0.0f) ? (1.0f / (g.FramerateSecPerFrameAccum / (float)IM_ARRAYSIZE(g.FramerateSecPerFrame))) : FLT_MAX;
// Undocking // Undocking
// (needs to be before UpdateMouseMovingWindow so the window is already offset and following the mouse on the detaching frame) // (needs to be before UpdateMouseMovingWindowNewFrame so the window is already offset and following the mouse on the detaching frame)
DockContextNewFrameUpdateUndocking(&g); DockContextNewFrameUpdateUndocking(&g);
// Find hovered window // Find hovered window
// (needs to be before UpdateMouseMovingWindow() so we fill g.HoveredWindowUnderMovingWindow on the mouse release frame) // (needs to be before UpdateMouseMovingWindowNewFrame so we fill g.HoveredWindowUnderMovingWindow on the mouse release frame)
UpdateHoveredWindowAndCaptureFlags(); UpdateHoveredWindowAndCaptureFlags();
// Handle user moving window with mouse (at the beginning of the frame to avoid input lag or sheering) // Handle user moving window with mouse (at the beginning of the frame to avoid input lag or sheering)
@ -4284,7 +4284,7 @@ static void FindHoveredWindow()
g.HoveredWindow = hovered_window; g.HoveredWindow = hovered_window;
g.HoveredRootWindow = g.HoveredWindow ? g.HoveredWindow->RootWindow : NULL; g.HoveredRootWindow = g.HoveredWindow ? g.HoveredWindow->RootWindow : NULL;
g.HoveredWindowUnderMovingWindow = hovered_window_ignoring_moving_window; g.HoveredWindowUnderMovingWindow = g.MovingWindow ? hovered_window_ignoring_moving_window : NULL;
if (g.MovingWindow) if (g.MovingWindow)
g.MovingWindow->Viewport = moving_window_viewport; g.MovingWindow->Viewport = moving_window_viewport;
@ -7434,7 +7434,7 @@ void ImGui::ClosePopupToLevel(int remaining, bool apply_focus_to_window_under)
// FIXME: This code is faulty and we may want to eventually to replace or remove the 'apply_focus_to_window_under=true' path completely. // FIXME: This code is faulty and we may want to eventually to replace or remove the 'apply_focus_to_window_under=true' path completely.
// Instead of using g.OpenPopupStack[remaining-1].Window etc. we should find the highest root window that is behind the popups we are closing. // Instead of using g.OpenPopupStack[remaining-1].Window etc. we should find the highest root window that is behind the popups we are closing.
// The current code will set focus to the parent of the popup window which is incorrect. // The current code will set focus to the parent of the popup window which is incorrect.
// It rarely manifested until now because UpdateMouseMovingWindow() would call FocusWindow() again on the clicked window, // It rarely manifested until now because UpdateMouseMovingWindowNewFrame() would call FocusWindow() again on the clicked window,
// leading to a chain of focusing A (clicked window) then B (parent window of the popup) then A again. // leading to a chain of focusing A (clicked window) then B (parent window of the popup) then A again.
// However if the clicked window has the _NoMove flag set we would be left with B focused. // However if the clicked window has the _NoMove flag set we would be left with B focused.
// For now, we have disabled this path when called from ClosePopupsOverWindow() because the users of ClosePopupsOverWindow() don't need to alter focus anyway, // For now, we have disabled this path when called from ClosePopupsOverWindow() because the users of ClosePopupsOverWindow() don't need to alter focus anyway,
@ -10304,7 +10304,7 @@ void ImGui::DockContextNewFrameUpdateUndocking(ImGuiContext* ctx)
dc->WantFullRebuild = false; dc->WantFullRebuild = false;
} }
// Process Undocking requests (we need to process them _before_ the UpdateMouseMovingWindow call in NewFrame) // Process Undocking requests (we need to process them _before_ the UpdateMouseMovingWindowNewFrame call in NewFrame)
for (int n = 0; n < dc->Requests.Size; n++) for (int n = 0; n < dc->Requests.Size; n++)
{ {
ImGuiDockRequest* req = &dc->Requests[n]; ImGuiDockRequest* req = &dc->Requests[n];

View File

@ -901,7 +901,7 @@ struct ImGuiContext
ImGuiWindow* CurrentWindow; // Being drawn into ImGuiWindow* CurrentWindow; // Being drawn into
ImGuiWindow* HoveredWindow; // Will catch mouse inputs ImGuiWindow* HoveredWindow; // Will catch mouse inputs
ImGuiWindow* HoveredRootWindow; // Will catch mouse inputs (for focus/move only) ImGuiWindow* HoveredRootWindow; // Will catch mouse inputs (for focus/move only)
ImGuiWindow* HoveredWindowUnderMovingWindow; ImGuiWindow* HoveredWindowUnderMovingWindow; // Hovered window ignoring MovingWindow. Only set if MovingWindow is set.
ImGuiID HoveredId; // Hovered widget ImGuiID HoveredId; // Hovered widget
bool HoveredIdAllowOverlap; bool HoveredIdAllowOverlap;
ImGuiID HoveredIdPreviousFrame; ImGuiID HoveredIdPreviousFrame;

View File

@ -6525,27 +6525,25 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
} }
// Extract a Dockable window out of it's tab bar // Extract a Dockable window out of it's tab bar
if (docked_window != NULL) if (docked_window != NULL && !(docked_window->Flags & ImGuiWindowFlags_NoMove))
{ {
// We use a variable threshold to distinguish dragging tabs within a tab bar and extracting them out of the tab bar // We use a variable threshold to distinguish dragging tabs within a tab bar and extracting them out of the tab bar
bool undocking_tab = (g.DragDropActive && g.DragDropPayload.SourceId == id); bool undocking_tab = (g.DragDropActive && g.DragDropPayload.SourceId == id);
if (!undocking_tab)
{
//if (!g.IO.ConfigDockingWithShift || g.IO.KeyShift)
{
float threshold_base = g.FontSize;
//float threshold_base = g.IO.ConfigDockingWithShift ? g.FontSize * 0.5f : g.FontSize;
float threshold_x = (threshold_base * 2.2f);
float threshold_y = (threshold_base * 1.5f) + ImClamp((ImFabs(g.IO.MouseDragMaxDistanceAbs[0].x) - threshold_base * 2.0f) * 0.20f, 0.0f, threshold_base * 4.0f);
//GetOverlayDrawList(window)->AddRect(ImVec2(bb.Min.x - threshold_x, bb.Min.y - threshold_y), ImVec2(bb.Max.x + threshold_x, bb.Max.y + threshold_y), IM_COL32_WHITE); // [DEBUG]
float distance_from_edge_y = ImMax(bb.Min.y - g.IO.MousePos.y, g.IO.MousePos.y - bb.Max.y); if (!undocking_tab) //&& (!g.IO.ConfigDockingWithShift || g.IO.KeyShift)
if (distance_from_edge_y >= threshold_y) {
float threshold_base = g.FontSize;
//float threshold_base = g.IO.ConfigDockingWithShift ? g.FontSize * 0.5f : g.FontSize;
float threshold_x = (threshold_base * 2.2f);
float threshold_y = (threshold_base * 1.5f) + ImClamp((ImFabs(g.IO.MouseDragMaxDistanceAbs[0].x) - threshold_base * 2.0f) * 0.20f, 0.0f, threshold_base * 4.0f);
//GetOverlayDrawList(window)->AddRect(ImVec2(bb.Min.x - threshold_x, bb.Min.y - threshold_y), ImVec2(bb.Max.x + threshold_x, bb.Max.y + threshold_y), IM_COL32_WHITE); // [DEBUG]
float distance_from_edge_y = ImMax(bb.Min.y - g.IO.MousePos.y, g.IO.MousePos.y - bb.Max.y);
if (distance_from_edge_y >= threshold_y)
undocking_tab = true;
else if (drag_distance_from_edge_x > threshold_x)
if ((tab_bar->ReorderRequestDir < 0 && tab_bar->GetTabOrder(tab) == 0) || (tab_bar->ReorderRequestDir > 0 && tab_bar->GetTabOrder(tab) == tab_bar->Tabs.Size - 1))
undocking_tab = true; undocking_tab = true;
else if (drag_distance_from_edge_x > threshold_x)
if ((tab_bar->ReorderRequestDir < 0 && tab_bar->GetTabOrder(tab) == 0) || (tab_bar->ReorderRequestDir > 0 && tab_bar->GetTabOrder(tab) == tab_bar->Tabs.Size - 1))
undocking_tab = true;
}
} }
if (undocking_tab) if (undocking_tab)