# How to Implement Multi-Viewport Support in Dear ImGui

> Learn to implement multi-viewport support in Dear ImGui by enabling the ViewportsEnable flag and configuring your platform backend for native OS windows.

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

---

**Enable the `ImGuiConfigFlags_ViewportsEnable` flag in your ImGuiIO configuration and ensure your platform backend implements viewport creation callbacks to render ImGui windows as separate native OS windows.**

Dear ImGui's multi-viewport system allows UI windows to break free from the main application frame and exist as independent platform windows. When you implement multi-viewport support in Dear ImGui, the library automatically manages native window creation, destruction, and rendering across multiple viewports. This feature requires the docking branch of the repository and specific backend integration to handle platform-specific window lifecycle events.

## Enable the Viewport Configuration Flag

Multi-viewport functionality activates through a specific configuration bit defined in the `ImGuiConfigFlags_` enum. In [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h) (lines 1710-1724), the library defines `ImGuiConfigFlags_ViewportsEnable`, which triggers the viewport management system when set.

After creating your ImGui context, enable the feature through the IO structure:

```cpp
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;   // Enables multi-viewport support

```

Setting this flag instructs Dear ImGui to initialize the viewport array and prepare for platform window creation when ImGui windows move outside the main client area.

## Understanding Viewport Architecture

Internally, Dear ImGui represents each window container as an `ImGuiViewport` object. The global context maintains an array of active viewports in `g.Viewports`, defined in [`imgui_internal.h`](https://github.com/ocornut/imgui/blob/main/imgui_internal.h), with the primary viewport accessible through public API functions.

### Primary Viewport Initialization

During the first frame, Dear ImGui automatically allocates the primary viewport. In [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) (line 4483), the system calls `IM_NEW` to create an `ImGuiViewportP` instance (the internal implementation of `ImGuiViewport`), storing it in the viewports array. You can retrieve this primary viewport via `GetMainViewport()` (line 16052):

```cpp
ImGuiViewport* main_viewport = ImGui::GetMainViewport();  // Returns the primary viewport

```

### Automatic Secondary Viewport Creation

When users drag an ImGui window outside the main viewport bounds, the system automatically instantiates a secondary viewport. The function `SetWindowViewport()` in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) (line 16058) binds the window to a new viewport object and synchronizes the window position through `window->Viewport->Pos`. This association happens transparently during the frame update when the configuration flag is enabled.

## Backend Integration Requirements

Multi-viewport support requires explicit cooperation from platform-specific backends to manage native OS windows. Each backend (Win32, GLFW, SDL, etc.) must implement callbacks for creating, destroying, and updating platform windows, as well as routing input events to the correct viewport.

According to the source comments in [`imgui_impl_win32.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_impl_win32.cpp) (line 139), the docking branch contains the reference implementation for multi-viewport support. Backends must register input callbacks such as `io.AddMouseViewportEvent()` to ensure mouse events route to the correct viewport window.

Initialize your platform and renderer backends before the main loop:

```cpp
// Platform-specific initialization (Win32 example shown)
ImGui_ImplWin32_Init(hwnd);
ImGui_ImplOpenGL3_Init("#version 130");

```

## The Viewport Rendering Pipeline

When viewports are enabled, the rendering pipeline extends beyond the standard single-window approach. Dear ImGui iterates through all active viewports during the frame update and delegates platform-specific rendering to the backend.

### Frame Updates and Draw Data

During `ImGui::Render()`, the system calls `UpdateViewportsNewFrame()` to process the `g.Viewports` array. Each viewport generates its own draw data, with the owner relationship stored in `draw_data->OwnerViewport` (line 5957 in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp)). This allows the backend to associate render commands with the correct platform window handle.

### Platform Window Management

After rendering the main viewport, you must explicitly update and render secondary viewports. The following code belongs in your main loop after standard ImGui rendering:

```cpp
// Standard ImGui frame rendering
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

// Multi-viewport specific rendering
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
    ImGui::UpdatePlatformWindows();        // Create/update/destroy platform windows
    ImGui::RenderPlatformWindowsDefault(); // Render secondary viewports
}

