mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-11-03 22:51:06 +01:00 
			
		
		
		
	Nav: Fix not clearing NavWindowingToggleLayer properly (old code left it to true, relied on Alt release only). Removed unnecessary KeyMenu_ from NavInput. (#4439, #787)
This commit is contained in:
		
							
								
								
									
										55
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										55
									
								
								imgui.cpp
									
									
									
									
									
								
							@@ -4033,6 +4033,7 @@ void ImGui::NewFrame()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Update keyboard input state
 | 
					    // Update keyboard input state
 | 
				
			||||||
    // Synchronize io.KeyMods with individual modifiers io.KeyXXX bools
 | 
					    // Synchronize io.KeyMods with individual modifiers io.KeyXXX bools
 | 
				
			||||||
 | 
					    g.IO.KeyModsPrev = g.IO.KeyMods;
 | 
				
			||||||
    g.IO.KeyMods = GetMergedKeyModFlags();
 | 
					    g.IO.KeyMods = GetMergedKeyModFlags();
 | 
				
			||||||
    memcpy(g.IO.KeysDownDurationPrev, g.IO.KeysDownDuration, sizeof(g.IO.KeysDownDuration));
 | 
					    memcpy(g.IO.KeysDownDurationPrev, g.IO.KeysDownDuration, sizeof(g.IO.KeysDownDuration));
 | 
				
			||||||
    for (int i = 0; i < IM_ARRAYSIZE(g.IO.KeysDown); i++)
 | 
					    for (int i = 0; i < IM_ARRAYSIZE(g.IO.KeysDown); i++)
 | 
				
			||||||
@@ -9117,22 +9118,6 @@ static void ImGui::NavUpdate()
 | 
				
			|||||||
            io.NavInputs[ImGuiNavInput_TweakSlow] = 1.0f;
 | 
					            io.NavInputs[ImGuiNavInput_TweakSlow] = 1.0f;
 | 
				
			||||||
        if (io.KeyShift)
 | 
					        if (io.KeyShift)
 | 
				
			||||||
            io.NavInputs[ImGuiNavInput_TweakFast] = 1.0f;
 | 
					            io.NavInputs[ImGuiNavInput_TweakFast] = 1.0f;
 | 
				
			||||||
 | 
					 | 
				
			||||||
        // AltGR is normally Alt+Ctrl but we can't reliably detect it (not all backends/systems/layout emit it as Alt+Ctrl)
 | 
					 | 
				
			||||||
        // But also even on keyboards without AltGR we don't want Alt+Ctrl to open menu anyway.
 | 
					 | 
				
			||||||
        if (io.KeyAlt && !io.KeyCtrl)
 | 
					 | 
				
			||||||
            io.NavInputs[ImGuiNavInput_KeyMenu_]  = 1.0f;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // We cancel toggling nav layer when any text has been typed while holding Alt. (See #370)
 | 
					 | 
				
			||||||
        // We cancel toggling nav layer when other modifiers are pressed. (See #4439)
 | 
					 | 
				
			||||||
        if (g.NavWindowingToggleLayer && g.NavInputSource == ImGuiInputSource_Keyboard)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if (io.KeyAlt && !io.KeyCtrl && io.InputQueueCharacters.Size > 0)
 | 
					 | 
				
			||||||
                g.NavWindowingToggleLayer = false;
 | 
					 | 
				
			||||||
            if (io.KeyCtrl || io.KeyShift || io.KeySuper)
 | 
					 | 
				
			||||||
                g.NavWindowingToggleLayer = false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #undef NAV_MAP_KEY
 | 
					        #undef NAV_MAP_KEY
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    memcpy(io.NavInputsDownDurationPrev, io.NavInputsDownDuration, sizeof(io.NavInputsDownDuration));
 | 
					    memcpy(io.NavInputsDownDurationPrev, io.NavInputsDownDuration, sizeof(io.NavInputsDownDuration));
 | 
				
			||||||
@@ -9625,6 +9610,8 @@ static void NavUpdateWindowingHighlightWindow(int focus_change_dir)
 | 
				
			|||||||
static void ImGui::NavUpdateWindowing()
 | 
					static void ImGui::NavUpdateWindowing()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ImGuiContext& g = *GImGui;
 | 
					    ImGuiContext& g = *GImGui;
 | 
				
			||||||
 | 
					    ImGuiIO& io = g.IO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ImGuiWindow* apply_focus_window = NULL;
 | 
					    ImGuiWindow* apply_focus_window = NULL;
 | 
				
			||||||
    bool apply_toggle_layer = false;
 | 
					    bool apply_toggle_layer = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -9636,14 +9623,14 @@ static void ImGui::NavUpdateWindowing()
 | 
				
			|||||||
    // Fade out
 | 
					    // Fade out
 | 
				
			||||||
    if (g.NavWindowingTargetAnim && g.NavWindowingTarget == NULL)
 | 
					    if (g.NavWindowingTargetAnim && g.NavWindowingTarget == NULL)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        g.NavWindowingHighlightAlpha = ImMax(g.NavWindowingHighlightAlpha - g.IO.DeltaTime * 10.0f, 0.0f);
 | 
					        g.NavWindowingHighlightAlpha = ImMax(g.NavWindowingHighlightAlpha - io.DeltaTime * 10.0f, 0.0f);
 | 
				
			||||||
        if (g.DimBgRatio <= 0.0f && g.NavWindowingHighlightAlpha <= 0.0f)
 | 
					        if (g.DimBgRatio <= 0.0f && g.NavWindowingHighlightAlpha <= 0.0f)
 | 
				
			||||||
            g.NavWindowingTargetAnim = NULL;
 | 
					            g.NavWindowingTargetAnim = NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Start CTRL-TAB or Square+L/R window selection
 | 
					    // Start CTRL-TAB or Square+L/R window selection
 | 
				
			||||||
    bool start_windowing_with_gamepad = allow_windowing && !g.NavWindowingTarget && IsNavInputTest(ImGuiNavInput_Menu, ImGuiInputReadMode_Pressed);
 | 
					    bool start_windowing_with_gamepad = allow_windowing && !g.NavWindowingTarget && IsNavInputTest(ImGuiNavInput_Menu, ImGuiInputReadMode_Pressed);
 | 
				
			||||||
    bool start_windowing_with_keyboard = allow_windowing && !g.NavWindowingTarget && g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab) && (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard);
 | 
					    bool start_windowing_with_keyboard = allow_windowing && !g.NavWindowingTarget && io.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab) && (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard);
 | 
				
			||||||
    if (start_windowing_with_gamepad || start_windowing_with_keyboard)
 | 
					    if (start_windowing_with_gamepad || start_windowing_with_keyboard)
 | 
				
			||||||
        if (ImGuiWindow* window = g.NavWindow ? g.NavWindow : FindWindowNavFocusable(g.WindowsFocusOrder.Size - 1, -INT_MAX, -1))
 | 
					        if (ImGuiWindow* window = g.NavWindow ? g.NavWindow : FindWindowNavFocusable(g.WindowsFocusOrder.Size - 1, -INT_MAX, -1))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -9654,7 +9641,7 @@ static void ImGui::NavUpdateWindowing()
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Gamepad update
 | 
					    // Gamepad update
 | 
				
			||||||
    g.NavWindowingTimer += g.IO.DeltaTime;
 | 
					    g.NavWindowingTimer += io.DeltaTime;
 | 
				
			||||||
    if (g.NavWindowingTarget && g.NavInputSource == ImGuiInputSource_Gamepad)
 | 
					    if (g.NavWindowingTarget && g.NavInputSource == ImGuiInputSource_Gamepad)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // Highlight only appears after a brief time holding the button, so that a fast tap on PadMenu (to toggle NavLayer) doesn't add visual noise
 | 
					        // Highlight only appears after a brief time holding the button, so that a fast tap on PadMenu (to toggle NavLayer) doesn't add visual noise
 | 
				
			||||||
@@ -9686,34 +9673,48 @@ static void ImGui::NavUpdateWindowing()
 | 
				
			|||||||
        // Visuals only appears after a brief time after pressing TAB the first time, so that a fast CTRL+TAB doesn't add visual noise
 | 
					        // Visuals only appears after a brief time after pressing TAB the first time, so that a fast CTRL+TAB doesn't add visual noise
 | 
				
			||||||
        g.NavWindowingHighlightAlpha = ImMax(g.NavWindowingHighlightAlpha, ImSaturate((g.NavWindowingTimer - NAV_WINDOWING_HIGHLIGHT_DELAY) / 0.05f)); // 1.0f
 | 
					        g.NavWindowingHighlightAlpha = ImMax(g.NavWindowingHighlightAlpha, ImSaturate((g.NavWindowingTimer - NAV_WINDOWING_HIGHLIGHT_DELAY) / 0.05f)); // 1.0f
 | 
				
			||||||
        if (IsKeyPressedMap(ImGuiKey_Tab, true))
 | 
					        if (IsKeyPressedMap(ImGuiKey_Tab, true))
 | 
				
			||||||
            NavUpdateWindowingHighlightWindow(g.IO.KeyShift ? +1 : -1);
 | 
					            NavUpdateWindowingHighlightWindow(io.KeyShift ? +1 : -1);
 | 
				
			||||||
        if (!g.IO.KeyCtrl)
 | 
					        if (!io.KeyCtrl)
 | 
				
			||||||
            apply_focus_window = g.NavWindowingTarget;
 | 
					            apply_focus_window = g.NavWindowingTarget;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Keyboard: Press and Release ALT to toggle menu layer
 | 
					    // Keyboard: Press and Release ALT to toggle menu layer
 | 
				
			||||||
    // FIXME: We lack an explicit IO variable for "is the imgui window focused", so compare mouse validity to detect the common case of backend clearing releases all keys on ALT-TAB
 | 
					    // - Testing that only Alt is tested prevents Alt+Shift or AltGR from toggling menu layer.
 | 
				
			||||||
    if (IsNavInputTest(ImGuiNavInput_KeyMenu_, ImGuiInputReadMode_Pressed) && g.IO.KeyMods == ImGuiKeyModFlags_Alt)
 | 
					    // - AltGR is normally Alt+Ctrl but we can't reliably detect it (not all backends/systems/layout emit it as Alt+Ctrl). But even on keyboards without AltGR we don't want Alt+Ctrl to open menu anyway.
 | 
				
			||||||
 | 
					    if (io.KeyMods == ImGuiKeyModFlags_Alt && (io.KeyModsPrev & ImGuiKeyModFlags_Alt) == 0)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        g.NavWindowingToggleLayer = true;
 | 
					        g.NavWindowingToggleLayer = true;
 | 
				
			||||||
        g.NavInputSource = ImGuiInputSource_Keyboard;
 | 
					        g.NavInputSource = ImGuiInputSource_Keyboard;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if ((g.ActiveId == 0 || g.ActiveIdAllowOverlap) && g.NavWindowingToggleLayer && IsNavInputTest(ImGuiNavInput_KeyMenu_, ImGuiInputReadMode_Released))
 | 
					    if (g.NavWindowingToggleLayer && g.NavInputSource == ImGuiInputSource_Keyboard)
 | 
				
			||||||
        if (IsMousePosValid(&g.IO.MousePos) == IsMousePosValid(&g.IO.MousePosPrev))
 | 
					    {
 | 
				
			||||||
 | 
					        // 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)
 | 
				
			||||||
 | 
					        if (io.InputQueueCharacters.Size > 0 || io.KeyCtrl || io.KeyShift || io.KeySuper)
 | 
				
			||||||
 | 
					            g.NavWindowingToggleLayer = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Apply layer toggle on release
 | 
				
			||||||
 | 
					        // FIXME: We lack an explicit IO variable for "is the platform window focused", so compare mouse validity to detect the common case of backend clearing releases all keys on ALT-TAB
 | 
				
			||||||
 | 
					        if (!io.KeyAlt && g.NavWindowingToggleLayer)
 | 
				
			||||||
 | 
					            if (g.ActiveId == 0 || g.ActiveIdAllowOverlap)
 | 
				
			||||||
 | 
					                if (IsMousePosValid(&io.MousePos) == IsMousePosValid(&io.MousePosPrev))
 | 
				
			||||||
                    apply_toggle_layer = true;
 | 
					                    apply_toggle_layer = true;
 | 
				
			||||||
 | 
					        if (!io.KeyAlt)
 | 
				
			||||||
 | 
					            g.NavWindowingToggleLayer = false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Move window
 | 
					    // Move window
 | 
				
			||||||
    if (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoMove))
 | 
					    if (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoMove))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        ImVec2 move_delta;
 | 
					        ImVec2 move_delta;
 | 
				
			||||||
        if (g.NavInputSource == ImGuiInputSource_Keyboard && !g.IO.KeyShift)
 | 
					        if (g.NavInputSource == ImGuiInputSource_Keyboard && !io.KeyShift)
 | 
				
			||||||
            move_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard, ImGuiInputReadMode_Down);
 | 
					            move_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard, ImGuiInputReadMode_Down);
 | 
				
			||||||
        if (g.NavInputSource == ImGuiInputSource_Gamepad)
 | 
					        if (g.NavInputSource == ImGuiInputSource_Gamepad)
 | 
				
			||||||
            move_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_PadLStick, ImGuiInputReadMode_Down);
 | 
					            move_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_PadLStick, ImGuiInputReadMode_Down);
 | 
				
			||||||
        if (move_delta.x != 0.0f || move_delta.y != 0.0f)
 | 
					        if (move_delta.x != 0.0f || move_delta.y != 0.0f)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            const float NAV_MOVE_SPEED = 800.0f;
 | 
					            const float NAV_MOVE_SPEED = 800.0f;
 | 
				
			||||||
            const float move_speed = ImFloor(NAV_MOVE_SPEED * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y)); // FIXME: Doesn't handle variable framerate very well
 | 
					            const float move_speed = ImFloor(NAV_MOVE_SPEED * io.DeltaTime * ImMin(io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y)); // FIXME: Doesn't handle variable framerate very well
 | 
				
			||||||
            ImGuiWindow* moving_window = g.NavWindowingTarget->RootWindow;
 | 
					            ImGuiWindow* moving_window = g.NavWindowingTarget->RootWindow;
 | 
				
			||||||
            SetWindowPos(moving_window, moving_window->Pos + move_delta * move_speed, ImGuiCond_Always);
 | 
					            SetWindowPos(moving_window, moving_window->Pos + move_delta * move_speed, ImGuiCond_Always);
 | 
				
			||||||
            MarkIniSettingsDirty(moving_window);
 | 
					            MarkIniSettingsDirty(moving_window);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								imgui.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								imgui.h
									
									
									
									
									
								
							@@ -1388,13 +1388,12 @@ enum ImGuiNavInput_
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // [Internal] Don't use directly! This is used internally to differentiate keyboard from gamepad inputs for behaviors that require to differentiate them.
 | 
					    // [Internal] Don't use directly! This is used internally to differentiate keyboard from gamepad inputs for behaviors that require to differentiate them.
 | 
				
			||||||
    // Keyboard behavior that have no corresponding gamepad mapping (e.g. CTRL+TAB) will be directly reading from io.KeysDown[] instead of io.NavInputs[].
 | 
					    // Keyboard behavior that have no corresponding gamepad mapping (e.g. CTRL+TAB) will be directly reading from io.KeysDown[] instead of io.NavInputs[].
 | 
				
			||||||
    ImGuiNavInput_KeyMenu_,      // toggle menu                                  // = io.KeyAlt
 | 
					 | 
				
			||||||
    ImGuiNavInput_KeyLeft_,      // move left                                    // = Arrow keys
 | 
					    ImGuiNavInput_KeyLeft_,      // move left                                    // = Arrow keys
 | 
				
			||||||
    ImGuiNavInput_KeyRight_,     // move right
 | 
					    ImGuiNavInput_KeyRight_,     // move right
 | 
				
			||||||
    ImGuiNavInput_KeyUp_,        // move up
 | 
					    ImGuiNavInput_KeyUp_,        // move up
 | 
				
			||||||
    ImGuiNavInput_KeyDown_,      // move down
 | 
					    ImGuiNavInput_KeyDown_,      // move down
 | 
				
			||||||
    ImGuiNavInput_COUNT,
 | 
					    ImGuiNavInput_COUNT,
 | 
				
			||||||
    ImGuiNavInput_InternalStart_ = ImGuiNavInput_KeyMenu_
 | 
					    ImGuiNavInput_InternalStart_ = ImGuiNavInput_KeyLeft_
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Configuration flags stored in io.ConfigFlags. Set by user/application.
 | 
					// Configuration flags stored in io.ConfigFlags. Set by user/application.
 | 
				
			||||||
