Viewport: extracted code out of Begin() into WindowSyncOwnedViewport() - no other change
diff --git a/imgui.cpp b/imgui.cpp
index 0d62709..552b361 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -946,7 +946,8 @@
static ImGuiViewportP* AddUpdateViewport(ImGuiWindow* window, ImGuiID id, const ImVec2& platform_pos, const ImVec2& size, ImGuiViewportFlags flags);
static void UpdateViewportsNewFrame();
static void UpdateViewportsEndFrame();
-static void UpdateSelectWindowViewport(ImGuiWindow* window);
+static void WindowSelectViewport(ImGuiWindow* window);
+static void WindowSyncOwnedViewport(ImGuiWindow* window, ImGuiWindow* parent_window_in_stack);
static bool UpdateTryMergeWindowIntoHostViewport(ImGuiWindow* window, ImGuiViewportP* host_viewport);
static bool UpdateTryMergeWindowIntoHostViewports(ImGuiWindow* window);
static bool GetWindowAlwaysWantOwnViewport(ImGuiWindow* window);
@@ -6315,7 +6316,7 @@
// SELECT VIEWPORT
// We need to do this before using any style/font sizes, as viewport with a different DPI may affect font sizes.
- UpdateSelectWindowViewport(window);
+ WindowSelectViewport(window);
SetCurrentViewport(window, window->Viewport);
window->FontDpiScale = (g.IO.ConfigFlags & ImGuiConfigFlags_DpiEnableScaleFonts) ? window->Viewport->DpiScale : 1.0f;
SetCurrentWindow(window);
@@ -6447,85 +6448,8 @@
SetCurrentWindow(window);
}
- bool viewport_rect_changed = false;
if (window->ViewportOwned)
- {
- // Synchronize window --> viewport in most situations
- // Synchronize viewport -> window in case the platform window has been moved or resized from the OS/WM
- if (window->Viewport->PlatformRequestMove)
- {
- window->Pos = window->Viewport->Pos;
- MarkIniSettingsDirty(window);
- }
- else if (memcmp(&window->Viewport->Pos, &window->Pos, sizeof(window->Pos)) != 0)
- {
- viewport_rect_changed = true;
- window->Viewport->Pos = window->Pos;
- }
-
- if (window->Viewport->PlatformRequestResize)
- {
- window->Size = window->SizeFull = window->Viewport->Size;
- MarkIniSettingsDirty(window);
- }
- else if (memcmp(&window->Viewport->Size, &window->Size, sizeof(window->Size)) != 0)
- {
- viewport_rect_changed = true;
- window->Viewport->Size = window->Size;
- }
- window->Viewport->UpdateWorkRect();
-
- // The viewport may have changed monitor since the global update in UpdateViewportsNewFrame()
- // Either a SetNextWindowPos() call in the current frame or a SetWindowPos() call in the previous frame may have this effect.
- if (viewport_rect_changed)
- UpdateViewportPlatformMonitor(window->Viewport);
-
- // Update common viewport flags
- const ImGuiViewportFlags viewport_flags_to_clear = ImGuiViewportFlags_TopMost | ImGuiViewportFlags_NoTaskBarIcon | ImGuiViewportFlags_NoDecoration | ImGuiViewportFlags_NoRendererClear;
- ImGuiViewportFlags viewport_flags = window->Viewport->Flags & ~viewport_flags_to_clear;
- const bool is_modal = (flags & ImGuiWindowFlags_Modal) != 0;
- const bool is_short_lived_floating_window = (flags & (ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup)) != 0;
- if (flags & ImGuiWindowFlags_Tooltip)
- viewport_flags |= ImGuiViewportFlags_TopMost;
- if ((g.IO.ConfigViewportsNoTaskBarIcon || is_short_lived_floating_window) && !is_modal)
- viewport_flags |= ImGuiViewportFlags_NoTaskBarIcon;
- if (g.IO.ConfigViewportsNoDecoration || is_short_lived_floating_window)
- viewport_flags |= ImGuiViewportFlags_NoDecoration;
-
- // Not correct to set modal as topmost because:
- // - Because other popups can be stacked above a modal (e.g. combo box in a modal)
- // - ImGuiViewportFlags_TopMost is currently handled different in backends: in Win32 it is "appear top most" whereas in GLFW and SDL it is "stay topmost"
- //if (flags & ImGuiWindowFlags_Modal)
- // viewport_flags |= ImGuiViewportFlags_TopMost;
-
- // For popups and menus that may be protruding out of their parent viewport, we enable _NoFocusOnClick so that clicking on them
- // won't steal the OS focus away from their parent window (which may be reflected in OS the title bar decoration).
- // Setting _NoFocusOnClick would technically prevent us from bringing back to front in case they are being covered by an OS window from a different app,
- // but it shouldn't be much of a problem considering those are already popups that are closed when clicking elsewhere.
- if (is_short_lived_floating_window && !is_modal)
- viewport_flags |= ImGuiViewportFlags_NoFocusOnAppearing | ImGuiViewportFlags_NoFocusOnClick;
-
- // We can overwrite viewport flags using ImGuiWindowClass (advanced users)
- // We don't default to the main viewport because.
- if (window->WindowClass.ParentViewportId)
- window->Viewport->ParentViewportId = window->WindowClass.ParentViewportId;
- else if ((flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) && parent_window_in_stack)
- window->Viewport->ParentViewportId = parent_window_in_stack->Viewport->ID;
- else
- window->Viewport->ParentViewportId = g.IO.ConfigViewportsNoDefaultParent ? 0 : IMGUI_VIEWPORT_DEFAULT_ID;
- if (window->WindowClass.ViewportFlagsOverrideSet)
- viewport_flags |= window->WindowClass.ViewportFlagsOverrideSet;
- if (window->WindowClass.ViewportFlagsOverrideClear)
- viewport_flags &= ~window->WindowClass.ViewportFlagsOverrideClear;
-
- // We can also tell the backend that clearing the platform window won't be necessary,
- // as our window background is filling the viewport and we have disabled BgAlpha.
- // FIXME: Work on support for per-viewport transparency (#2766)
- if (!(flags & ImGuiWindowFlags_NoBackground))
- viewport_flags |= ImGuiViewportFlags_NoRendererClear;
-
- window->Viewport->Flags = viewport_flags;
- }
+ WindowSyncOwnedViewport(window, parent_window_in_stack);
// Calculate the range of allowed position for that window (to be movable and visible past safe area padding)
// When clamping to stay visible, we will enforce that window->Pos stays inside of visibility_rect.
@@ -11409,7 +11333,8 @@
// - UpdateViewportsNewFrame() [Internal]
// - UpdateViewportsEndFrame() [Internal]
// - AddUpdateViewport() [Internal]
-// - UpdateSelectWindowViewport() [Internal]
+// - WindowSelectViewport() [Internal]
+// - WindowSyncOwnedViewport() [Internal]
// - UpdatePlatformWindows()
// - RenderPlatformWindowsDefault()
// - FindPlatformMonitorForPos() [Internal]
@@ -11425,6 +11350,7 @@
return g.Viewports[0];
}
+// FIXME: This leaks access to viewports not listed in PlatformIO.Viewports[]. Problematic? (#4236)
ImGuiViewport* ImGui::FindViewportByID(ImGuiID id)
{
ImGuiContext& g = *GImGui;
@@ -11856,7 +11782,7 @@
}
// FIXME-VIEWPORT: This is all super messy and ought to be clarified or rewritten.
-static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window)
+static void ImGui::WindowSelectViewport(ImGuiWindow* window)
{
ImGuiContext& g = *GImGui;
ImGuiWindowFlags flags = window->Flags;
@@ -11983,6 +11909,89 @@
// window->Flags |= ImGuiWindowFlags_NoTitleBar;
}
+void ImGui::WindowSyncOwnedViewport(ImGuiWindow* window, ImGuiWindow* parent_window_in_stack)
+{
+ ImGuiContext& g = *GImGui;
+
+ bool viewport_rect_changed = false;
+
+ // Synchronize window --> viewport in most situations
+ // Synchronize viewport -> window in case the platform window has been moved or resized from the OS/WM
+ if (window->Viewport->PlatformRequestMove)
+ {
+ window->Pos = window->Viewport->Pos;
+ MarkIniSettingsDirty(window);
+ }
+ else if (memcmp(&window->Viewport->Pos, &window->Pos, sizeof(window->Pos)) != 0)
+ {
+ viewport_rect_changed = true;
+ window->Viewport->Pos = window->Pos;
+ }
+
+ if (window->Viewport->PlatformRequestResize)
+ {
+ window->Size = window->SizeFull = window->Viewport->Size;
+ MarkIniSettingsDirty(window);
+ }
+ else if (memcmp(&window->Viewport->Size, &window->Size, sizeof(window->Size)) != 0)
+ {
+ viewport_rect_changed = true;
+ window->Viewport->Size = window->Size;
+ }
+ window->Viewport->UpdateWorkRect();
+
+ // The viewport may have changed monitor since the global update in UpdateViewportsNewFrame()
+ // Either a SetNextWindowPos() call in the current frame or a SetWindowPos() call in the previous frame may have this effect.
+ if (viewport_rect_changed)
+ UpdateViewportPlatformMonitor(window->Viewport);
+
+ // Update common viewport flags
+ const ImGuiViewportFlags viewport_flags_to_clear = ImGuiViewportFlags_TopMost | ImGuiViewportFlags_NoTaskBarIcon | ImGuiViewportFlags_NoDecoration | ImGuiViewportFlags_NoRendererClear;
+ ImGuiViewportFlags viewport_flags = window->Viewport->Flags & ~viewport_flags_to_clear;
+ ImGuiWindowFlags window_flags = window->Flags;
+ const bool is_modal = (window_flags & ImGuiWindowFlags_Modal) != 0;
+ const bool is_short_lived_floating_window = (window_flags & (ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup)) != 0;
+ if (window_flags & ImGuiWindowFlags_Tooltip)
+ viewport_flags |= ImGuiViewportFlags_TopMost;
+ if ((g.IO.ConfigViewportsNoTaskBarIcon || is_short_lived_floating_window) && !is_modal)
+ viewport_flags |= ImGuiViewportFlags_NoTaskBarIcon;
+ if (g.IO.ConfigViewportsNoDecoration || is_short_lived_floating_window)
+ viewport_flags |= ImGuiViewportFlags_NoDecoration;
+
+ // Not correct to set modal as topmost because:
+ // - Because other popups can be stacked above a modal (e.g. combo box in a modal)
+ // - ImGuiViewportFlags_TopMost is currently handled different in backends: in Win32 it is "appear top most" whereas in GLFW and SDL it is "stay topmost"
+ //if (flags & ImGuiWindowFlags_Modal)
+ // viewport_flags |= ImGuiViewportFlags_TopMost;
+
+ // For popups and menus that may be protruding out of their parent viewport, we enable _NoFocusOnClick so that clicking on them
+ // won't steal the OS focus away from their parent window (which may be reflected in OS the title bar decoration).
+ // Setting _NoFocusOnClick would technically prevent us from bringing back to front in case they are being covered by an OS window from a different app,
+ // but it shouldn't be much of a problem considering those are already popups that are closed when clicking elsewhere.
+ if (is_short_lived_floating_window && !is_modal)
+ viewport_flags |= ImGuiViewportFlags_NoFocusOnAppearing | ImGuiViewportFlags_NoFocusOnClick;
+
+ // We can overwrite viewport flags using ImGuiWindowClass (advanced users)
+ if (window->WindowClass.ParentViewportId)
+ window->Viewport->ParentViewportId = window->WindowClass.ParentViewportId;
+ else if ((window_flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) && parent_window_in_stack)
+ window->Viewport->ParentViewportId = parent_window_in_stack->Viewport->ID;
+ else
+ window->Viewport->ParentViewportId = g.IO.ConfigViewportsNoDefaultParent ? 0 : IMGUI_VIEWPORT_DEFAULT_ID;
+ if (window->WindowClass.ViewportFlagsOverrideSet)
+ viewport_flags |= window->WindowClass.ViewportFlagsOverrideSet;
+ if (window->WindowClass.ViewportFlagsOverrideClear)
+ viewport_flags &= ~window->WindowClass.ViewportFlagsOverrideClear;
+
+ // We can also tell the backend that clearing the platform window won't be necessary,
+ // as our window background is filling the viewport and we have disabled BgAlpha.
+ // FIXME: Work on support for per-viewport transparency (#2766)
+ if (!(window_flags & ImGuiWindowFlags_NoBackground))
+ viewport_flags |= ImGuiViewportFlags_NoRendererClear;
+
+ window->Viewport->Flags = viewport_flags;
+}
+
// Called by user at the end of the main loop, after EndFrame()
// This will handle the creation/update of all OS windows via function defined in the ImGuiPlatformIO api.
void ImGui::UpdatePlatformWindows()