Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows undocks when DockSpace() is not submitted (e.g. host collapsed) #2599

Closed
BeachCoder76 opened this issue May 31, 2019 · 5 comments
Closed
Labels

Comments

@BeachCoder76
Copy link

Version/Branch of Dear ImGui:

Version: v1.70 WIP
Branch: Docking branch

Back-end/Renderer/Compiler/OS

Back-ends: custom
Compiler: Dev Studio 2019
Operating System: Win10

My Issue/Question:

What I want to achieve creating a master window which has a Dockspace built into it. Then, automatically docking other windows at creation time into that DockSpace. Then, the user can decide to undock or dock back anywhere in the viewport.

Issue I'm having is that upon collapsing the master window, all docked windows undock automatically.

I would have assumed that all windows would disappear since the top window is collapsed.

Screenshots/Video

imguidockspaceissue

Standalone, minimal, complete and verifiable example:

    static ImGuiID dockspaceID = 0;
    if (ImGui::Begin("Master Window"/*, nullptr, ImGuiWindowFlags_MenuBar*/))
    {
        ImGui::TextUnformatted("DockSpace below");

        // Declare Central dockspace
        dockspaceID = ImGui::GetID("HUB_DockSpace");
        ImGui::DockSpace(dockspaceID , ImVec2(0.0f, 0.0f), ImGuiDockNodeFlags_None|ImGuiDockNodeFlags_PassthruCentralNode/*|ImGuiDockNodeFlags_NoResize*/);
    }
    ImGui::End();

    ImGui::SetNextWindowDockID(dockspaceID , ImGuiCond_FirstUseEver);
    if (ImGui::Begin("Dockable Window"))
    {
        ImGui::TextUnformatted("Test");
    }
    ImGui::End();

#2109

@ocornut
Copy link
Owner

ocornut commented May 31, 2019

I would have assumed that all windows would disappear since the top window is collapsed.

As you the code shows you have stopped submitting the dockspace, if you stop submitting the dockspace it doesn't exist any more.

If we were to have those docked window hold into non-active dockspaces, it becomes impossible to decide at which point they should let go of it. It means that if you made any change to your code (e.g. moved/renamed a dockspace), those windows would stay hidden forever.

So the decision that comes naturally from that and which fits with every other decision in the ecosystem, is that windows undock themselves if their parent dockspace is not active.

The demo help marker says:

"ImGui::DockSpace() comes with one hard constraint: it needs to be submitted before any window which may be docked into it. Therefore, if you use a dock spot as the central point of your application, you'll probably want it to be part of the very first window you are submitting to imgui every frame."

What would you suggest?

@BeachCoder76
Copy link
Author

After @ocornut comment from the #2109 thread, I changed the code to always do the dockspace even though ::Begin returns false (collapsed) but the window is active and that fixed it. All docked windows are now properly hiding when my master window gets collapsed.

I'll leave this code here as a reference for others who might want to try this.

    static ImGuiID dockspaceID = 0;
    bool active = true;
    if (ImGui::Begin("Master Window", &active))
    {
        ImGui::TextUnformatted("DockSpace below");
    }
    if (active)
    {
        // Declare Central dockspace
        dockspaceID = ImGui::GetID("HUB_DockSpace");
        ImGui::DockSpace(dockspaceID , ImVec2(0.0f, 0.0f), ImGuiDockNodeFlags_None|ImGuiDockNodeFlags_PassthruCentralNode/*|ImGuiDockNodeFlags_NoResize*/);
    }
    ImGui::End();

    ImGui::SetNextWindowDockID(dockspaceID , ImGuiCond_FirstUseEver);
    if (ImGui::Begin("Dockable Window"))
    {
        ImGui::TextUnformatted("Test");
    }
    ImGui::End();

Thanks for your awesome work!

@BeachCoder76
Copy link
Author

I would have assumed that all windows would disappear since the top window is collapsed.

As you the code shows you have stopped submitting the dockspace, if you stop submitting the dockspace it doesn't exist any more.

If we were to have those docked window hold into non-active dockspaces, it becomes impossible to decide at which point they should let go of it. It means that if you made any change to your code (e.g. moved/renamed a dockspace), those windows would stay hidden forever.

So the decision that comes naturally from that and which fits with every other decision in the ecosystem, is that windows undock themselves if their parent dockspace is not active.

The demo help marker says:

"ImGui::DockSpace() comes with one hard constraint: it needs to be submitted before any window which may be docked into it. Therefore, if you use a dock spot as the central point of your application, you'll probably want it to be part of the very first window you are submitting to imgui every frame."

What would you suggest?

It definitely makes lots of sense. The biggest issue I had with this feature is that I always assumed that if a ::Begin call was returning false, I couldn't assume that CurrentWindow was set. My bad.

That and you were just too fast on this one and posted before I could submit my own solution to this! :)

On a side note, I did try to play with ImGuiDockNodeFlags_KeepAliveOnly but couldn't see the gain so I will investigate that one later.

ocornut added a commit that referenced this issue Jun 4, 2019
@ocornut ocornut changed the title Creating a DockSpace() from code within a window Windows undocks when DockSpace() is not submitted (e.g. host collapsed) May 27, 2021
@ocornut
Copy link
Owner

ocornut commented May 27, 2021

I've been going through open Docking issues:
Renamed the thread to ease discoverability, and closing this as solved now.

On a side note, I did try to play with ImGuiDockNodeFlags_KeepAliveOnly but couldn't see the gain so I will investigate that one later.

I am surprised my first answer didn't mention ImGuiDockNodeFlags_KeepAliveOnly (which you discovered). Indeed it is not super clear what the benefit is, it is mostly a (small) performance benefit.
EDIT As reminded by #2720 situations where multiple dockspace are in multiple tabs would require the use of ImGuiDockNodeFlags_KeepAliveOnly since you don't want to layout multiple dockspace in the same spot.

It also ties with this:

It definitely makes lots of sense. The biggest issue I had with this feature is that I always assumed that if a ::Begin call was returning false, I couldn't assume that CurrentWindow was set. My bad.

I'm trying to steer dear imgui toward "fixing" the inconsistent Begin/End API and that change would change the assumption above. Among the problems this Begin/End API change would lead to, the submission of dockspace in a collapsed window would be problematic. I haven't decided between having a Begin()-end flags to ensure "always get in the window" (which will be required for very few edge cases, including this one) or having an equivalent of the _KeepAlive that which can be "actioned" from outside the window. Aside from one minor remaining change, calling DockSpace() with the _KeepAlive could technically be done WITHOUT submitting the host window.

@Julianiolo
Copy link

Julianiolo commented Jun 27, 2021

@ocornut I'm having some issues with the soultion @BeachCoder76 suggested when I use it together with a modal popup

When I open a popup when the Master Window gets closed it brings the Master Window in focus above the modal popup. The window cant be moved though and the popup cant be accesed through it.
I was able to fix this by adding the commented out ImGui::SetNextWindowFocus(); before the popup

For this to occur the Master Window has to be docked to another window as a tab and be a not selected tab like so:
image

When I then close the Master Window it appears before the popup like so:
image
EDIT: I've realized that the popup in the window is very hard to see, and I can't make a new screenshot at the moment. It is there though, behind the Main Window you just have to look real closely.

Version 1.84 WIP
Branch: Docking

code:

ImGui::Begin("Window");
ImGui::End();

static ImGuiID dockspaceID = 0;
static bool winOpenWish = true;
if (ImGui::Begin("Master Window", &winOpenWish))
{
	ImGui::TextUnformatted("DockSpace below");
}
	// Declare Central dockspace
	dockspaceID = ImGui::GetID("HUB_DockSpace");
	ImGui::DockSpace(dockspaceID , ImVec2(0.0f, 0.0f), ImGuiDockNodeFlags_None|ImGuiDockNodeFlags_PassthruCentralNode/*|ImGuiDockNodeFlags_NoResize*/);

ImGui::End();

if (!winOpenWish) 
{
	ImGui::OpenPopup("Popup");
}

//ImGui::SetNextWindowFocus();
if (ImGui::BeginPopupModal("Popup")) 
{
	ImGui::TextUnformatted("a popup");
	ImGui::EndPopup();
}

ImGui::SetNextWindowDockID(dockspaceID , ImGuiCond_FirstUseEver);
if (ImGui::Begin("Dockable Window"))
{
	ImGui::TextUnformatted("Test");
}
ImGui::End();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants