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.
This commit is contained in:
ocornut 2023-06-23 15:40:54 +02:00
parent 7d81a166f9
commit 66c09fc05b
3 changed files with 12 additions and 0 deletions

View File

@ -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

View File

@ -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 : "<NULL>");
// 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)

View File

@ -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;