How to Enable Docking in Dear ImGui Applications: Complete Implementation Guide
Enable docking in Dear ImGui by setting io.ConfigFlags |= ImGuiConfigFlags_DockingEnable before your main loop, then call ImGui::DockSpace() or ImGui::DockSpaceOverViewport() each frame to create an anchor region where windows can be dragged, tabbed, and organized.
Dear ImGui (ocornut/imgui) provides a powerful docking system built directly into the core library that transforms floating windows into a professional, dockable interface. To enable docking in Dear ImGui applications, you must configure the ImGuiIO structure with the appropriate configuration flags and establish a dock space host within your frame rendering logic. This implementation activates hidden dock nodes that manage window hierarchies, split layouts, and tabbed containers.
Step 1: Configure the Docking Flag
Before creating your ImGui context or entering the main loop, enable docking by modifying the ConfigFlags field of the ImGuiIO structure. In imgui.h (around line 1279), the ImGuiConfigFlags_DockingEnable enum is defined as the primary switch for this feature.
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
Optionally, combine this with ImGuiConfigFlags_ViewportsEnable to allow docked windows to be moved outside the main application window as independent OS-level viewports. This extended functionality is implemented in imgui_viewports.cpp.
Step 2: Create a Dock Space Host
Docking requires a persistent host window that serves as the root container. You have two primary approaches:
DockSpaceOverViewport (Recommended): The simplest method, implemented in imgui.cpp (around line 16130), automatically creates a fullscreen dock space covering the entire main viewport.
ImGui::NewFrame();
ImGui::DockSpaceOverViewport(ImGui::GetMainViewport());
Manual DockSpace: For custom layouts, create a dedicated window and explicitly call ImGui::DockSpace() with a unique identifier. This approach requires setting window flags to remove decorations and fill the available area.
ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
if (opt_fullscreen)
{
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), ImGuiDockNodeFlags_None);
ImGui::End();
Complete Implementation Example
The following example demonstrates a minimal SDL + OpenGL setup with docking enabled:
// Configuration (do this once before the main loop)
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Optional: multi-viewport
// Main loop
while (running)
{
// Platform backend new frame calls...
ImGui::NewFrame();
// Create fullscreen dock space
static bool opt_fullscreen = true;
static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_None;
ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
if (opt_fullscreen)
{
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();
// Your dockable windows
ImGui::Begin("Example Window");
ImGui::Text("Drag me by the title bar to dock!");
ImGui::End();
// Rendering
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
// Update multi-viewports if enabled
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
ImGui::UpdatePlatformWindows();
ImGui::RenderPlatformWindowsDefault();
}
}
Programmatic Layout Control with the Dock Builder API
For applications requiring specific default layouts (e.g., a sidebar on the left and main content on the right), use the Dock Builder API. These functions allow you to split nodes and dock windows programmatically before the user interacts with them.
if (ImGui::DockBuilderGetNode(dockspace_id) == nullptr)
{
// Clear existing layout and add root node
ImGui::DockBuilderRemoveNode(dockspace_id);
ImGui::DockBuilderAddNode(dockspace_id, ImGuiDockNodeFlags_None);
// Split the dock space
ImGuiID dock_main_id = dockspace_id;
ImGuiID dock_left_id = ImGui::DockBuilderSplitNode(
dock_main_id, ImGuiDir_Left, 0.25f, nullptr, &dock_main_id);
// Dock specific windows to nodes
ImGui::DockBuilderDockWindow("Properties", dock_left_id);
ImGui::DockBuilderDockWindow("Viewport", dock_main_id);
ImGui::DockBuilderFinish(dockspace_id);
}
Internal Architecture and Key Source Files
Understanding the underlying implementation helps debug docking behavior:
-
imgui.h: DefinesImGuiConfigFlags_DockingEnable,ImGuiDockNodeFlags, and public API functions includingDockSpace()andDockSpaceOverViewport(). -
imgui.cpp: Contains the core docking logic, including window-to-node attachment, tab bar rendering, and theDockSpaceOverViewport()implementation. -
imgui_internal.h: Houses internal structures such as ImGuiDockNode and ImGuiDockContext (around line 2150), which track the hierarchy of split nodes and window relationships viaImGuiWindow::DockId. -
imconfig.h: Provides compile-time switches; defineIMGUI_DISABLE_DOCKINGto remove docking code entirely for minimal binary sizes. -
imgui_viewports.cpp: Handles the multi-viewport extension, allowing individual dock nodes to exist as separate OS windows.
To require the Shift key for docking operations (preventing accidental docks), set io.ConfigDockingWithShift = true before calling NewFrame().
Summary
- Set
io.ConfigFlags |= ImGuiConfigFlags_DockingEnablein your initialization code to activate the docking system. - Call
ImGui::DockSpaceOverViewport()for automatic fullscreen docking, or manually create a host window withImGui::DockSpace()for custom layouts. - Any window created with
ImGui::Begin()can be dragged by its title bar and docked into the active dock space. - Use the Dock Builder API (
DockBuilderSplitNode,DockBuilderDockWindow) to programmatically define default layouts. - Enable
ImGuiConfigFlags_ViewportsEnablefor multi-viewport support, allowing docked panels to become floating OS windows.
Frequently Asked Questions
Where is the docking configuration flag defined according to the Dear ImGui source code?
The ImGuiConfigFlags_DockingEnable flag is defined in imgui.h (around line 1279) as part of the ImGuiConfigFlags_ enumeration. This flag instructs ImGui::CreateContext() to allocate an ImGuiDockContext structure, documented in imgui_internal.h, which manages the entire docking node hierarchy.
Why don't my windows dock after enabling the configuration flag?
Dear ImGui requires a dock space host to receive docked windows. Simply enabling the flag allows windows to attempt docking, but you must also create a dock space using ImGui::DockSpace() or ImGui::DockSpaceOverViewport() within a persistent host window each frame. Without this anchor, windows remain floating despite the flag being enabled.
How can I customize the docking behavior to require a modifier key?
Set io.ConfigDockingWithShift = true in your initialization or runtime configuration. When this boolean is enabled, users must hold the Shift key while dragging a window to initiate docking, preventing accidental window attachment during normal UI interaction. Additional customization is available through ImGuiDockNodeFlags passed to DockSpace().
What is the difference between DockSpace and DockSpaceOverViewport?
DockSpaceOverViewport is a convenience wrapper that automatically handles window positioning, sizing, and viewport management to create a fullscreen docking area. DockSpace requires manual setup of a host window (including flags like ImGuiWindowFlags_NoDocking on the host and explicit position/size calls) but offers greater control over placement and sizing. Both functions return an ImGuiID representing the root dock node.
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 →