How to Implement Docking and Advanced Layout Customization in Dear ImGui
Dear ImGui provides a built-in docking system that allows users to rearrange, split, and tab-merge windows at runtime by setting a configuration flag and creating dock nodes.
The ocornut/imgui repository includes a complete window docking and layout system in its master branch. By enabling ImGuiConfigFlags_DockingEnable and utilizing the DockBuilder API, you can create complex, persistent layouts that users can customize through drag-and-drop or that you can define programmatically at startup.
Enabling the Docking System
Before you can dock windows, you must activate the docking subsystem in the ImGuiIO structure. This should be done once after creating the ImGui context but before your main loop begins.
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Activate docking system
The ImGuiConfigFlags_DockingEnable flag is defined in imgui.h and instructs Dear ImGui to initialize the docking infrastructure. Without this flag, all docking-related functions will behave as no-ops.
Creating a Full-Screen Dockspace
The most common pattern for docking-based applications is to create a full-screen dockspace that fills the entire main viewport. This provides a root node into which all other windows can be docked.
void MyMainUI()
{
// Create a dockspace covering the main viewport
ImGui::DockSpaceOverViewport(ImGui::GetMainViewport());
// Your application windows
ImGui::Begin("Viewport");
ImGui::Text("Rendering output goes here");
ImGui::End();
ImGui::Begin("Log");
ImGui::TextWrapped("Application logs...");
ImGui::End();
}
The DockSpaceOverViewport function, implemented in imgui.cpp, automatically handles size updates when the window resizes and respects the multi-viewport system when ImGuiConfigFlags_ViewportsEnable is active.
Embedding Dockspaces Inside Windows
For more complex interfaces, you can create dockspaces within specific windows rather than covering the entire screen. This requires generating a unique ImGuiID and calling DockSpace directly.
void MyEditorPanel()
{
ImGui::Begin("Editor");
static ImGuiID dock_id = ImGui::GetID("EditorDockSpace");
ImGui::DockSpace(dock_id, ImVec2(0.0f, 0.0f), ImGuiDockNodeFlags_None);
ImGui::End();
}
The DockSpace function is declared in imgui.h and creates a hosting area for dock nodes within the current window. The second parameter specifies the desired size, where ImVec2(0.0f, 0.0f) tells the dockspace to fill all available space.
Programmatic Layout Design with DockBuilder
To define default layouts or restore specific arrangements at startup, use the DockBuilder API exposed in imgui_internal.h. This internal API allows you to split nodes, set sizes, and dock windows programmatically.
void SetupDefaultLayout()
{
ImGuiID dock_main = ImGui::GetID("MyDockSpace");
// Clear previous layout and create root node
ImGui::DockBuilderRemoveNode(dock_main);
ImGui::DockBuilderAddNode(dock_main, ImGuiDockNodeFlags_None);
ImGui::DockBuilderSetNodeSize(dock_main, ImGui::GetMainViewport()->Size);
// Split the dockspace: 30% left, 70% right
ImGuiID dock_left, dock_right;
ImGui::DockBuilderSplitNode(dock_main, ImGuiDir_Left, 0.30f, &dock_left, &dock_right);
// Assign windows to specific nodes
ImGui::DockBuilderDockWindow("Inspector", dock_left);
ImGui::DockBuilderDockWindow("Scene", dock_right);
}
Key DockBuilder functions include:
DockBuilderRemoveNode– Clears existing node data to prevent conflictsDockBuilderSplitNode– Divides a node horizontally or vertically, returning the new child IDsDockBuilderDockWindow– Assigns a window to a specific node by ID
Run this setup code once during application initialization, guarded by a "first frame" check or configuration load flag.
Controlling Docking Behavior
You can fine-tune docking behavior using node flags and window flags.
To prevent a specific window from docking, use ImGuiWindowFlags_NoDocking:
ImGui::Begin("Settings", nullptr, ImGuiWindowFlags_NoDocking);
ImGui::Text("This window cannot be docked.");
ImGui::End();
For node-level control, pass flags like ImGuiDockNodeFlags_NoResize or ImGuiDockNodeFlags_NoSplit to DockSpace to disable user resizing or splitting of that specific dockspace. These flags are defined in imgui_internal.h alongside the DockBuilder API.
Summary
- Enable docking by setting
ImGuiConfigFlags_DockingEnablein theImGuiIOconfiguration flags immediately after context creation. - Create dockspaces using
DockSpaceOverViewportfor full-screen layouts orDockSpacewith a unique ID for embedded panels. - Program layouts with the DockBuilder API (
RemoveNode,SplitNode,DockWindow) to define default arrangements inimgui_internal.h. - Restrict docking per-window using
ImGuiWindowFlags_NoDockingor per-node usingImGuiDockNodeFlags. - Reference implementations exist in
imgui_demo.cppunder the "Docking" demonstration section.
Frequently Asked Questions
How do I enable docking in Dear ImGui?
Set the ImGuiConfigFlags_DockingEnable flag in your ImGuiIO structure after creating the context but before the main loop: ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_DockingEnable;. This flag is defined in imgui.h and activates the entire docking subsystem.
What is the difference between DockSpace and DockSpaceOverViewport?
DockSpaceOverViewport is a convenience wrapper that creates a full-screen dockspace covering a specific viewport (usually the main one) and handles sizing automatically, while DockSpace requires you to provide a unique ImGuiID and size parameters, allowing you to embed dockable areas inside specific windows or regions.
How do I create a default layout programmatically?
Use the DockBuilder API from imgui_internal.h: first call DockBuilderRemoveNode to clear existing data, then DockBuilderAddNode to create a root node, DockBuilderSplitNode to divide it, and DockBuilderDockWindow to assign windows to the resulting nodes. Execute this setup once at application startup.
Can I prevent specific windows from docking?
Yes. Pass ImGuiWindowFlags_NoDocking to the ImGui::Begin() call for that window. To prevent docking at the node level, use ImGuiDockNodeFlags_NoDockingOver or ImGuiDockNodeFlags_NoDockingSplit when creating the dockspace.
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 →