From a26fcf58cc2d0cfeee8b98ad8517af998f75c27e Mon Sep 17 00:00:00 2001 From: ocornut Date: Sun, 30 Mar 2025 16:40:36 +0200 Subject: [PATCH] Nav: fixed assertion when holding gamepad FaceLeft/West button + pressing a keyboard key. (#8525) --- docs/CHANGELOG.txt | 2 ++ imgui.cpp | 19 +++++++++++-------- imgui_internal.h | 1 + 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 4a691a20a..b333f109e 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -52,6 +52,8 @@ Other changes: codepath that preserve last contents size when collapsed, resulting in programmatically uncollapsing auto-sizing windows having them flicker size for a frame. (#7691) [@achabense] +- Nav: fixed assertion when holding gamepad FaceLeft/West button to open + CTRL+Tab windowing + pressing a keyboard key. (#8525) - Error Handling: added better error report and recovery for extraneous EndPopup() call. (#1651, #8499) - Style, InputText: added ImGuiCol_InputTextCursor to configure color of diff --git a/imgui.cpp b/imgui.cpp index 53537baa0..b9088378a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4020,6 +4020,7 @@ ImGuiContext::ImGuiContext(ImFontAtlas* shared_font_atlas) ConfigNavWindowingKeyNext = IO.ConfigMacOSXBehaviors ? (ImGuiMod_Super | ImGuiKey_Tab) : (ImGuiMod_Ctrl | ImGuiKey_Tab); ConfigNavWindowingKeyPrev = IO.ConfigMacOSXBehaviors ? (ImGuiMod_Super | ImGuiMod_Shift | ImGuiKey_Tab) : (ImGuiMod_Ctrl | ImGuiMod_Shift | ImGuiKey_Tab); NavWindowingTarget = NavWindowingTargetAnim = NavWindowingListWindow = NULL; + NavWindowingInputSource = ImGuiInputSource_None; NavWindowingTimer = NavWindowingHighlightAlpha = 0.0f; NavWindowingToggleLayer = false; NavWindowingToggleKey = ImGuiKey_None; @@ -13786,11 +13787,12 @@ static void ImGui::NavUpdateWindowing() if (start_windowing_with_gamepad || start_windowing_with_keyboard) if (ImGuiWindow* window = g.NavWindow ? g.NavWindow : FindWindowNavFocusable(g.WindowsFocusOrder.Size - 1, -INT_MAX, -1)) { - g.NavWindowingTarget = g.NavWindowingTargetAnim = window->RootWindow; // Current location + if (start_windowing_with_keyboard || g.ConfigNavWindowingWithGamepad) + g.NavWindowingTarget = g.NavWindowingTargetAnim = window->RootWindow; // Current location g.NavWindowingTimer = g.NavWindowingHighlightAlpha = 0.0f; g.NavWindowingAccumDeltaPos = g.NavWindowingAccumDeltaSize = ImVec2(0.0f, 0.0f); g.NavWindowingToggleLayer = start_windowing_with_gamepad ? true : false; // Gamepad starts toggling layer - g.NavInputSource = start_windowing_with_keyboard ? ImGuiInputSource_Keyboard : ImGuiInputSource_Gamepad; + g.NavWindowingInputSource = g.NavInputSource = start_windowing_with_keyboard ? ImGuiInputSource_Keyboard : ImGuiInputSource_Gamepad; if (g.NavWindow == NULL) just_started_windowing_from_null_focus = true; @@ -13800,9 +13802,9 @@ static void ImGui::NavUpdateWindowing() } // Gamepad update - if (g.NavWindowingTarget && g.NavInputSource == ImGuiInputSource_Gamepad) + if ((g.NavWindowingTarget || g.NavWindowingToggleLayer) && g.NavWindowingInputSource == ImGuiInputSource_Gamepad) { - if (g.ConfigNavWindowingWithGamepad) + if (g.NavWindowingTarget != NULL) { // Highlight only appears after a brief time holding the button, so that a fast tap on ImGuiKey_NavGamepadMenu (to toggle NavLayer) doesn't add visual noise // However inputs are accepted immediately, so you press ImGuiKey_NavGamepadMenu + L1/R1 fast. @@ -13824,14 +13826,15 @@ static void ImGui::NavUpdateWindowing() g.NavWindowingToggleLayer &= (g.NavWindowingHighlightAlpha < 1.0f); // Once button was held long enough we don't consider it a tap-to-toggle-layer press anymore. if (g.NavWindowingToggleLayer && g.NavWindow) apply_toggle_layer = true; - else if (!g.NavWindowingToggleLayer && g.ConfigNavWindowingWithGamepad) + else if (!g.NavWindowingToggleLayer) apply_focus_window = g.NavWindowingTarget; g.NavWindowingTarget = NULL; + g.NavWindowingToggleLayer = false; } } // Keyboard: Focus - if (g.NavWindowingTarget && g.NavInputSource == ImGuiInputSource_Keyboard) + if (g.NavWindowingTarget && g.NavWindowingInputSource == ImGuiInputSource_Keyboard) { // Visuals only appears after a brief time after pressing TAB the first time, so that a fast CTRL+TAB doesn't add visual noise ImGuiKeyChord shared_mods = ((g.ConfigNavWindowingKeyNext ? g.ConfigNavWindowingKeyNext : ImGuiMod_Mask_) & (g.ConfigNavWindowingKeyPrev ? g.ConfigNavWindowingKeyPrev : ImGuiMod_Mask_)) & ImGuiMod_Mask_; @@ -13854,10 +13857,10 @@ static void ImGui::NavUpdateWindowing() windowing_toggle_layer_start = true; g.NavWindowingToggleLayer = true; g.NavWindowingToggleKey = windowing_toggle_key; - g.NavInputSource = ImGuiInputSource_Keyboard; + g.NavWindowingInputSource = g.NavInputSource = ImGuiInputSource_Keyboard; break; } - if (g.NavWindowingToggleLayer && g.NavInputSource == ImGuiInputSource_Keyboard) + if (g.NavWindowingToggleLayer && g.NavWindowingInputSource == ImGuiInputSource_Keyboard) { // We cancel toggling nav layer when any text has been typed (generally while holding Alt). (See #370) // We cancel toggling nav layer when other modifiers are pressed. (See #4439) diff --git a/imgui_internal.h b/imgui_internal.h index ec9c6047c..ff1a8d8ac 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -2248,6 +2248,7 @@ struct ImGuiContext ImGuiWindow* NavWindowingListWindow; // Internal window actually listing the CTRL+Tab contents float NavWindowingTimer; float NavWindowingHighlightAlpha; + ImGuiInputSource NavWindowingInputSource; bool NavWindowingToggleLayer; ImGuiKey NavWindowingToggleKey; ImVec2 NavWindowingAccumDeltaPos;