ocornut / imgui

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
MIT License
57.74k stars 9.9k forks source link

Restoring layout from memory rearranges windows and sometimes crashes. #7705

Open nikitablack opened 2 weeks ago

nikitablack commented 2 weeks ago

Version/Branch of Dear ImGui:

Version 1.90.5, Branch: docking

Back-ends:

Custom

Compiler, OS:

Ubuntu 20.04

Details:

I'm trying to implement the maximize <-> restore functionality, i.e. by clicking on a button I want the selected window to cover the complete viewport, and by clicking once again return it to a previous position. Here's the full source code for this:

static bool maximized{false};

// don't show if other window is maximized
if (!maximized) {
    ImGui::Begin("C", nullptr);
    ImGui::Text("CCCCCCCCCC");
    ImGui::End();
}

ImGuiWindowFlags flags = ImGuiWindowFlags_None;

if (maximized) {
    auto* viewport = ImGui::GetMainViewport();

    ImGui::SetNextWindowPos(viewport->WorkPos);
    ImGui::SetNextWindowSize(viewport->WorkSize);
    ImGui::SetNextWindowViewport(viewport->ID);

    flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove;
}

ImGui::Begin("D", nullptr, flags);

static std::vector<char> settings{};

if (ImGui::Button(!maximized ? "Maximize" : "Restore")) {
    if (!maximized) {
        size_t size{};
        auto s = ImGui::SaveIniSettingsToMemory(&size);
        settings.resize(size);

        memcpy(settings.data(), s, size);
    } else if (!settings.empty()) {
        ImGui::LoadIniSettingsFromMemory(settings.data());
        settings.clear();
    }
    maximized = !maximized;
}

ImGui::End();

The first problem with this is that the order of windows is not preserved if the windows are tabbed. I.e. before the maximizing the tabs are in CD order and after restoring it's DC. The second problem is that with certain actions the application SOMETIMES crashes. I saw multiple different asserts, but one that is reproducible is the following:

  1. Dock a window to the right of another window.
  2. Maximize.
  3. Restore.
  4. Dock a window over the another window.
  5. Maximize
  6. Restore -> Crash.

output

ocornut commented 2 weeks ago

Can you try moving the LoadIniSettingsFromMemory() call to before NewFrame() ?

nikitablack commented 2 weeks ago

Unfortunately, it's the same. Only IM_ASSERT fires now from another place.