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 conflicts
  • DockBuilderSplitNode – Divides a node horizontally or vertically, returning the new child IDs
  • DockBuilderDockWindow – 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_DockingEnable in the ImGuiIO configuration flags immediately after context creation.
  • Create dockspaces using DockSpaceOverViewport for full-screen layouts or DockSpace with a unique ID for embedded panels.
  • Program layouts with the DockBuilder API (RemoveNode, SplitNode, DockWindow) to define default arrangements in imgui_internal.h.
  • Restrict docking per-window using ImGuiWindowFlags_NoDocking or per-node using ImGuiDockNodeFlags.
  • Reference implementations exist in imgui_demo.cpp under 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →