How to Enable Multi-Viewport Support in ImGui for Detached Windows
To enable multi-viewport support in Dear ImGui, set the ImGuiConfigFlags_ViewportsEnable flag in ImGuiIO::ConfigFlags, ensure your backend reports ImGuiBackendFlags_PlatformHasViewports, and call ImGui::UpdatePlatformWindows() and ImGui::RenderPlatformWindowsDefault() after your main render loop each frame.
Multi-viewport support allows ImGui windows to break out of the main application window and exist as independent native OS windows. This feature requires specific configuration in the ImGui context setup and proper backend integration to manage platform window creation and rendering.
Setting the Viewport Configuration Flag
Before initializing your backend, you must explicitly enable the multi-viewport feature in the ImGui configuration flags. This instructs the library to track and manage multiple viewport contexts.
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
// Enable multi-viewport support for detached windows
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
// Optional: Enable docking support alongside viewports
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
According to the ocornut/imgui source code, the ImGuiConfigFlags_ViewportsEnable constant is defined in imgui.h within the ImGuiConfigFlags_ enumeration. Without this flag, ImGui treats all windows as belonging to a single main viewport regardless of their position.
Ensuring Backend Support for Platform Windows
Your chosen backend must advertise its capability to handle platform windows by setting the ImGuiBackendFlags_PlatformHasViewports flag. Most official backends—including GLFW, SDL2, and Win32—automatically set this flag during initialization.
When calling backend-specific initialization functions (such as ImGui_ImplGlfw_InitForOpenGL), the backend implementation sets the required flags internally. For example, in backends/imgui_impl_glfw.cpp, the initialization code sets:
io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports;
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // If supported
If you are implementing a custom backend, you must manually set ImGuiBackendFlags_PlatformHasViewports in ImGuiIO::BackendFlags to indicate that your platform layer can create and manage separate OS windows.
Updating and Rendering Platform Windows Each Frame
The standard ImGui render loop only handles the main viewport. When multi-viewport support is active, you must explicitly update and render additional platform windows after processing the primary draw data.
Place the following calls after your main ImGui::Render() and backend-specific draw data rendering:
// Standard ImGui frame rendering
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
// Handle multi-viewport windows
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
ImGui::UpdatePlatformWindows(); // Create/update OS windows
ImGui::RenderPlatformWindowsDefault(); // Render content to each viewport
}
As implemented in imgui.cpp, UpdatePlatformWindows() synchronizes the ImGui viewport data with platform-specific window objects, while RenderPlatformWindowsDefault() iterates through all active viewports and invokes the appropriate backend render callbacks for each detached window.
Optional Styling Adjustments for Seamless Integration
Detached OS windows may exhibit visual artifacts if ImGui's default styling uses transparency or rounded corners that clip against the window frame. To ensure a seamless desktop appearance, adjust the window style properties:
ImGuiStyle& style = ImGui::GetStyle();
style.WindowRounding = 0.0f; // Disable rounding for crisp edges
style.Colors[ImGuiCol_WindowBg].w = 1.0f; // Ensure fully opaque backgrounds
These adjustments are not strictly required for functionality but prevent visual inconsistencies when ImGui windows float outside the main application boundary.
Complete Implementation Example (GLFW + OpenGL3)
Below is a minimal, runnable implementation demonstrating the full setup required for multi-viewport support using the GLFW and OpenGL3 backends:
// Setup
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable multi-viewport
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Optional docking
// Initialize backends
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init("#version 150");
// Main loop
while (!glfwWindowShouldClose(window))
{
glfwPollEvents();
// Start ImGui frame
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
// Build UI
ImGui::Begin("Detached Window Demo");
ImGui::Text("Drag this window outside the main window to detach it");
ImGui::End();
// Render to main viewport
ImGui::Render();
int display_w, display_h;
glfwGetFramebufferSize(window, &display_w, &display_h);
glViewport(0, 0, display_w, display_h);
glClear(GL_COLOR_BUFFER_BIT);
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
// Render additional viewports if enabled
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
ImGui::UpdatePlatformWindows();
ImGui::RenderPlatformWindowsDefault();
}
glfwSwapBuffers(window);
}
// Cleanup
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
Summary
- Enable
ImGuiConfigFlags_ViewportsEnableinImGuiIO::ConfigFlagsbefore backend initialization to activate the multi-viewport system. - Verify backend capability by ensuring
ImGuiBackendFlags_PlatformHasViewportsis set inImGuiIO::BackendFlags(automatic in official backends like GLFW and SDL2). - Call platform window functions—specifically
ImGui::UpdatePlatformWindows()andImGui::RenderPlatformWindowsDefault()—after your main render loop to handle detached window creation and rendering. - Adjust styling by disabling window rounding and ensuring opaque backgrounds for a native desktop appearance.
Frequently Asked Questions
What ImGui backends support multi-viewport functionality?
The official Dear ImGui backends that support multi-viewport functionality include GLFW (imgui_impl_glfw.cpp), SDL2 (imgui_impl_sdl2.cpp), Win32 (imgui_impl_win32.cpp), and macOS/iOS implementations. These backends automatically set ImGuiBackendFlags_PlatformHasViewports during initialization and implement the required platform window creation and management callbacks. Custom backends must manually implement these interfaces to support detached windows.
Can I use multi-viewport support without docking?
Yes, multi-viewport support is independent of the docking system. While the two features are often used together—set via ImGuiConfigFlags_DockingEnable—you can enable viewports alone by setting only ImGuiConfigFlags_ViewportsEnable. This allows windows to detach into separate OS windows without the tab-based docking interface appearing when windows overlap.
Why do my detached windows appear black or fail to render?
Black or unrendered detached windows typically indicate that ImGui::RenderPlatformWindowsDefault() is not being called after the main render loop, or that the backend's renderer implementation lacks viewport support. Ensure your renderer backend (such as OpenGL3, Vulkan, or DirectX) sets ImGuiBackendFlags_RendererHasViewports and that you call the update and render functions every frame when the viewports flag is enabled.
Where are the viewport structures defined in the source code?
The public ImGuiViewport structure and related flags are defined in imgui.h, while the internal implementation details—including the ImGuiViewportP class used for platform window management—reside in imgui_internal.h. The core logic for viewport creation and destruction is implemented in imgui.cpp, specifically within the UpdatePlatformWindows() and RenderPlatformWindowsDefault() functions.
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 →