```

The `UpdatePlatformWindows()` function handles the lifecycle of native windows—creating them when ImGui windows leave the main viewport and destroying them when they return. The `RenderPlatformWindowsDefault()` function executes the backend-specific rendering for each secondary viewport.

## Advanced: Manual Viewport Management

For specialized scenarios such as embedding ImGui into existing native windows or creating dedicated tool windows, you can manually create and configure viewports. Each `ImGuiViewport` structure contains a `void* PlatformHandleRaw` field (lines 660-665 in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp)) that backends populate with native window handles, replacing the deprecated `ImeWindowHandle` approach.

To draw directly onto a specific viewport:

```cpp
ImGuiViewport* viewport = ImGui::GetMainViewport();
ImDrawList* draw_list = ImGui::GetForegroundDrawList(viewport);  // Lines 5309-5311
draw_list->AddText(ImVec2(10, 10), IM_COL32(255, 255, 255, 255), "Overlay Text");

```

You can also create viewports programmatically for custom window arrangements:

```cpp
ImGuiViewport* secondary = ImGui::CreateViewport();   // Allocate new viewport
secondary->Pos = ImVec2(800, 100);
secondary->Size = ImVec2(400, 300);
secondary->Flags = ImGuiViewportFlags_NoTaskBarIcon;
secondary->PlatformHandleRaw = (void*)my_native_hwnd; // Bind to existing window

```

## Summary

- **Enable the configuration flag**: Set `ImGuiConfigFlags_ViewportsEnable` in `io.ConfigFlags` immediately after context creation, as defined in [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h) (lines 1710-1724).
- **Use the docking branch**: Multi-viewport support requires the docking branch of Dear ImGui, which contains the necessary backend implementations and viewport management code.
- **Update your render loop**: Call `ImGui::UpdatePlatformWindows()` and `ImGui::RenderPlatformWindowsDefault()` after standard rendering to handle secondary viewports.
- **Understand viewport storage**: Viewports are `ImGuiViewport` objects (internally `ImGuiViewportP`) stored in `g.Viewports`, with the primary accessible via `GetMainViewport()` (line 16052).
- **Leverage platform handles**: Use `PlatformHandleRaw` to bind viewports to existing native windows and `GetForegroundDrawList(viewport)` (lines 5309-5311) for direct rendering.

## Frequently Asked Questions

### What is the difference between the docking branch and multi-viewport support?

The docking branch contains both window docking functionality and the multi-viewport implementation. While the master branch provides core Dear ImGui, the specific code for `ImGuiConfigFlags_ViewportsEnable` and associated backend support resides exclusively in the docking branch. The comments in [`imgui_impl_win32.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_impl_win32.cpp) (line 139) indicate that this branch is the preferred source for obtaining multi-viewport capabilities.

### Do all backends support multi-viewport functionality?

No, multi-viewport support requires explicit implementation in each platform backend. The official repository provides reference implementations for Win32 ([`imgui_impl_win32.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_impl_win32.cpp)), GLFW ([`imgui_impl_glfw.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_impl_glfw.cpp)), and SDL. Each backend must handle native window creation, destruction, and event forwarding. If you use a custom backend, you must implement the viewport-related platform interfaces yourself.

### How does Dear ImGui route input to the correct viewport?

Each viewport receives input independently through backend callbacks. When the mouse moves over a secondary viewport, the backend calls `io.AddMouseViewportEvent()` to notify Dear ImGui which viewport currently owns the input. The internal function `SetWindowViewport()` (line 16058 in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp)) uses this information to associate user interactions with the correct ImGui windows, regardless of which native OS window they occupy.

### Can I prevent specific ImGui windows from creating new viewports?

Yes, you can control viewport creation behavior through window flags and manual viewport assignment. While the default behavior automatically creates viewports when windows are dragged outside the main window, you can use `ImGuiWindowFlags_NoMove` to restrict window movement or manually assign windows to specific viewports using `SetWindowViewport()`. For windows that should remain docked to the main viewport, avoid dragging them outside the primary window bounds or explicitly set their viewport to `GetMainViewport()`.