How to Manage ImGui Docking and Tab Windows: A Complete Guide to the Built-In Docking System
Enable ImGuiConfigFlags_DockingEnable in the ImGuiIO configuration, create a host dock space with ImGui::DockSpace(), and use ImGuiTabBarFlags_DockingEnable when building tab bars so that windows and tabs can be dragged, split, and persisted between sessions.
Dear ImGui (ocornut/imgui) ships with a built-in docking system that lets you create IDE-style layouts without external dependencies. Learning how to manage ImGui docking and tab windows starts with three configuration and API calls that activate dock nodes, host spaces, and tab grouping. The entire implementation is compiled from the master branch and exposed through headers and functions found in imgui.h and imgui.cpp.
Enable Docking with ImGuiConfigFlags_DockingEnable
Set the flag on the IO object during setup. This flag is declared in imgui.h and activates the docking code path compiled under the IMGUI_HAS_DOCK preprocessor guard.
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
Create a Dock Space Host Window
Call ImGui::DockSpace() inside a host window to allocate a region that receives dockable windows. The convenience wrapper ImGui::DockSpaceOverViewport() is also available. In imgui.cpp, the DockSpace() implementation handles node allocation and layout resolution.
ImGui::Begin("MainDockSpace", nullptr,
ImGuiWindowFlags_NoTitleBar |
ImGuiWindowFlags_NoCollapse |
ImGuiWindowFlags_NoResize |
ImGuiWindowFlags_NoMove |
ImGuiWindowFlags_NoBringToFrontOnFocus |
ImGuiWindowFlags_NoNavFocus);
ImGuiID dockspace_id = ImGui::DockSpace(ImGui::GetID("MyDockSpace"));
ImGui::End();
Assign Windows to Specific Dock Nodes
After you have a dock node ID, use ImGui::SetNextWindowDockID() to force a window to open inside that node.
ImGui::SetNextWindowDockID(my_dock_id, ImGuiCond_Once);
ImGui::Begin("MyFixedPanel");
ImGui::Text("This window always starts docked in the same node.");
ImGui::End();
Program Default Layouts with the Dock Builder API
For tool-style applications, use the ImGui::DockBuilder* family declared in imgui.h and defined in imgui.cpp to split nodes and assign windows before the first frame.
ImGuiID dock_main = ImGui::GetID("MainDockSpace");
ImGui::DockBuilderRemoveNode(dock_main);
ImGui::DockBuilderAddNode(dock_main, ImGuiDockNodeFlags_None);
ImGui::DockBuilderSetNodeSize(dock_main, ImGui::GetMainViewport()->Size);
ImGuiID dock_left, dock_right;
dock_left = ImGui::DockBuilderSplitNode(dock_main, ImGuiDir_Left, 0.25f, nullptr, &dock_main);
dock_right = dock_main;
ImGui::DockBuilderDockWindow("LeftPanel", dock_left);
ImGui::DockBuilderDockWindow("RightPanel", dock_right);
ImGui::DockBuilderFinish(dock_main);
Build Tab Windows That Integrate with Docking
Tab bars participate in the docking system when you pass ImGuiTabBarFlags_DockingEnable. This lets users drag an entire tab group between dock slots.
ImGui::Begin("TabHost");
if (ImGui::BeginTabBar("MyTabBar", ImGuiTabBarFlags_DockingEnable)) {
if (ImGui::BeginTabItem("Tab A")) {
ImGui::Text("Content of Tab A");
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Tab B")) {
ImGui::Text("Content of Tab B");
ImGui::EndTabItem();
}
ImGui::EndTabBar();
}
ImGui::End();
Persist and Restore Docking Layouts
Docking hierarchies are written to the .ini file as [Dock][...] entries. Call ImGui::SaveIniSettingsToDisk() before shutdown and ImGui::LoadIniSettingsFromDisk() at startup.
ImGui::SaveIniSettingsToDisk("my_imgui_layout.ini");
// ...
ImGui::LoadIniSettingsFromDisk("my_imgui_layout.ini");
Key Source Files and Internal Architecture
The docking system relies on a few critical files in the ocornut/imgui repository. imgui.h contains the public flags and DockSpace() prototype, while imgui.cpp implements the core docking logic, layout persistence, and the DockBuilder* family. Internal structures such as ImGuiDockNode and ImGuiDockContext are defined in imgui_internal.h. You can find usage examples in examples/example_sdl2_opengl3/main.cpp and the interactive docking demo inside imgui_demo.cpp.
Summary
- Enable docking globally by setting
ImGuiConfigFlags_DockingEnableinImGuiIO. - Host dockable panels inside a region created with
ImGui::DockSpace()orImGui::DockSpaceOverViewport(). - Pin windows to nodes with
ImGui::SetNextWindowDockID()or build default trees with theImGui::DockBuilder*API. - Combine tabs into draggable groups by passing
ImGuiTabBarFlags_DockingEnabletoImGui::BeginTabBar(). - Persist layouts between sessions using
ImGui::SaveIniSettingsToDisk()andImGui::LoadIniSettingsFromDisk().
Frequently Asked Questions
Why is my dock space not interacting with windows?
Docking only activates if ImGuiConfigFlags_DockingEnable is set in the ImGuiIO object before the first frame, and if the host window containing ImGui::DockSpace() is submitted before the child windows. Verify that the dock space ID is consistent and that the host window uses correct flags such as ImGuiWindowFlags_NoNavFocus.
Can I dock windows without a user dragging them?
Yes. Use ImGui::SetNextWindowDockID() to place a single window, or use the ImGui::DockBuilder* API to split nodes and assign multiple windows to a default tree programmatically as implemented in imgui.cpp.
Do tab bars require a separate dock space to work?
No. Tab bars that use ImGuiTabBarFlags_DockingEnable live inside normal windows and participate in the same docking system. You can drag the entire tab group into any existing dock node because the tab bar integrates with the ImGuiDockContext structures defined in imgui_internal.h.
How do I reset the docking layout to the original default?
Call ImGui::DockBuilderRemoveNode() on your dock space ID before rebuilding the tree with ImGui::DockBuilderAddNode() and ImGui::DockBuilderDockWindow(). Alternatively, delete the saved .ini file and restart so that ImGui::LoadIniSettingsFromDisk() finds no prior state.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →