# How to Implement Multi-Viewport Support in Dear ImGui: A Complete Guide

> Implement multi-viewport support in Dear ImGui easily. Learn to enable viewports and configure backends in this complete guide. Boost your application's UI flexibility.

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

---

**To implement multi-viewport support in Dear ImGui, enable the `ImGuiConfigFlags_ViewportsEnable` flag in your `ImGuiIO` configuration and ensure your platform backend implements the required window creation and event forwarding callbacks.**

Dear ImGui's multi-viewport feature allows UI windows to be dragged outside the main application window into separate native OS windows. This article explains the implementation details based on the `ocornut/imgui` source code, covering configuration flags, internal viewport management, and backend integration requirements.

## What Is Multi-Viewport Support?

Multi-viewport support enables Dear ImGui to render interface elements onto multiple native platform windows simultaneously. Internally, each viewport is represented by an `ImGuiViewport` object that owns a platform-specific window handle—such as an `HWND` on Windows or an X11/Wayland window on Linux.

When `ImGuiConfigFlags_ViewportsEnable` is active, ImGui creates a **primary viewport** that owns the main rendering context, plus additional **secondary viewports** on demand whenever an ImGui window is dragged outside the main window boundaries.

## Enabling the Multi-Viewport Configuration Flag

The first step to implement multi-viewport support in Dear ImGui is setting the configuration flag immediately after creating the ImGui context. According to [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h), the `ImGuiConfigFlags_ViewportsEnable` value is defined in the `ImGuiConfigFlags_` enum alongside other behavioral flags.

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

```

This flag signals ImGui to allocate viewport objects and invoke platform-specific backend callbacks during the frame lifecycle. Without this flag set, all rendering remains constrained to the single main window regardless of user interactions.

## Internal Viewport Management

### Viewport Creation and Storage

In [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp), the core engine manages viewports through the global context `g.Viewports`. During the first frame, ImGui automatically allocates the primary viewport using `IM_NEW`, as implemented around line 4483 in the source. This viewport is stored in the dynamic array `g.Viewports` and remains persistent for the application's lifetime.

You can retrieve this primary viewport at any time using:

```cpp
ImGuiViewport* main_viewport = ImGui::GetMainViewport();

```

The `GetMainViewport()` function, defined in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) near line 16052, returns the first viewport in the array, which corresponds to the main application window.

### Dynamic Viewport Association

When a user drags an ImGui window outside the main work area, ImGui automatically creates secondary viewports. The internal function `ImGui::SetWindowViewport`, referenced around line 16058 in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp), binds the floating window to a new `ImGuiViewport` object and updates the window's position via `window->Viewport->Pos`.

This process is transparent to user code—windows automatically gain their own OS window handles when dragged beyond the primary viewport boundaries.

## Backend Requirements for Multi-Viewport Support

Multi-viewport functionality requires explicit backend support. Each platform backend (Win32, GLFW, SDL, etc.) must implement callbacks for creating, destroying, and managing platform windows for secondary viewports.

### Win32 Backend Implementation

The Win32 backend in [`backends/imgui_impl_win32.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_win32.cpp) contains platform-specific logic for multi-viewport support. As noted in the comments around line 139, the docking branch contains the necessary multi-viewport code for this backend. The backend registers mouse viewport events using `io.AddMouseViewportEvent()` to route input to the correct viewport window.

### GLFW Backend Implementation

Similarly, [`backends/imgui_impl_glfw.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_glfw.cpp) implements the required platform window creation and destruction routines for GLFW-based applications. Both backends follow the same pattern of implementing the `ImGuiPlatformIO` interface functions that ImGui calls when viewports are created or destroyed.

## Rendering Secondary Viewports

When multi-viewport is enabled, the standard render loop requires additional calls to handle secondary windows. During `ImGui::Render()`, the internal function `UpdateViewportsNewFrame()` iterates over `g.Viewports` (including the primary viewport) and prepares draw data for each one, storing viewport ownership in `draw_data->OwnerViewport` as seen around line 5957 in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp).

Your render loop must explicitly update and render platform windows:

```cpp
// Standard frame preparation
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplWin32_NewFrame();  // Or your specific backend
ImGui::NewFrame();

// ... your UI code ...

// Standard rendering
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

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

```

`UpdatePlatformWindows()` processes viewport creation, destruction, and position updates, while `RenderPlatformWindowsDefault()` handles the actual rendering submission for all secondary viewports.

## Working with Viewport Objects Programmatically

### Accessing Viewport Draw Lists

For advanced rendering scenarios, you can draw directly onto specific viewports using `ImGui::GetForegroundDrawList(viewport)`. This function, defined around lines 5309-5311 in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp), accepts an `ImGuiViewport*` parameter and returns a draw list that renders on top of all windows within that viewport.

```cpp
ImGuiViewport* viewport = ImGui::GetMainViewport();
ImDrawList* draw_list = ImGui::GetForegroundDrawList(viewport);
draw_list->AddCircle(viewport->GetCenter(), 50.0f, IM_COL32(255, 0, 0, 255));

```

### Creating Custom Viewports

While ImGui creates viewports automatically for dragged windows, you can manually create viewports for specific embedding scenarios:

```cpp
ImGuiViewport* secondary = ImGui::CreateViewport();
secondary->Pos = ImVec2(800, 100);
secondary->Size = ImVec2(400, 300);
secondary->Flags = ImGuiViewportFlags_NoTaskBarIcon;
secondary->PlatformHandleRaw = (void*)my_native_hwnd;  // Platform-specific handle

```

As documented in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) around lines 660-665, the `PlatformHandleRaw` field replaces the deprecated `ImeWindowHandle` field and stores the native window handle for platform-specific operations.

## Summary

- **Enable the flag**: Set `ImGuiConfigFlags_ViewportsEnable` in `io.ConfigFlags` after creating the ImGui context.
- **Backend support**: Ensure your platform backend (Win32, GLFW, SDL) implements the viewport management callbacks required for window creation and event forwarding.
- **Render loop**: Call `ImGui::UpdatePlatformWindows()` and `ImGui::RenderPlatformWindowsDefault()` after your standard render call to process secondary viewports.
- **Internal storage**: Viewports are stored in `g.Viewports` with the primary viewport accessible via `ImGui::GetMainViewport()`.
- **Native handles**: Use `PlatformHandleRaw` in `ImGuiViewport` structures for advanced platform-specific window embedding.

## Frequently Asked Questions

### What is the difference between the primary viewport and secondary viewports?

The **primary viewport** is created automatically during the first frame and corresponds to the main application window that owns the rendering context. **Secondary viewports** are created dynamically when ImGui windows are dragged outside the primary viewport boundaries, each owning a separate native OS window. According to [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp), both are stored in the same `g.Viewports` array but serve different lifecycle roles.

### Which backends support multi-viewport functionality?

The official backends in [`backends/imgui_impl_win32.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_win32.cpp), [`backends/imgui_impl_glfw.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_glfw.cpp), and [`backends/imgui_impl_sdl.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_sdl.cpp) support multi-viewport functionality when using the docking branch of Dear ImGui. Each backend implements the `ImGuiPlatformIO` interface functions for creating, destroying, and managing platform-specific window handles. The Win32 backend specifically notes in its implementation that the docking branch is required for full multi-viewport support.

### How do I render content directly onto a specific viewport?

Use `ImGui::GetForegroundDrawList(viewport)` to obtain a draw list associated with a specific `ImGuiViewport` pointer. This function, implemented in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp), allows you to submit draw commands that render on top of all windows within that viewport. You can retrieve the main viewport using `ImGui::GetMainViewport()` or iterate through all viewports via the internal context structure.

### Why are my windows not creating separate OS windows when dragged?

If windows remain constrained to the main window when dragged, verify that `ImGuiConfigFlags_ViewportsEnable` is set in `io.ConfigFlags` before the first `ImGui::NewFrame()` call. Additionally, confirm that your backend implements the required viewport callbacks and that you are calling `ImGui::UpdatePlatformWindows()` and `ImGui::RenderPlatformWindowsDefault()` in your render loop. Missing any of these steps prevents the automatic creation of secondary viewports.