How to Implement Multi-Viewport Support in Dear ImGui
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 (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:
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, 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 (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):
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 (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 (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:
// 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). 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:
// 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) that backends populate with native window handles, replacing the deprecated ImeWindowHandle approach.
To draw directly onto a specific viewport:
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:
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_ViewportsEnableinio.ConfigFlagsimmediately after context creation, as defined inimgui.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()andImGui::RenderPlatformWindowsDefault()after standard rendering to handle secondary viewports. - Understand viewport storage: Viewports are
ImGuiViewportobjects (internallyImGuiViewportP) stored ing.Viewports, with the primary accessible viaGetMainViewport()(line 16052). - Leverage platform handles: Use
PlatformHandleRawto bind viewports to existing native windows andGetForegroundDrawList(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 (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), GLFW (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) 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().
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 →