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

IsItemHovered will overlapping items doesn't reflect visible state of item #8411

Open
ocornut opened this issue Feb 18, 2025 · 1 comment
Open
Labels

Comments

@ocornut
Copy link
Owner

ocornut commented Feb 18, 2025

Version/Branch of Dear ImGui:

Version 1.91.8 master

Back-ends:

n/a

Compiler, OS:

n/a

Full config/build information:

Linking to e.g. #6610 for this is a different issue.

Details:

My Issue/Question:

XXX (please provide as much context as possible)

Screenshots/Video:

Image

Minimal, Complete and Verifiable Example code:

{

    static bool overlap = false;
    ImGui::Checkbox("Allow Overlap", &overlap);

    const ImVec2 pos = ImGui::GetCursorScreenPos();
    const float offset = 100.0f;
    const ImVec2 but_size(50, 30);

    ImGui::SetCursorScreenPos(ImVec2(pos.x + offset, pos.y));
    if (overlap)
        ImGui::SetNextItemAllowOverlap();
    ImGui::Button("AAAA", but_size);

    const bool aaa_hovered = ImGui::IsItemHovered();
    const bool aaa_active = ImGui::IsItemActive();
    const bool aaa_focused = ImGui::IsItemFocused();

    ImGui::SetCursorScreenPos(ImVec2(pos.x + offset + but_size.x * 0.5f, pos.y + but_size.y * 0.5f));
    ImGui::Button("BBBB", but_size);
    const bool bbb_hovered = ImGui::IsItemHovered();
    const bool bbb_active = ImGui::IsItemActive();
    const bool bbb_focused = ImGui::IsItemFocused();

    ImGui::SetCursorScreenPos(ImVec2(pos.x + offset, pos.y + but_size.y * 2));
    ImGui::Text("AAAA = %s - %s - %s",
        aaa_hovered ? "HOVERED" : "not hovered",
        aaa_active ? "ACTIVE" : "not active",
        aaa_focused ? "FOCUSED" : "not focused"
    );

    ImGui::SetCursorScreenPos(ImVec2(pos.x + offset, pos.y + but_size.y * 3));
    ImGui::Text("BBBB = %s - %s - %s",
        bbb_hovered ? "HOVERED" : "not hovered",
        bbb_active ? "ACTIVE" : "not active",
        bbb_focused ? "FOCUSED" : "not focused"
    );
}
@ocornut
Copy link
Owner Author

ocornut commented Feb 18, 2025

Note for future myself:
The "naive" change would be to change the code in IsItemHovered() to:

// Test if using AllowOverlap and overlapped
if ((flags & ImGuiHoveredFlags_AllowWhenOverlappedByItem) == 0 && id != 0)
{
    if (g.LastItemData.ItemFlags & ImGuiItemFlags_AllowOverlap)
    {
        if (g.HoveredIdPreviousFrame != g.LastItemData.ID)
            return false;
    }
++    else
++    {
++        if (g.HoveredId != g.LastItemData.ID && g.HoveredId != 0 && !g.HoveredIdAllowOverlap)
++            return false;
++    }
}

Which breaks the following tests:

  • window_title_context_menu
  • widgets_hover
  • widgets_overlap_3_timing
  • widgets_selectable_span_all_columns
  • widgets_selectable_span_all_table

widgets_overlap_3_timing had a IMGUI_BROKEN_TESTS block, new behavior seems better.

Both widgets_selectable_span_all_columns and widgets_selectable_span_all_table were actually incorrect and this revealed it.

But:

widgets_hover
Fails trying to call IsItemHovered() after EndChild().

window_title_context_menu
Highlight a non trivial issue: with this change BeginPopupContextItem() doesn't work when hovering the Close Button, because the function calls IsItemHovered(). In this case the submission order is: CloseButton(), then TitleBar but via SetLastItemDataForWindow() without a call to ItemHoverable().

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

1 participant