Skip to content

Commit 718e15c

Browse files
committed
Docking: Fix so that an appearing window making a dock node reappear won't have a zero-size on its first frame (because dock node ->Size was 0.0 unlike ->SizeRef) (#2109)
Docking: Added ImGuiDockNode to .natvis file.
1 parent 8bc6d97 commit 718e15c

File tree

3 files changed

+39
-4
lines changed

3 files changed

+39
-4
lines changed

imgui.cpp

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11373,7 +11373,7 @@ namespace ImGui
1137311373
// ImGuiDockNode tree manipulations
1137411374
static void DockNodeTreeSplit(ImGuiContext* ctx, ImGuiDockNode* parent_node, ImGuiAxis split_axis, int split_first_child, float split_ratio, ImGuiDockNode* new_node);
1137511375
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);
1137711377
static void DockNodeTreeUpdateSplitter(ImGuiDockNode* node);
1137811378
static ImGuiDockNode* DockNodeTreeFindNodeByPos(ImGuiDockNode* node, ImVec2 pos);
1137911379
static ImGuiDockNode* DockNodeTreeFindFallbackLeafNode(ImGuiDockNode* node);
@@ -11953,6 +11953,7 @@ ImGuiDockNode::ImGuiDockNode(ImGuiID id)
1195311953
IsVisible = true;
1195411954
IsFocused = HasCloseButton = HasWindowMenuButton = EnableCloseButton = false;
1195511955
WantCloseAll = WantLockSizeOnce = WantMouseMove = WantHiddenTabBarUpdate = WantHiddenTabBarToggle = false;
11956+
MarkedForPosSizeWrite = false;
1195611957
}
1195711958

1195811959
ImGuiDockNode::~ImGuiDockNode()
@@ -12286,6 +12287,7 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node)
1228612287
ImGuiContext& g = *GImGui;
1228712288
IM_ASSERT(node->LastFrameActive != g.FrameCount);
1228812289
node->LastFrameAlive = g.FrameCount;
12290+
node->MarkedForPosSizeWrite = false;
1228912291

1229012292
node->CentralNode = node->OnlyNodeWithWindows = NULL;
1229112293
if (node->IsRootNode())
@@ -12533,6 +12535,7 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node)
1253312535
node->LastFrameActive = g.FrameCount;
1253412536

1253512537
// Recurse into children
12538+
// FIXME-DOCK FIXME-OPT: Should not need to recurse into children
1253612539
if (host_window)
1253712540
{
1253812541
if (node->ChildNodes[0])
@@ -13265,10 +13268,17 @@ void ImGui::DockNodeTreeMerge(ImGuiContext* ctx, ImGuiDockNode* parent_node, ImG
1326513268
}
1326613269

1326713270
// 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)
1326913272
{
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+
1327213282
if (node->IsLeafNode())
1327313283
return;
1327413284

@@ -14082,6 +14092,25 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
1408214092
node->LastFrameAlive = g.FrameCount;
1408314093
}
1408414094

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
1408514114
DockNodeAddWindow(node, window, true);
1408614115
IM_ASSERT(node == window->DockNode);
1408714116
}
@@ -14128,6 +14157,7 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
1412814157
}
1412914158
IM_ASSERT(node->HostWindow);
1413014159
IM_ASSERT(node->IsLeafNode());
14160+
IM_ASSERT(node->Size.x > 0.0f && node->Size.y > 0.0f);
1413114161

1413214162
// Position window
1413314163
SetNextWindowPos(node->Pos);

imgui_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -956,6 +956,7 @@ struct ImGuiDockNode
956956
bool WantMouseMove :1; // After a node extraction we need to transition toward moving the newly created host window
957957
bool WantHiddenTabBarUpdate :1;
958958
bool WantHiddenTabBarToggle :1;
959+
bool MarkedForPosSizeWrite :1; // Update by DockNodeTreeUpdatePosSize() write-filtering
959960

960961
ImGuiDockNode(ImGuiID id);
961962
~ImGuiDockNode();

misc/natvis/imgui.natvis

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,9 @@
3535
<Type Name="ImGuiWindow">
3636
<DisplayString>{{Name {Name,s} Active {(Active||WasActive)?1:0,d} Child {(Flags &amp; 0x01000000)?1:0,d} Popup {(Flags &amp; 0x04000000)?1:0,d} Hidden {(Hidden)?1:0,d}}</DisplayString>
3737
</Type>
38+
39+
<Type Name="ImGuiDockNode">
40+
<DisplayString>{{ID {ID,x} Pos=({Pos.x,g} {Pos.y,g}) Size=({Size.x,g} {Size.y,g}) Parent {(ParentNode==0)?0:ParentNode->ID,x} Childs {(ChildNodes[0] != 0)+(ChildNodes[1] != 0)} Windows {Windows.Size} }</DisplayString>
41+
</Type>
3842

3943
</AutoVisualizer>

0 commit comments

Comments
 (0)