From 81176737f83a7e21cda5022c758e7c36fbdd0d1e Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 14 Oct 2022 17:39:04 +0200 Subject: [PATCH] Menus: Fixed using IsItemHovered()/IsItemClicked() on BeginMenu(). (#5775) --- docs/CHANGELOG.txt | 1 + imgui.cpp | 2 +- imgui.h | 2 +- imgui_widgets.cpp | 10 +++++++++- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 460d7747f..fdb8d646c 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -144,6 +144,7 @@ Other Changes: towards a sub-menu. (#2517, #5614). [@rokups] - Menus: Fixed gaps in closing logic which would make child-menu erroneously close when crossing the gap between a menu item inside a window and a child-menu in a secondary viewport. (#5614) +- Menus: Fixed using IsItemHovered()/IsItemClicked() on BeginMenu(). (#5775) - Menus, Nav: Fixed keyboard/gamepad navigation occasionally erroneously landing on menu-item in parent window when the parent is not a popup. (#5730) - Menus, Nav: Fixed not being able to close a menu with Left arrow when parent is not a popup. (#5730) diff --git a/imgui.cpp b/imgui.cpp index d2c96e90e..21d017b47 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3640,7 +3640,7 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags) // Test if interactions on this window are blocked by an active popup or modal. // The ImGuiHoveredFlags_AllowWhenBlockedByPopup flag will be tested here. - if (!IsWindowContentHoverable(window, flags)) + if (!IsWindowContentHoverable(window, flags) && !(g.LastItemData.InFlags & ImGuiItemFlags_NoWindowHoverableCheck)) return false; // Test if the item is disabled diff --git a/imgui.h b/imgui.h index 5d8b7c52b..de8deff8d 100644 --- a/imgui.h +++ b/imgui.h @@ -23,7 +23,7 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM > 12345') #define IMGUI_VERSION "1.89 WIP" -#define IMGUI_VERSION_NUM 18831 +#define IMGUI_VERSION_NUM 18832 #define IMGUI_HAS_TABLE /* diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index f72ea4ced..cf5eebb06 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -7125,11 +7125,19 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled) if (menu_is_open) { - // FIXME: This technically breaks functions relying on LastItemData, somehow nobody complained yet. Should backup/restore LastItemData. + ImGuiLastItemData last_item_in_parent = g.LastItemData; SetNextWindowPos(popup_pos, ImGuiCond_Always); // Note: misleading: the value will serve as reference for FindBestWindowPosForPopup(), not actual pos. PushStyleVar(ImGuiStyleVar_ChildRounding, style.PopupRounding); // First level will use _PopupRounding, subsequent will use _ChildRounding menu_is_open = BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display) PopStyleVar(); + if (menu_is_open) + { + // Restore LastItemData so IsItemXXXX functions can work after BeginMenu()/EndMenu() + // (This fixes using IsItemClicked() and IsItemHovered(), but IsItemHovered() also relies on its support for ImGuiItemFlags_NoWindowHoverableCheck) + g.LastItemData = last_item_in_parent; + if (g.HoveredWindow == window) + g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredWindow; + } } else {