From d4f136b68c7088970102130814ee3b5b01858bc7 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 29 Sep 2022 19:25:26 +0200 Subject: [PATCH] Menus, Nav: Fixed using left/right navigation when appending to an existing menu (multiple BeginMenu() call with same names). (#1207) --- docs/CHANGELOG.txt | 2 ++ imgui.cpp | 3 ++- imgui.h | 2 +- imgui_internal.h | 1 + imgui_widgets.cpp | 14 ++++++++------ 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index b1a28251a64d..a1288591252b 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -137,6 +137,8 @@ Other Changes: the gap between a menu item inside a window and a child-menu in a secondary viewport. (#5614) - Menus, Nav: Fixed keyboard/gamepad navigation occasionally erroneously landing on menu-item in parent when the parent is not a popup. (#5730) +- Menus, Nav: Fixed using left/right navigation when appending to an existing menu (multiple + BeginMenu() call with same names). (#1207) - Nav: Fixed moving/resizing window with gamepad or keyboard when running at very high framerate. - Nav: Pressing Space/GamepadFaceDown on a repeating button uses the same repeating rate as a mouse hold. - Nav: Fixed an issue opening a menu with Right key from a non-menu window. diff --git a/imgui.cpp b/imgui.cpp index 69569a91484b..5af4b2d99d51 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4608,9 +4608,10 @@ void ImGui::NewFrame() { ImGuiWindow* window = g.Windows[i]; window->WasActive = window->Active; - window->BeginCount = 0; window->Active = false; window->WriteAccessed = false; + window->BeginCountPreviousFrame = window->BeginCount; + window->BeginCount = 0; // Garbage collect transient buffers of recently unused windows if (!window->WasActive && !window->MemoryCompacted && window->LastTimeActive < memory_compact_start_time) diff --git a/imgui.h b/imgui.h index 27e97e64846b..33270458563b 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 18826 +#define IMGUI_VERSION_NUM 18827 #define IMGUI_HAS_TABLE /* diff --git a/imgui_internal.h b/imgui_internal.h index bae32248bd84..d564598dd9e7 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -2112,6 +2112,7 @@ struct IMGUI_API ImGuiWindow bool HasCloseButton; // Set when the window has a close button (p_open != NULL) signed char ResizeBorderHeld; // Current border being held for resize (-1: none, otherwise 0-3) short BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs) + short BeginCountPreviousFrame; // Number of Begin() during the previous frame short BeginOrderWithinParent; // Begin() order within immediate parent window, if we are a child window. Otherwise 0. short BeginOrderWithinContext; // Begin() order within entire imgui context. This is mostly used for debugging submission order related issues. short FocusOrder; // Order within WindowsFocusOrder[], altered when windows are focused. diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 1c19eca1b58a..cadad5bc91e7 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -7183,13 +7183,15 @@ void ImGui::EndMenu() // FIXME: This doesn't work if the parent BeginMenu() is not on a menu. ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - if (g.NavMoveDir == ImGuiDir_Left && NavMoveRequestButNoResultYet() && window->DC.LayoutType == ImGuiLayoutType_Vertical) - if (g.NavWindow && (g.NavWindow->RootWindowForNav->Flags & ImGuiWindowFlags_Popup) && g.NavWindow->RootWindowForNav->ParentWindow == window) - { - ClosePopupToLevel(g.BeginPopupStack.Size, true); - NavMoveRequestCancel(); - } + IM_ASSERT(window->Flags & ImGuiWindowFlags_Popup); // Mismatched BeginMenu()/EndMenu() calls + if (window->BeginCount == window->BeginCountPreviousFrame) + if (g.NavMoveDir == ImGuiDir_Left && NavMoveRequestButNoResultYet() && window->DC.LayoutType == ImGuiLayoutType_Vertical) + if (g.NavWindow && (g.NavWindow->RootWindowForNav->Flags & ImGuiWindowFlags_Popup) && g.NavWindow->RootWindowForNav->ParentWindow == window) + { + ClosePopupToLevel(g.BeginPopupStack.Size, true); + NavMoveRequestCancel(); + } EndPopup(); }