From 076d8fc86889b482785902628f64216533cdf849 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 10 Jun 2022 19:25:53 +0200 Subject: [PATCH] Nav: Fixed issues with nav request being transferred to another window when calling SetKeyboardFocusHere() and simultaneous changing window focus. (#4449) --- docs/CHANGELOG.txt | 2 ++ imgui.cpp | 23 +++++++++++++++++------ imgui.h | 2 +- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index e1e8737f..22152e96 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -82,6 +82,8 @@ Other Changes: - InputScalar: Automatically allow hexadecimal input when format is %X (without extra flag). - InputScalar: Automatically allow scientific input when format is float/double (without extra flag). - Nav: Fixed nav movement in a scope with only one disabled item from focusing the disabled item. (#5189) +- Nav: Fixed issues with nav request being transferred to another window when calling SetKeyboardFocusHere() + and simultaneous changing window focus. (#4449) - IsItemHovered(): added ImGuiHoveredFlags_NoNavOverride to disable the behavior where the return value is overriden by focus when gamepad/keyboard navigation is active. - InputText: Fixed pressing Tab emitting two tabs characters because of dual Keys/Chars events being diff --git a/imgui.cpp b/imgui.cpp index 19fac158..bfd624f7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7383,7 +7383,10 @@ void ImGui::SetKeyboardFocusHere(int offset) ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; IM_ASSERT(offset >= -1); // -1 is allowed but not below + g.NavWindow = window; + g.NavInitRequest = g.NavMoveSubmitted = g.NavMoveScoringItems = false; + ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY; NavMoveRequestSubmit(ImGuiDir_None, offset < 0 ? ImGuiDir_Up : ImGuiDir_Down, ImGuiNavMoveFlags_Tabbing | ImGuiNavMoveFlags_FocusApi, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable. if (offset == -1) @@ -9574,8 +9577,11 @@ void ImGui::SetFocusID(ImGuiID id, ImGuiWindow* window) // Note that window may be != g.CurrentWindow (e.g. SetFocusID call in InputTextEx for multi-line text) const ImGuiNavLayer nav_layer = window->DC.NavLayerCurrent; if (g.NavWindow != window) - g.NavInitRequest = false; - g.NavWindow = window; + { + g.NavWindow = window; + g.NavInitRequest = g.NavMoveSubmitted = g.NavMoveScoringItems = false; + NavUpdateAnyRequestFlag(); + } g.NavId = id; g.NavLayer = nav_layer; g.NavFocusScopeId = window->DC.NavFocusScopeIdCurrent; @@ -9823,7 +9829,12 @@ static void ImGui::NavProcessItem() // Update window-relative bounding box of navigated item if (g.NavId == id) { - g.NavWindow = window; // Always refresh g.NavWindow, because some operations such as FocusItem() don't have a window. + if (g.NavWindow != window) + { + g.NavWindow = window; // Always refresh g.NavWindow, because some operations such as FocusItem() don't have a window. + g.NavInitRequest = g.NavMoveSubmitted = g.NavMoveScoringItems = false; + NavUpdateAnyRequestFlag(); + } g.NavLayer = window->DC.NavLayerCurrent; g.NavFocusScopeId = window->DC.NavFocusScopeIdCurrent; g.NavIdIsAlive = true; @@ -9901,10 +9912,11 @@ void ImGui::NavMoveRequestSubmit(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavM g.NavMoveScrollFlags = scroll_flags; g.NavMoveForwardToNextFrame = false; g.NavMoveKeyMods = g.IO.KeyMods; - g.NavTabbingCounter = 0; g.NavMoveResultLocal.Clear(); g.NavMoveResultLocalVisible.Clear(); g.NavMoveResultOther.Clear(); + g.NavTabbingCounter = 0; + g.NavTabbingResultFirst.Clear(); NavUpdateAnyRequestFlag(); } @@ -9971,7 +9983,7 @@ void ImGui::NavRestoreLayer(ImGuiNavLayer layer) { ImGuiContext& g = *GImGui; if (layer == ImGuiNavLayer_Main) - g.NavWindow = NavRestoreLastChildNavWindow(g.NavWindow); + g.NavWindow = NavRestoreLastChildNavWindow(g.NavWindow); // FIXME-NAV: Should clear ongoing nav requests? ImGuiWindow* window = g.NavWindow; if (window->NavLastIds[layer] != 0) { @@ -10451,7 +10463,6 @@ void ImGui::NavUpdateCreateTabbingRequest() ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY; ImGuiDir clip_dir = (g.NavTabbingDir < 0) ? ImGuiDir_Up : ImGuiDir_Down; NavMoveRequestSubmit(ImGuiDir_None, clip_dir, ImGuiNavMoveFlags_Tabbing, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable. - g.NavTabbingResultFirst.Clear(); g.NavTabbingCounter = -1; } diff --git a/imgui.h b/imgui.h index 20b6ea9b..4a8a4865 100644 --- a/imgui.h +++ b/imgui.h @@ -65,7 +65,7 @@ Index of this file: // Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens) #define IMGUI_VERSION "1.88 WIP" -#define IMGUI_VERSION_NUM 18727 +#define IMGUI_VERSION_NUM 18728 #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) #define IMGUI_HAS_TABLE