How to Enable the Dear ImGui Docking System in Your Application
To enable Dear ImGui docking, set io.ConfigFlags |= ImGuiConfigFlags_DockingEnable before creating your context, then create a dock space using ImGui::DockSpace() or ImGui::DockSpaceOverViewport() each frame.
Dear ImGui (ocornut/imgui) includes an advanced docking system that allows users to drag, dock, and tab windows within a host space. This feature transforms floating tool windows into a professional, integrated layout similar to modern game engines and IDEs.
Prerequisites and Configuration
Enabling the Docking Flag
You must enable docking at initialization time by modifying the ImGuiIO configuration flags. According to the source code in imgui.h (around line 1279), you set the ImGuiConfigFlags_DockingEnable bit before calling NewFrame():
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
This flag triggers the allocation of an ImGuiDockContext structure (defined in imgui_internal.h near line 2150) that tracks all dock nodes and their hierarchy. Without this flag, the docking API functions exist but will not create or manage dock nodes.
Optional Multi-Viewport Support
For docking across multiple OS-level windows, combine the docking flag with ImGuiConfigFlags_ViewportsEnable:
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable | ImGuiConfigFlags_ViewportsEnable;
This integration, implemented in imgui_viewports.cpp, allows docked panels to be dragged outside the main window to form independent viewports.
Creating the Dock Space
Using DockSpaceOverViewport (Simpler)
The DockSpaceOverViewport function provides the quickest setup. As implemented in imgui.cpp (around line 16130), this creates a dock space that fills the specified viewport:
ImGui::NewFrame();
ImGui::DockSpaceOverViewport(ImGui::GetMainViewport());
// Your windows here...
ImGui::Render();
This handles the background window creation automatically, making it ideal for full-screen docking layouts.
Manual DockSpace Setup (More Control)
For custom layouts, explicitly create a host window and call ImGui::DockSpace():
static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_None;
ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
const ImGuiViewport* viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(viewport->Pos);
ImGui::SetNextWindowSize(viewport->Size);
ImGui::SetNextWindowViewport(viewport->ID);
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse |
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
ImGui::Begin("##DockSpace", nullptr, window_flags);
ImGuiID dockspace_id = ImGui::GetID("MyDockSpace");
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
ImGui::End();
The dockspace_id returned from GetID() serves as the anchor where windows can attach. Each ImGuiWindow stores its target dock node in the DockId field (part of the ImGuiWindow structure in imgui_internal.h).
Customizing Docking Behavior
Input Modifiers
Control how docking interactions behave using the IO configuration:
io.ConfigDockingWithShift = true; // Require Shift key for docking
io.ConfigDockingTransparentPayload = true; // Show window contents while dragging
Dock Node Flags
When calling DockSpace, pass flags to restrict behavior:
ImGuiDockNodeFlags_NoResize: Prevent manual resizing of splitsImGuiDockNodeFlags_AutoHideTabBar: Hide tabs when only one window is dockedImGuiDockNodeFlags_PassthruCentralNode: Central node is transparent (useful for full-screen game views)
Programmatic Layout Control
To define specific layouts programmatically rather than relying on user interaction, use the Dock Builder API. This code checks if a layout exists and constructs a split hierarchy:
if (ImGui::DockBuilderGetNode(dockspace_id) == nullptr)
{
ImGui::DockBuilderRemoveNode(dockspace_id); // Clear existing layout
ImGui::DockBuilderAddNode(dockspace_id, ImGuiDockNodeFlags_None);
ImGuiID dock_main_id = dockspace_id;
ImGuiID dock_left_id = ImGui::DockBuilderSplitNode(
dock_main_id, ImGuiDir_Left, 0.25f, nullptr, &dock_main_id);
ImGui::DockBuilderDockWindow("##MyLeftPanel", dock_left_id);
ImGui::DockBuilderDockWindow("##MyMainPanel", dock_main_id);
ImGui::DockBuilderFinish(dockspace_id);
}
DockBuilderSplitNode divides a node horizontally or vertically, returning the new child ID through the out parameter. DockBuilderDockWindow assigns specific windows to nodes by name.
How Docking Works Under the Hood
Behind the scenes, the docking system manages several key data structures:
-
ImGuiDockContext: A per-context structure allocated when
ImGuiConfigFlags_DockingEnableis set. It maintains a hash map ofImGuiDockNodeinstances indexed by ID. -
Dock Nodes: Each
ImGuiDockNode(defined inimgui_internal.h) represents a split container or tab bar. Nodes track their parent/child relationships, split ratios, and hosted windows. -
Window Attachment: When
Begin()is called on a window with a non-zeroDockId, the system looks up the corresponding node in the dock context. If the window is being dragged, the system evaluates mouse position against node split boundaries to determine docking targets. -
Serialization: Node layouts persist across frames through the
.inifile system, storing the hierarchy and window assignments (unlessImGuiDockNodeFlags_NoSavedSettingsis set).
Summary
- Enable docking by setting
ImGuiConfigFlags_DockingEnableinio.ConfigFlagsbefore the first frame - Call
ImGui::DockSpaceOverViewport()for automatic full-screen docking, orImGui::DockSpace()for manual host windows - Store the returned
ImGuiIDto reference specific dock nodes for programmatic layout - Use the Dock Builder API (
DockBuilderSplitNode,DockBuilderDockWindow) to create predefined layouts - Reference
imgui.hfor public flags,imgui_internal.hfor node structures, andimgui.cppfor the core implementation - Disable docking entirely at compile time via
IMGUI_DISABLE_DOCKINGinimconfig.h
Frequently Asked Questions
What is the difference between DockSpace and DockSpaceOverViewport?
DockSpaceOverViewport is a convenience wrapper that creates a full-screen background window and calls DockSpace internally, while DockSpace requires you to create and manage the host window manually. Use DockSpaceOverViewport for simple full-screen docking; use DockSpace when you need the dock area to occupy only a portion of your UI or require specific window flags.
Why are my windows not docking after enabling the flag?
Ensure you are creating a dock space every frame. Docking only works when a visible dock node exists to receive the window. If you enabled ImGuiConfigFlags_DockingEnable but forgot to call DockSpace() or DockSpaceOverViewport(), windows will remain floating. Also verify you are not passing ImGuiWindowFlags_NoDocking to your windows.
How do I save and restore docking layouts?
Dear ImGui automatically serializes docking layouts to the ini file. The dock node hierarchy and window assignments persist between sessions by default. To manually save/restore specific layouts, use the Dock Builder API to capture node IDs and reconstruct the splits, or use DockBuilderCopyWindowSettings to clone layouts between dock spaces.
Can I disable docking at compile time?
Yes, via imconfig.h. Define IMGUI_DISABLE_DOCKING before including imgui headers to remove all docking-related code and data structures. This reduces binary size for applications that do not need the feature, eliminating the ImGuiDockContext allocation and associated processing overhead.
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 →