@@ -11373,7 +11373,7 @@ namespace ImGui
11373
11373
// ImGuiDockNode tree manipulations
11374
11374
static void DockNodeTreeSplit(ImGuiContext* ctx, ImGuiDockNode* parent_node, ImGuiAxis split_axis, int split_first_child, float split_ratio, ImGuiDockNode* new_node);
11375
11375
static void DockNodeTreeMerge(ImGuiContext* ctx, ImGuiDockNode* parent_node, ImGuiDockNode* merge_lead_child);
11376
- static void DockNodeTreeUpdatePosSize(ImGuiDockNode* node, ImVec2 pos, ImVec2 size);
11376
+ static void DockNodeTreeUpdatePosSize(ImGuiDockNode* node, ImVec2 pos, ImVec2 size, bool only_write_to_marked_nodes = false );
11377
11377
static void DockNodeTreeUpdateSplitter(ImGuiDockNode* node);
11378
11378
static ImGuiDockNode* DockNodeTreeFindNodeByPos(ImGuiDockNode* node, ImVec2 pos);
11379
11379
static ImGuiDockNode* DockNodeTreeFindFallbackLeafNode(ImGuiDockNode* node);
@@ -11953,6 +11953,7 @@ ImGuiDockNode::ImGuiDockNode(ImGuiID id)
11953
11953
IsVisible = true;
11954
11954
IsFocused = HasCloseButton = HasWindowMenuButton = EnableCloseButton = false;
11955
11955
WantCloseAll = WantLockSizeOnce = WantMouseMove = WantHiddenTabBarUpdate = WantHiddenTabBarToggle = false;
11956
+ MarkedForPosSizeWrite = false;
11956
11957
}
11957
11958
11958
11959
ImGuiDockNode::~ImGuiDockNode()
@@ -12286,6 +12287,7 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node)
12286
12287
ImGuiContext& g = *GImGui;
12287
12288
IM_ASSERT(node->LastFrameActive != g.FrameCount);
12288
12289
node->LastFrameAlive = g.FrameCount;
12290
+ node->MarkedForPosSizeWrite = false;
12289
12291
12290
12292
node->CentralNode = node->OnlyNodeWithWindows = NULL;
12291
12293
if (node->IsRootNode())
@@ -12533,6 +12535,7 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node)
12533
12535
node->LastFrameActive = g.FrameCount;
12534
12536
12535
12537
// Recurse into children
12538
+ // FIXME-DOCK FIXME-OPT: Should not need to recurse into children
12536
12539
if (host_window)
12537
12540
{
12538
12541
if (node->ChildNodes[0])
@@ -13265,10 +13268,17 @@ void ImGui::DockNodeTreeMerge(ImGuiContext* ctx, ImGuiDockNode* parent_node, ImG
13265
13268
}
13266
13269
13267
13270
// Update Pos/Size for a node hierarchy (don't affect child Windows yet)
13268
- void ImGui::DockNodeTreeUpdatePosSize(ImGuiDockNode* node, ImVec2 pos, ImVec2 size)
13271
+ void ImGui::DockNodeTreeUpdatePosSize(ImGuiDockNode* node, ImVec2 pos, ImVec2 size, bool only_write_to_marked_nodes )
13269
13272
{
13270
- node->Pos = pos;
13271
- node->Size = size;
13273
+ // During the regular dock node update we write to all nodes.
13274
+ // 'only_write_to_marked_nodes' is only set when turning a node visible mid-frame and we need its size right-away.
13275
+ const bool write_to_node = (only_write_to_marked_nodes == false) || (node->MarkedForPosSizeWrite);
13276
+ if (write_to_node)
13277
+ {
13278
+ node->Pos = pos;
13279
+ node->Size = size;
13280
+ }
13281
+
13272
13282
if (node->IsLeafNode())
13273
13283
return;
13274
13284
@@ -14082,6 +14092,25 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
14082
14092
node->LastFrameAlive = g.FrameCount;
14083
14093
}
14084
14094
14095
+ // If the node just turned visible, it doesn't have a Size assigned by DockNodeTreeUpdatePosSize() yet,
14096
+ // so we're forcing a Pos/Size update from the first ancestor that is already visible (often it will be the root node).
14097
+ // If we don't do this, the window will be assigned a zero-size on its first frame, which won't ideally warm up the layout.
14098
+ // This is a little wonky because we don't normally update the Pos/Size of visible node mid-frame.
14099
+ if (!node->IsVisible)
14100
+ {
14101
+ ImGuiDockNode* ancestor_node = node;
14102
+ while (!ancestor_node->IsVisible)
14103
+ {
14104
+ ancestor_node->IsVisible = true;
14105
+ ancestor_node->MarkedForPosSizeWrite = true;
14106
+ if (ancestor_node->ParentNode)
14107
+ ancestor_node = ancestor_node->ParentNode;
14108
+ }
14109
+ IM_ASSERT(ancestor_node->Size.x > 0.0f && ancestor_node->Size.y > 0.0f);
14110
+ DockNodeTreeUpdatePosSize(ancestor_node, ancestor_node->Pos, ancestor_node->Size, true);
14111
+ }
14112
+
14113
+ // Add window to node
14085
14114
DockNodeAddWindow(node, window, true);
14086
14115
IM_ASSERT(node == window->DockNode);
14087
14116
}
@@ -14128,6 +14157,7 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
14128
14157
}
14129
14158
IM_ASSERT(node->HostWindow);
14130
14159
IM_ASSERT(node->IsLeafNode());
14160
+ IM_ASSERT(node->Size.x > 0.0f && node->Size.y > 0.0f);
14131
14161
14132
14162
// Position window
14133
14163
SetNextWindowPos(node->Pos);
0 commit comments