imgui icon indicating copy to clipboard operation
imgui copied to clipboard

Docking state lost on subsequent INI loads

Open lailoken opened this issue 9 months ago • 3 comments

Version/Branch of Dear ImGui:

1.92.0 WIP

Back-ends:

win dx11 / linux sd2 opengl3

Compiler, OS:

any

Full config/build information:

Dear ImGui 1.92.0 WIP (19191)
--------------------------------
sizeof(size_t): 8, sizeof(ImDrawIdx): 4, sizeof(ImDrawVert): 20
define: __cplusplus=199711
define: IMGUI_DISABLE_OBSOLETE_FUNCTIONS
define: _WIN32
define: _WIN64
define: _MSC_VER=1940
define: _MSVC_LANG=202002
define: IMGUI_HAS_VIEWPORT
define: IMGUI_HAS_DOCK
--------------------------------
io.BackendPlatformName: imgui_impl_win32
io.BackendRendererName: imgui_impl_dx11
io.ConfigFlags: 0x0000C081
 NavEnableKeyboard
 DockingEnable
 DpiEnableScaleViewports
 DpiEnableScaleFonts
io.ConfigViewportsNoDecoration
io.ConfigDockingWithShift
io.ConfigNavCaptureKeyboard
io.ConfigInputTextCursorBlink
io.ConfigWindowsResizeFromEdges
io.ConfigMemoryCompactTimer = 60.0
io.BackendFlags: 0x00001C0E
 HasMouseCursors
 HasSetMousePos
 PlatformHasViewports
 HasMouseHoveredViewport
 RendererHasVtxOffset
 RendererHasViewports
--------------------------------
io.Fonts: 10 fonts, Flags: 0x00000000, TexSize: 1024,2048
io.DisplaySize: 1814.00,1177.00
io.DisplayFramebufferScale: 1.00,1.00
--------------------------------
style.WindowPadding: 8.00,8.00
style.WindowBorderSize: 1.00
style.FramePadding: 4.00,3.00
style.FrameRounding: 0.00
style.FrameBorderSize: 0.00
style.ItemSpacing: 8.00,4.00
style.ItemInnerSpacing: 4.00,4.00

Details:

On initial load of the ini, the persisted docking state is loaded correctly. If that same load is triggered a second time, the docked nodes become undocked. (with nothing else changing)

I've created test code which load and saved into a static in-memory string, and can't get docking to work at all at this point. Docking state loading only seems to work on application start.

Screenshots/Video:

No response

Minimal, Complete and Verifiable Example code:

        if (ImGui::Button("Store"))
        {
            savedIniConf = ImGui::SaveIniSettingsToMemory();
        }

        ImGui::SameLine();
        ImGui::BeginDisabled(savedIniConf.empty());
        if (ImGui::Button("Load"))
        {
            if (!savedIniConf.empty())
            {
                ImGui::LoadIniSettingsFromMemory(savedIniConf.c_str());
            }
        }
        ImGui::EndDisabled();

        ImGui::SameLine();
        if (ImGui::Button("Empty"))
        {
            ImGui::LoadIniSettingsFromMemory("");
        }

        ImGui::SameLine();
        if (ImGui::Button("Clear"))
        {
            ClearInMemoryWorkspace();
        }

lailoken avatar Mar 24 '25 14:03 lailoken

Thanks for the report and repro.! Docking is rather fragile to mid-frame changes, so the first thing you can do is: try to see if queuing your change to before NewFrame() makes a difference.

ocornut avatar Mar 24 '25 15:03 ocornut

Thanks, that indeed fixed the issue. It seems our previous code to load config was outside the g.WithinFrameScope. However new code which detected multi-monitor changes reloaded new configs after detection, and this detection was inside the NewFrame EndFrame group.

Doing a deferred loading when this is detected fixed docking.

lailoken avatar Mar 24 '25 16:03 lailoken

I'll temporarily reopen that, I would like to consider if it is possible to allow mid-frame loading and/or more thoroughly document that loading docking settings may have this constraint.

ocornut avatar Mar 24 '25 18:03 ocornut