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: Defines ImGuiConfigFlags_DockingEnable, ImGuiDockNodeFlags, and public API functions including DockSpace() and DockSpaceOverViewport().

  • imgui.cpp: Contains the core docking logic, including window-to-node attachment, tab bar rendering, and the DockSpaceOverViewport() 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 via ImGuiWindow::DockId.

  • imconfig.h: Provides compile-time switches; define IMGUI_DISABLE_DOCKING to 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_DockingEnable in your initialization code to activate the docking system.
  • Call ImGui::DockSpaceOverViewport() for automatic fullscreen docking, or manually create a host window with ImGui::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_ViewportsEnable for 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:

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 →