From 66c09fc05b93c41be1f55d6dd610b2b3cabf39db Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 23 Jun 2023 15:40:54 +0200 Subject: [PATCH] Docking+Viewports: Fixed extraneous viewport+platform-window recreation. Part 1. Part 1: Add counters. Amend logs. Refer to "viewport_owner_change_1" and "viewport_owner_change_2" in ImGuiTestSuite. --- docs/CHANGELOG.txt | 5 +++++ imgui.cpp | 4 ++++ imgui_internal.h | 3 +++ 3 files changed, 12 insertions(+) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 7907226b9..4228d118c 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -151,6 +151,11 @@ Other changes: Docking+Viewports Branch: +- Viewports+Docking: Fixed extraneous viewport+platform-window recreation in various + combination of showing or hiding windows, docking with/without split, undocking. + While with some backends and without OS decorations, some extraneous window recreation + were visibly not noticeable, they would typically become noticeable when enabling + OS decorations on those windows (e.g. Windows title bar fade-in/animation). - Viewports: Closing a viewport via OS/platform means (e.g. OS close button or task-bar menu), mark all windows in this viewport as closed. - Docking: Fixed one-frame flickering on reappearing windows binding to a dock node diff --git a/imgui.cpp b/imgui.cpp index 8763aa528..e5fcaa9dc 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3631,6 +3631,7 @@ void ImGui::Initialize() viewport->Flags = ImGuiViewportFlags_OwnedByApp; g.Viewports.push_back(viewport); g.TempBuffer.resize(1024 * 3 + 1, 0); + g.ViewportCreatedCount++; g.PlatformIO.Viewports.push_back(g.Viewports[0]); #ifdef IMGUI_HAS_DOCK @@ -14373,6 +14374,7 @@ ImGuiViewportP* ImGui::AddUpdateViewport(ImGuiWindow* window, ImGuiID id, const viewport->Flags = flags; UpdateViewportPlatformMonitor(viewport); g.Viewports.push_back(viewport); + g.ViewportCreatedCount++; IMGUI_DEBUG_LOG_VIEWPORT("[viewport] Add Viewport %08X '%s'\n", id, window ? window->Name : ""); // We normally setup for all viewports in NewFrame() but here need to handle the mid-frame creation of a new viewport. @@ -14685,6 +14687,7 @@ void ImGui::UpdatePlatformWindows() g.PlatformIO.Platform_CreateWindow(viewport); if (g.PlatformIO.Renderer_CreateWindow != NULL) g.PlatformIO.Renderer_CreateWindow(viewport); + g.PlatformWindowsCreatedCount++; viewport->LastNameHash = 0; viewport->LastPlatformPos = viewport->LastPlatformSize = ImVec2(FLT_MAX, FLT_MAX); // By clearing those we'll enforce a call to Platform_SetWindowPos/Size below, before Platform_ShowWindow (FIXME: Is that necessary?) viewport->LastRendererSize = viewport->Size; // We don't need to call Renderer_SetWindowSize() as it is expected Renderer_CreateWindow() already did it. @@ -16254,6 +16257,7 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node) FocusWindow(single_window); if (node->HostWindow) { + IMGUI_DEBUG_LOG_VIEWPORT("[viewport] Node %08X transfer Viewport %08X->%08X to Window '%s'\n", node->ID, node->HostWindow->Viewport->ID, single_window->ID, single_window->Name); single_window->Viewport = node->HostWindow->Viewport; single_window->ViewportId = node->HostWindow->ViewportId; if (node->HostWindow->ViewportOwned) diff --git a/imgui_internal.h b/imgui_internal.h index 7cd4201d3..85fabcf29 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -2058,6 +2058,8 @@ struct ImGuiContext ImGuiViewportP* MouseLastHoveredViewport; // Last known viewport that was hovered by mouse (even if we are not hovering any viewport any more) + honoring the _NoInputs flag. ImGuiID PlatformLastFocusedViewportId; ImGuiPlatformMonitor FallbackMonitor; // Virtual monitor used as fallback if backend doesn't provide monitor information. + int ViewportCreatedCount; // Unique sequential creation counter (mostly for testing/debugging) + int PlatformWindowsCreatedCount; // Unique sequential creation counter (mostly for testing/debugging) int ViewportFocusedStampCount; // Every time the front-most window changes, we stamp its viewport with an incrementing counter // Gamepad/keyboard Navigation @@ -2327,6 +2329,7 @@ struct ImGuiContext CurrentViewport = NULL; MouseViewport = MouseLastHoveredViewport = NULL; PlatformLastFocusedViewportId = 0; + ViewportCreatedCount = PlatformWindowsCreatedCount = 0; ViewportFocusedStampCount = 0; NavWindow = NULL;