ocornut / imgui

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

Docked Windows with _NoInput flag #4795

Open Bizzarrus opened 2 years ago

Bizzarrus commented 2 years ago

Version/Branch of Dear ImGui:

Version: 1.83 WIP (18204) Branch: docking

Back-end/Renderer/Compiler/OS

Back-ends: custom backend Compiler: MSVC (Visual Studio 2019) Operating System: Windows 10

My Issue/Question:

In the program I'm working on, we have a series of windows (effectively displaying various performance stats and similar), all sharing the same code skeleton. In order for QA to test the program in a comfortable manner, there's a toggle (a checkbox in this particular case), which makes all those windows see-through and click-through (toggling the NoBackground and NoInputs window flags). The idea is that they position these windows suitable for their setup, and then use the toggle in order to test the program while being able to see the stats.

This all works fine as long as none of the windows are docked anywhere. However, once they are docked (that is to say: They were docked somewhere, and then the toggle was turned on), their background becomes visible again, and they also can't be clicked through anymore (though they still can't actually be interacted with, except for resizing the window).

Is there something that can be done about this? I get that merging flags is difficult if windows with different flags are docked together - however, if all docked windows have the same flag, or if the windows are just docked next to each other or to the viewport covering (PassthruCentralNode) DockSpace, I would expect these flags to have at least some effect (other than making the UI unresponsive because of the NoInputs flag).

Also, on a side note, I noticed that, if you have a window with the NoInputs flag, and that window contains a tab bar which contains a child window, the content of said child window still receives input unless I explicitly set the NoInputs flag to it as well (see second code sample). That's easy enough to work around tho, so I didn't feel like it needs it's own issue, which is why I just mention it here. I also didn't test it very much, so I'm not sure if the tab bar is relevant to it, or if that's just the behaviour of any child window (Therefore also sorry if this is actually the intended behaviour - just seems unintuitive to me that something inside a "NoInput" window can receive input at all)

Standalone, minimal, complete and verifiable example:

Click-Through toggle code:

static bool clickthrough = false;
ImGui::Checkbox("Click Through", &clickthrough);

auto flags = clickthrough ? ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoInputs : ImGuiWindowFlags_None;

// Windows will be click-through (when the checkbox is active) only if they aren't docked to anything, not even to one another
if(ImGui::Begin("Window A", nullptr, flags))
    ImGui::Button("Test Button A");
ImGui::End();

if(ImGui::Begin("Window B", nullptr, flags))
    ImGui::Button("Test Button B");
ImGui::End();

NoInput flag not being inherited:

if(ImGui::Begin("Window", nullptr, ImGuiWindowFlags_NoInputs))
{
    if(ImGui::BeginTabBar("##Tabs"))
    {
        if(ImGui::BeginTabItem("Test Tab"))
        {
            // "Test Button" still receives input if BeginChild doesn't also explicitly get NoInputs flag
            if(ImGui::BeginChild("##ScrollChild", ImVec2(0,0), false, ImGuiWindowFlags_NoInputs)) 
            {
                // Note that, technically, in my case there's also a BeginTable around the button, but I don't think that's related
                ImGui::Button("Test Button");
            } 

            ImGui::EndChild();
            ImGui::EndTabItem();
        }

        ImGui::EndTabBar();
    }
}

ImGui::End();
ocornut commented 2 years ago

The effect of the _NoBackground flag now works since December 2 (namely b16f738 and some other commits, see #2522)

It's difficult to handle the _NoInput flag as passthrough here because of how the hovering system work, however I suspect that if you create a root window with _NoInput and then a Dockspace inside it should work.

Bizzarrus commented 2 years ago

Alright, I'll update our ImGui version to get that _NoBackground flag fix, thanks :)

Our Dockspace is actually already inside a root window with the _NoInput flag (and a bunch of other flags), so that doesn't seem to fix it :( (Though, to be honest, our code around creating the dockspace is a bit wanky, and I can't change that without breaking peoples window layouts, so it can be that we just run into an edge case there)

Also, about the part that child windows (BeginChild etc) don't inherit the _NoInput flag from the window they are in: Thanks to our QA, I just learned that BeginTable internally uses BeginChild if the _ScrollX or _ScrollY table flags are set. This leads to the very unexpected side effect that the tables content ignores the _NoInput flag only if either of the _Scroll flags are set:

if(ImGui::Begin("Window", nullptr, ImGuiWindowFlags_NoInputs))
{
    if(ImGui::BeginTable("Table", 1, ImGuiTableFlags_ScrollY))
    {
        ImGui::TableNextRow();
        ImGui::Button("Test Button"); // Button still receives input only if ImGuiTableFlags_ScrollY (or _ScrollX) is set
        ImGui::EndTable();
    }
}
ImGui::End();

It's of course easy enough to work around this, but the behaviour is very unexpected, so it would be nice if that could be fixed anyways :)