ocornut / imgui

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

Assertion failing when clicking on dockspace #4454

Open WerWolv opened 3 years ago

WerWolv commented 3 years ago

Version/Branch of Dear ImGui:

Version: 1.84.1 Branch: docking

Back-end/Renderer/Compiler/OS

Back-ends: imgui_impl_glfw.cpp + imgui_impl_opengl3.cpp Compiler: mingw gcc Operating System: Windows

My Issue/Question:

I have window that consists of a title bar, a footer and a bit dockspace. With the latest update, clicking anywhere on the dockspace (or on any element that's drawn on top of it) the following assertion is thrown:

Assertion failed: g.WindowsFocusOrder[cur_order] == window, file imgui.cpp, line 6987

Removing the assertion doesn't seem to break anything but it's probably not a good idea.

Screenshots/Video

Standalone, minimal, complete and verifiable example:

https://github.com/WerWolv/ImHex/blob/master/source/window/window.cpp#L354-L440

ocornut commented 3 years ago

Hello @WerWolv

I don't think we've got enough details for an easy repro here. In Demo>Examples>Dockspace we do something similar and it doesn't assert.

What are the values for window, window->FocusOrder and the contents of g.WindowsFocusOrder[] when asserting?

As you can see in the code there are only 2 spots manipulating those values,

So debugging the issue shouldn't be too difficult.

(I'm not able to easily build ImHex otherwise I might it a look.)

WerWolv commented 3 years ago

Hi, sorry I didn't really know what information have would been useful.

When the assertion happens, window is pointing to a valid ImGuiWindow object with the Name "DockSpace/DockSpace_B835EE5E/Welcome Screen_F5901CB1", its FocusOrder is 0 and g.WindowsFocusOrder has three entries with the names: Debug##Default, ##MainMenuBar and DockSpace.

I assume it has to do something with my a little unorthodox way of drawing elements directly onto the dockspace for the Welcome screen since window is pointing to a child inside the dockspace window and the WindowsFocusOrder is pointing to the actual DockSpace. To draw stuff onto the DockSpace I "open" the window the dockspace creates manually by replicating the name it generates internally and then add elements to that. I don't know if there's a better way to do that: https://github.com/WerWolv/ImHex/blob/master/source/window/window.cpp#L437-L438

ocornut commented 3 years ago

To draw stuff onto the DockSpace I "open" the window the dockspace creates manually

That's fine. Appending is generally supported.

But I think I may understand what's happening: The only issue is if you were doing that Begin() on a frame where the Dockspace() wasn't previously submitted. Then it won't be an append and it would override the settings of that window (e.g not be a child window again, and that marking has an effect in the FocusOrder[] thing). On frame where if (ImGui::Begin("DockSpace", nullptr, windowFlags)) { return false you could do your Begin-to-append for the welcome screen. Can you try that?

(Even if it fixes it I'm going to see if we can somehow improve the way this is reported, instead of an obscure error somewhere else.)

WerWolv commented 3 years ago

Moving the welcome screen drawing from the if to the else block indeed fixes the assertion from being thrown. However it also causes it to not render at all anymore. Is that what you meant of did I misunderstand?

ocornut commented 3 years ago

I meant only render it IF the dockspace was submitted. You have frames where the dockspace won’t be submitted.

WerWolv commented 3 years ago

I think that's what I'm doing already. Here's some very minimal pseudo code showing the procedure

if (ImGui::Begin("DockSpace")) {
    ImGui::Dockspace(ImGui::GetID("MainDock"));

    drawMenubar();
    drawWelcomeScreen(); // Open the window created by ImGui::Dockspace again and draw to it
}
ImGui::End();
WerWolv commented 3 years ago

Or do you mean I should check if the window ImGui::Dockspace creates was submitted? I just saw that you unconditionally draw everything inside the window there: bild

ocornut commented 3 years ago

Oh no you are doing the right thing.

Would need to step in debugger or use metrics to understand why your welcome screen is not rendering.

WerWolv commented 3 years ago

Doing it like this does render the welcome screen but causes the assertion to fail.

However, I might have found a way to circumvent the whole issue by creating the Dockspace after drawing the welcome screen. That way I don't have to open the window Dockspace created

ocornut commented 3 years ago

I still believe the drawWelcomeScreen() inside the Begin() block should work well and is worth investigating why your stuff doesn’t render (Metrics window will help).

As for the initial version I am going to create a minimum repro on my side in order to find how it can either behave better either provide a more explicit assert.

WerWolv commented 3 years ago

I'll try to find something with the Metrics, thanks a lot for your help :)