# How to Enable Docking in Dear ImGui Applications: Complete Implementation Guide

> Enable docking in Dear ImGui applications with this complete implementation guide. Learn to set config flags and call DockSpace for an organized window layout.

- Repository: [omar/imgui](https://github.com/ocornut/imgui)
- Tags: how-to-guide
- Published: 2026-07-30

---

**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`](https://github.com/ocornut/imgui/blob/main/imgui.h) (around line 1279), the `ImGuiConfigFlags_DockingEnable` enum is defined as the primary switch for this feature.

```cpp
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`](https://github.com/ocornut/imgui/blob/main/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`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) (around line 16130), automatically creates a fullscreen dock space covering the entire main viewport.

```cpp
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.

```cpp
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:

```cpp
// 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.

```cpp
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`](https://github.com/ocornut/imgui/blob/main/imgui.h)**: Defines `ImGuiConfigFlags_DockingEnable`, `ImGuiDockNodeFlags`, and public API functions including `DockSpace()` and `DockSpaceOverViewport()`.

- **[`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp)**: Contains the core docking logic, including window-to-node attachment, tab bar rendering, and the `DockSpaceOverViewport()` implementation.

- **[`imgui_internal.h`](https://github.com/ocornut/imgui/blob/main/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`](https://github.com/ocornut/imgui/blob/main/imconfig.h)**: Provides compile-time switches; define `IMGUI_DISABLE_DOCKING` to remove docking code entirely for minimal binary sizes.

- **[`imgui_viewports.cpp`](https://github.com/ocornut/imgui/blob/main/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`](https://github.com/ocornut/imgui/blob/main/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`](https://github.com/ocornut/imgui/blob/main/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.