ocornut / imgui

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

Double-click window collapsing doesn't correctly test for other active widgets e.g. `InvisibleButton(..., ImGuiButtonFlags_MouseButtonRight)` #7841

Open achabense opened 1 month ago

achabense commented 1 month ago

Version/Branch of Dear ImGui:

Version 1.90.9

Back-ends:

imgui_impl_sdl2.cpp + imgui_impl_sdlrenderer2.cpp

Compiler, OS:

Windows 10 + MSVC 2022

Full config/build information:

No response

Details:

For InvisibleButton(..., ImGuiButtonFlags_MouseButtonRight), when the button is right-clicked and held, users can still collapse the windows by (left) double-clicking the title bars. I think this behavior is a bit surprising.

Screenshots/Video:

effect

Minimal, Complete and Verifiable Example code:

If the invisible button is right-clicked, interactions with other widgets are disabled as expected, but A or B window will still be collapsed when their title bars are (left) double-clicked.

void issue() {
    static bool a = true, b = true;

    if (a) {
        if (ImGui::Begin("A", &a)) {
            ImGui::InvisibleButton("Invisible", {100, 100}, ImGuiButtonFlags_MouseButtonRight);
            ImGui::GetWindowDrawList()->AddRectFilled(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32_WHITE);
        }
        ImGui::End();
    }

    if (b) {
        if (ImGui::Begin("B", &b)) {
            ImGui::Button("B", {100, 100});
        }
        ImGui::End();
    }
}
ocornut commented 1 month ago

Hello, Thanks for reporting. This seems to be a bug related to the fact that specifically the "double click on title bar empty space" behavior is not consistent with practically any other behavior in the code.

Code does:

// We don't use a regular button+id to test for double-click on title bar (mostly due to legacy reason, could be fixed), so verify that we don't have items over the title bar.
ImRect title_bar_rect = window->TitleBarRect();
if (g.HoveredWindow == window && g.HoveredId == 0 && g.HoveredIdPreviousFrame == 0 && IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max))
    if (g.IO.MouseClickedCount[0] == 2 && GetKeyOwner(ImGuiKey_MouseLeft) == ImGuiKeyOwner_NoOwner)
        window->WantCollapseToggle = true;

I'm not even sure why the code doesn't simply add a if (g.ActiveId == 0) code, seems like it would fix it, and we could remove the GetKeyOwner() test as well. Will investigate at some point.