From 50a8bb2711e466060eac5849260f36ee5940dbec Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 30 Sep 2025 17:38:06 +0200 Subject: [PATCH] Viewports: added ImGuiBackendFlags_HasParentViewportId backend flag. (#8948) --- backends/imgui_impl_glfw.cpp | 2 +- backends/imgui_impl_glfw.h | 2 +- backends/imgui_impl_osx.h | 2 +- backends/imgui_impl_osx.mm | 2 +- backends/imgui_impl_sdl2.cpp | 2 +- backends/imgui_impl_sdl2.h | 2 +- backends/imgui_impl_sdl3.cpp | 8 ++++++-- backends/imgui_impl_win32.cpp | 3 ++- docs/BACKENDS.md | 1 + docs/CHANGELOG.txt | 5 +++++ imgui.h | 9 +++++---- imgui_demo.cpp | 2 ++ 12 files changed, 27 insertions(+), 13 deletions(-) diff --git a/backends/imgui_impl_glfw.cpp b/backends/imgui_impl_glfw.cpp index 31da48289..c4b5f8822 100644 --- a/backends/imgui_impl_glfw.cpp +++ b/backends/imgui_impl_glfw.cpp @@ -14,7 +14,7 @@ // Missing features or Issues: // [ ] Platform: Touch events are only correctly identified as Touch on Windows. This create issues with some interactions. GLFW doesn't provide a way to identify touch inputs from mouse inputs, we cannot call io.AddMouseSourceEvent() to identify the source. We provide a Windows-specific workaround. // [ ] Platform: Missing ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress cursors. -// [ ] Platform: Multi-viewport: viewport->ParentViewportID is ignored, and therefore io.ConfigViewportsNoDefaultParent has no effect either. +// [ ] Platform: Multi-viewport: Missing ImGuiBackendFlags_HasParentViewportId support. The viewport->ParentViewportID field is ignored, and therefore io.ConfigViewportsNoDefaultParent has no effect either. // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. diff --git a/backends/imgui_impl_glfw.h b/backends/imgui_impl_glfw.h index 37525caef..f1fa10307 100644 --- a/backends/imgui_impl_glfw.h +++ b/backends/imgui_impl_glfw.h @@ -14,7 +14,7 @@ // Missing features or Issues: // [ ] Platform: Touch events are only correctly identified as Touch on Windows. This create issues with some interactions. GLFW doesn't provide a way to identify touch inputs from mouse inputs, we cannot call io.AddMouseSourceEvent() to identify the source. We provide a Windows-specific workaround. // [ ] Platform: Missing ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress cursors. -// [ ] Platform: Multi-viewport: viewport->ParentViewportID is ignored, and therefore io.ConfigViewportsNoDefaultParent has no effect either. +// [ ] Platform: Multi-viewport: Missing ImGuiBackendFlags_HasParentViewportId support. The viewport->ParentViewportID field is ignored, and therefore io.ConfigViewportsNoDefaultParent has no effect either. // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. diff --git a/backends/imgui_impl_osx.h b/backends/imgui_impl_osx.h index 4c2cde35a..121ca5d9a 100644 --- a/backends/imgui_impl_osx.h +++ b/backends/imgui_impl_osx.h @@ -13,7 +13,7 @@ // [x] Platform: Multi-viewport / platform windows. // Missing features or Issues: // [ ] Platform: Multi-viewport: Window size not correctly reported when enabling io.ConfigViewportsNoDecoration -// [ ] Platform: Multi-viewport: viewport->ParentViewportID is ignored, and therefore io.ConfigViewportsNoDefaultParent has no effect either. +// [ ] Platform: Multi-viewport: Missing ImGuiBackendFlags_HasParentViewportId support. The viewport->ParentViewportID field is ignored, and therefore io.ConfigViewportsNoDefaultParent has no effect either. // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. diff --git a/backends/imgui_impl_osx.mm b/backends/imgui_impl_osx.mm index 2345efbe8..7dc8cae25 100644 --- a/backends/imgui_impl_osx.mm +++ b/backends/imgui_impl_osx.mm @@ -13,7 +13,7 @@ // [x] Platform: Multi-viewport / platform windows. // Missing features or Issues: // [ ] Platform: Multi-viewport: Window size not correctly reported when enabling io.ConfigViewportsNoDecoration -// [ ] Platform: Multi-viewport: viewport->ParentViewportID is ignored, and therefore io.ConfigViewportsNoDefaultParent has no effect either. +// [ ] Platform: Multi-viewport: Missing ImGuiBackendFlags_HasParentViewportId support. The viewport->ParentViewportID field is ignored, and therefore io.ConfigViewportsNoDefaultParent has no effect either. // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. diff --git a/backends/imgui_impl_sdl2.cpp b/backends/imgui_impl_sdl2.cpp index fb1a1e367..635655cb9 100644 --- a/backends/imgui_impl_sdl2.cpp +++ b/backends/imgui_impl_sdl2.cpp @@ -13,7 +13,7 @@ // [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. // Missing features or Issues: // [ ] Platform: Multi-viewport: Minimized windows seems to break mouse wheel events (at least under Windows). -// [ ] Platform: Multi-viewport: viewport->ParentViewportID is ignored, and therefore io.ConfigViewportsNoDefaultParent has no effect either. +// [ ] Platform: Multi-viewport: Missing ImGuiBackendFlags_HasParentViewportId support. The viewport->ParentViewportID field is ignored, and therefore io.ConfigViewportsNoDefaultParent has no effect either. // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. diff --git a/backends/imgui_impl_sdl2.h b/backends/imgui_impl_sdl2.h index 0cf005cf6..715429863 100644 --- a/backends/imgui_impl_sdl2.h +++ b/backends/imgui_impl_sdl2.h @@ -12,7 +12,7 @@ // [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. // Missing features or Issues: // [ ] Platform: Multi-viewport: Minimized windows seems to break mouse wheel events (at least under Windows). -// [ ] Platform: Multi-viewport: viewport->ParentViewportID is ignored, and therefore io.ConfigViewportsNoDefaultParent has no effect either. +// [ ] Platform: Multi-viewport: Missing ImGuiBackendFlags_HasParentViewportId support. The viewport->ParentViewportID field is ignored, and therefore io.ConfigViewportsNoDefaultParent has no effect either. // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. diff --git a/backends/imgui_impl_sdl3.cpp b/backends/imgui_impl_sdl3.cpp index 670b2e4a8..a581a7e3d 100644 --- a/backends/imgui_impl_sdl3.cpp +++ b/backends/imgui_impl_sdl3.cpp @@ -534,7 +534,8 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void io.BackendPlatformName = bd->BackendPlatformName; io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) - // (ImGuiBackendFlags_PlatformHasViewports may be set just below) + // (ImGuiBackendFlags_PlatformHasViewports and ImGuiBackendFlags_HasParentViewportId may be set just below) + // (ImGuiBackendFlags_HasMouseHoveredViewport is set dynamically in our _NewFrame function) bd->Window = window; bd->WindowID = SDL_GetWindowID(window); @@ -560,7 +561,10 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void bd->MouseCanUseGlobalState = bd->MouseCanUseCapture = true; #endif if (bd->MouseCanUseGlobalState) + { io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional) + io.BackendFlags |= ImGuiBackendFlags_HasParentViewportId; // We can honor viewport->ParentViewportId by applying the corresponding parent/child relationship at platform levle (optional) + } ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); platform_io.Platform_SetClipboardTextFn = ImGui_ImplSDL3_SetClipboardText; @@ -675,7 +679,7 @@ void ImGui_ImplSDL3_Shutdown() io.BackendPlatformName = nullptr; io.BackendPlatformUserData = nullptr; - io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport); + io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport | ImGuiBackendFlags_HasParentViewportId); platform_io.ClearPlatformHandlers(); IM_DELETE(bd); } diff --git a/backends/imgui_impl_win32.cpp b/backends/imgui_impl_win32.cpp index 4312e4ff4..bb7ef89d3 100644 --- a/backends/imgui_impl_win32.cpp +++ b/backends/imgui_impl_win32.cpp @@ -189,6 +189,7 @@ static bool ImGui_ImplWin32_InitEx(void* hwnd, bool platform_has_own_dc) io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional) io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can call io.AddMouseViewportEvent() with correct data (optional) + io.BackendFlags |= ImGuiBackendFlags_HasParentViewportId; // We can honor viewport->ParentViewportId by applying the corresponding parent/child relationship at platform levle (optional) bd->hWnd = (HWND)hwnd; bd->TicksPerSecond = perf_frequency; @@ -261,7 +262,7 @@ void ImGui_ImplWin32_Shutdown() io.BackendPlatformName = nullptr; io.BackendPlatformUserData = nullptr; - io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport); + io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport | ImGuiBackendFlags_HasParentViewportId); platform_io.ClearPlatformHandlers(); IM_DELETE(bd); } diff --git a/docs/BACKENDS.md b/docs/BACKENDS.md index 629f8d83f..bbd586f20 100644 --- a/docs/BACKENDS.md +++ b/docs/BACKENDS.md @@ -182,6 +182,7 @@ The Platform backends in impl_impl_XXX.cpp files contain many implementations. - `ImGuiBackendFlags_HasSetMousePos`: supports io.WantSetMousePos requests to reposition the OS mouse position (only used if io.ConfigNavMoveSetMousePos is set). - `ImGuiBackendFlags_PlatformHasViewports` supports multiple viewports. (multi-viewports only) - `ImGuiBackendFlags_HasMouseHoveredViewport` supports calling io.AddMouseViewportEvent() with the viewport under the mouse. IF POSSIBLE, ignore viewports with the ImGuiViewportFlags_NoInputs flag. If this cannot be done, Dear ImGui needs to use a flawed heuristic to find the viewport under mouse position, as it doesn't know about foreign windows. (multi-viewports only) + - `ImGuiBackendFlags_HasParentViewportId` supports honoring viewport->ParentViewportId value, by applying the corresponding parent/child relation at the Platform level. **In your `ImGui_ImplXXX_NewFrame()` function:** - Set `io.DeltaTime` to the time elapsed (in seconds) since last frame. diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 063a51ebb..7c46aa333 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -105,6 +105,11 @@ Docking+Viewports Branch: - Nav: fixed a crash that could occur when opening a popup following the processing of a global shortcut while no windows were focused (the fix done in 1.92.3 was incomplete for docking branch). +- Viewports: added ImGuiBackendFlags_HasParentViewportId backend flag for + backend to specify if it can honor the viewport->ParentViewportId value by + applying the corresponding parent/child relation at the Platform level. (#8948) + - SDL3, Win32 backends: supported. + - SDL2, GLFW, OSX backends: unsupported. - Viewports: fixed a bug where ImGuiWindowFlags_NoBringToFrontOnFocus would effectivey be ignored when windows first appear and viewports are enabled. (#7008) [@jshofmann] - Viewports: changed default value of io.ConfigViewportsNoDefaultParent to true. (#8948) diff --git a/imgui.h b/imgui.h index 961397dd6..a06efdd7b 100644 --- a/imgui.h +++ b/imgui.h @@ -1785,10 +1785,11 @@ enum ImGuiBackendFlags_ ImGuiBackendFlags_RendererHasVtxOffset = 1 << 3, // Backend Renderer supports ImDrawCmd::VtxOffset. This enables output of large meshes (64K+ vertices) while still using 16-bit indices. ImGuiBackendFlags_RendererHasTextures = 1 << 4, // Backend Renderer supports ImTextureData requests to create/update/destroy textures. This enables incremental texture updates and texture reloads. See https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md for instructions on how to upgrade your custom backend. - // [BETA] Viewports - ImGuiBackendFlags_PlatformHasViewports = 1 << 10, // Backend Platform supports multiple viewports. - ImGuiBackendFlags_HasMouseHoveredViewport=1 << 11, // Backend Platform supports calling io.AddMouseViewportEvent() with the viewport under the mouse. IF POSSIBLE, ignore viewports with the ImGuiViewportFlags_NoInputs flag (Win32 backend, GLFW 3.30+ backend can do this, SDL backend cannot). If this cannot be done, Dear ImGui needs to use a flawed heuristic to find the viewport under. - ImGuiBackendFlags_RendererHasViewports = 1 << 12, // Backend Renderer supports multiple viewports. + // [BETA] Multi-Viewports + ImGuiBackendFlags_RendererHasViewports = 1 << 10, // Backend Renderer supports multiple viewports. + ImGuiBackendFlags_PlatformHasViewports = 1 << 11, // Backend Platform supports multiple viewports. + ImGuiBackendFlags_HasMouseHoveredViewport=1 << 12, // Backend Platform supports calling io.AddMouseViewportEvent() with the viewport under the mouse. IF POSSIBLE, ignore viewports with the ImGuiViewportFlags_NoInputs flag (Win32 backend, GLFW 3.30+ backend can do this, SDL backend cannot). If this cannot be done, Dear ImGui needs to use a flawed heuristic to find the viewport under. + ImGuiBackendFlags_HasParentViewportId = 1 << 13, // Backend Platform supports honoring viewport->ParentViewportId value, by applying the corresponding parent/child relation at the Platform level. }; // Enumeration for PushStyleColor() / PopStyleColor() diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 19673368f..f7f9064dd 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -640,6 +640,7 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::CheckboxFlags("io.BackendFlags: HasSetMousePos", &io.BackendFlags, ImGuiBackendFlags_HasSetMousePos); ImGui::CheckboxFlags("io.BackendFlags: PlatformHasViewports", &io.BackendFlags, ImGuiBackendFlags_PlatformHasViewports); ImGui::CheckboxFlags("io.BackendFlags: HasMouseHoveredViewport",&io.BackendFlags, ImGuiBackendFlags_HasMouseHoveredViewport); + ImGui::CheckboxFlags("io.BackendFlags: HasParentViewportId", &io.BackendFlags, ImGuiBackendFlags_HasParentViewportId); ImGui::CheckboxFlags("io.BackendFlags: RendererHasVtxOffset", &io.BackendFlags, ImGuiBackendFlags_RendererHasVtxOffset); ImGui::CheckboxFlags("io.BackendFlags: RendererHasTextures", &io.BackendFlags, ImGuiBackendFlags_RendererHasTextures); ImGui::CheckboxFlags("io.BackendFlags: RendererHasViewports", &io.BackendFlags, ImGuiBackendFlags_RendererHasViewports); @@ -8298,6 +8299,7 @@ void ImGui::ShowAboutWindow(bool* p_open) if (io.BackendFlags & ImGuiBackendFlags_HasSetMousePos) ImGui::Text(" HasSetMousePos"); if (io.BackendFlags & ImGuiBackendFlags_PlatformHasViewports) ImGui::Text(" PlatformHasViewports"); if (io.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport)ImGui::Text(" HasMouseHoveredViewport"); + if (io.BackendFlags & ImGuiBackendFlags_HasParentViewportId) ImGui::Text(" HasParentViewportId"); if (io.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset) ImGui::Text(" RendererHasVtxOffset"); if (io.BackendFlags & ImGuiBackendFlags_RendererHasTextures) ImGui::Text(" RendererHasTextures"); if (io.BackendFlags & ImGuiBackendFlags_RendererHasViewports) ImGui::Text(" RendererHasViewports");