@@ -1896,6 +1895,7 @@ struct ImGuiIO
 | 
				
			|||||||
    //------------------------------------------------------------------
 | 
					    //------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ImGuiKeyModFlags KeyMods;                   // Key mods flags (same as io.KeyCtrl/KeyShift/KeyAlt/KeySuper but merged into flags), updated by NewFrame()
 | 
					    ImGuiKeyModFlags KeyMods;                   // Key mods flags (same as io.KeyCtrl/KeyShift/KeyAlt/KeySuper but merged into flags), updated by NewFrame()
 | 
				
			||||||
 | 
					    ImGuiKeyModFlags KeyModsPrev;               // Previous key mods
 | 
				
			||||||
    ImVec2      MousePosPrev;                   // Previous mouse position (note that MouseDelta is not necessary == MousePos-MousePosPrev, in case either position is invalid)
 | 
					    ImVec2      MousePosPrev;                   // Previous mouse position (note that MouseDelta is not necessary == MousePos-MousePosPrev, in case either position is invalid)
 | 
				
			||||||
    ImVec2      MouseClickedPos[5];             // Position at time of clicking
 | 
					    ImVec2      MouseClickedPos[5];             // Position at time of clicking
 | 
				
			||||||
    double      MouseClickedTime[5];            // Time of last click (used to figure out double-click)
 | 
					    double      MouseClickedTime[5];            // Time of last click (used to figure out double-click)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user