Docking: Fixed non-root dockspace not having their background rendered properly.

Fix f422e78. Fuller version of 08b3a1a pushed in master.
This commit is contained in:
ocornut 2023-08-30 15:26:46 +02:00
parent 762ec445e6
commit 7d6e83efca

View File

@ -5012,6 +5012,8 @@ static void AddWindowToDrawData(ImGuiWindow* window, int layer)
ImGuiViewportP* viewport = window->Viewport;
IM_ASSERT(viewport != NULL);
g.IO.MetricsRenderWindows++;
if (window->DrawList->_Splitter._Count > 1)
window->DrawList->ChannelsMerge(); // Merge if user forgot to merge back. Also required in Docking branch for ImGuiWindowFlags_DockNodeHost windows.
ImGui::AddDrawListToDrawDataEx(&viewport->DrawDataP, viewport->DrawDataBuilder.Layers[layer], window->DrawList);
for (int i = 0; i < window->DC.ChildWindows.Size; i++)
{
@ -5115,10 +5117,10 @@ static void ImGui::RenderDimmedBackgroundBehindWindow(ImGuiWindow* window, ImU32
// Draw behind window by moving the draw command at the FRONT of the draw list
{
// We've already called AddWindowToDrawData() which called DrawList->ChannelsMerge() on DockNodeHost windows,
// and draw list have been trimmed already, hence the explicit recreation of a draw command if missing.
// Draw list have been trimmed already, hence the explicit recreation of a draw command if missing.
// FIXME: This is creating complication, might be simpler if we could inject a drawlist in drawdata at a given position and not attempt to manipulate ImDrawCmd order.
ImDrawList* draw_list = window->RootWindowDockTree->DrawList;
draw_list->ChannelsMerge();
if (draw_list->CmdBuffer.Size == 0)
draw_list->AddDrawCmd();
draw_list->PushClipRect(viewport_rect.Min - ImVec2(1, 1), viewport_rect.Max + ImVec2(1, 1), false); // FIXME: Need to stricty ensure ImDrawCmd are not merged (ElemCount==6 checks below will verify that)
@ -5135,6 +5137,7 @@ static void ImGui::RenderDimmedBackgroundBehindWindow(ImGuiWindow* window, ImU32
if (window->RootWindow->DockIsActive)
{
ImDrawList* draw_list = FindFrontMostVisibleChildWindow(window->RootWindowDockTree)->DrawList;
draw_list->ChannelsMerge();
if (draw_list->CmdBuffer.Size == 0)
draw_list->AddDrawCmd();
draw_list->PushClipRect(viewport_rect.Min, viewport_rect.Max, false);
@ -5160,6 +5163,8 @@ ImGuiWindow* ImGui::FindBottomMostVisibleWindowWithinBeginStack(ImGuiWindow* par
return bottom_most_visible_window;
}
// Important: AddWindowToDrawData() has not been called yet, meaning DockNodeHost windows needs a DrawList->ChannelsMerge() before usage.
// We call ChannelsMerge() lazily here at it is faster that doing a full iteration of g.Windows[] prior to calling RenderDimmedBackgrounds().
static void ImGui::RenderDimmedBackgrounds()
{
ImGuiContext& g = *GImGui;
@ -5196,6 +5201,7 @@ static void ImGui::RenderDimmedBackgrounds()
bb.Expand(distance);
if (bb.GetWidth() >= viewport->Size.x && bb.GetHeight() >= viewport->Size.y)
bb.Expand(-distance - 1.0f); // If a window fits the entire viewport, adjust its highlight inward
window->DrawList->ChannelsMerge();
if (window->DrawList->CmdBuffer.Size == 0)
window->DrawList->AddDrawCmd();
window->DrawList->PushClipRect(viewport->Pos, viewport->Pos + viewport->Size);
@ -5348,10 +5354,6 @@ void ImGui::Render()
AddDrawListToDrawDataEx(&viewport->DrawDataP, viewport->DrawDataBuilder.Layers[0], GetBackgroundDrawList(viewport));
}
for (ImGuiWindow* window : g.WindowsFocusOrder)
if (window->Flags & ImGuiWindowFlags_DockNodeHost)
window->DrawList->ChannelsMerge();
// Draw modal/window whitening backgrounds
RenderDimmedBackgrounds();