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:
parent
8fa502ca42
commit
ff428f1d2f
57
imgui.cpp
57
imgui.cpp
@ -4033,6 +4033,7 @@ void ImGui::NewFrame()
|
||||
|
||||
// Update keyboard input state
|
||||
// Synchronize io.KeyMods with individual modifiers io.KeyXXX bools
|
||||
g.IO.KeyModsPrev = g.IO.KeyMods;
|
||||
g.IO.KeyMods = GetMergedKeyModFlags();
|
||||
memcpy(g.IO.KeysDownDurationPrev, g.IO.KeysDownDuration, sizeof(g.IO.KeysDownDuration));
|
||||
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;
|
||||
if (io.KeyShift)
|
||||
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
|
||||
}
|
||||
memcpy(io.NavInputsDownDurationPrev, io.NavInputsDownDuration, sizeof(io.NavInputsDownDuration));
|
||||
@ -9625,6 +9610,8 @@ static void NavUpdateWindowingHighlightWindow(int focus_change_dir)
|
||||
static void ImGui::NavUpdateWindowing()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiIO& io = g.IO;
|
||||
|
||||
ImGuiWindow* apply_focus_window = NULL;
|
||||
bool apply_toggle_layer = false;
|
||||
|
||||
@ -9636,14 +9623,14 @@ static void ImGui::NavUpdateWindowing()
|
||||
// Fade out
|
||||
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)
|
||||
g.NavWindowingTargetAnim = NULL;
|
||||
}
|
||||
|
||||
// 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_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 (ImGuiWindow* window = g.NavWindow ? g.NavWindow : FindWindowNavFocusable(g.WindowsFocusOrder.Size - 1, -INT_MAX, -1))
|
||||
{
|
||||
@ -9654,7 +9641,7 @@ static void ImGui::NavUpdateWindowing()
|
||||
}
|
||||
|
||||
// Gamepad update
|
||||
g.NavWindowingTimer += g.IO.DeltaTime;
|
||||
g.NavWindowingTimer += io.DeltaTime;
|
||||
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
|
||||
@ -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
|
||||
g.NavWindowingHighlightAlpha = ImMax(g.NavWindowingHighlightAlpha, ImSaturate((g.NavWindowingTimer - NAV_WINDOWING_HIGHLIGHT_DELAY) / 0.05f)); // 1.0f
|
||||
if (IsKeyPressedMap(ImGuiKey_Tab, true))
|
||||
NavUpdateWindowingHighlightWindow(g.IO.KeyShift ? +1 : -1);
|
||||
if (!g.IO.KeyCtrl)
|
||||
NavUpdateWindowingHighlightWindow(io.KeyShift ? +1 : -1);
|
||||
if (!io.KeyCtrl)
|
||||
apply_focus_window = g.NavWindowingTarget;
|
||||
}
|
||||
|
||||
// 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
|
||||
if (IsNavInputTest(ImGuiNavInput_KeyMenu_, ImGuiInputReadMode_Pressed) && g.IO.KeyMods == ImGuiKeyModFlags_Alt)
|
||||
// - Testing that only Alt is tested prevents Alt+Shift or AltGR from toggling menu layer.
|
||||
// - 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.NavInputSource = ImGuiInputSource_Keyboard;
|
||||
}
|
||||
if ((g.ActiveId == 0 || g.ActiveIdAllowOverlap) && g.NavWindowingToggleLayer && IsNavInputTest(ImGuiNavInput_KeyMenu_, ImGuiInputReadMode_Released))
|
||||
if (IsMousePosValid(&g.IO.MousePos) == IsMousePosValid(&g.IO.MousePosPrev))
|
||||
apply_toggle_layer = true;
|
||||
if (g.NavWindowingToggleLayer && g.NavInputSource == 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)
|
||||
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;
|
||||
if (!io.KeyAlt)
|
||||
g.NavWindowingToggleLayer = false;
|
||||
}
|
||||
|
||||
// Move window
|
||||
if (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoMove))
|
||||
{
|
||||
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);
|
||||
if (g.NavInputSource == ImGuiInputSource_Gamepad)
|
||||
move_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_PadLStick, ImGuiInputReadMode_Down);
|
||||
if (move_delta.x != 0.0f || move_delta.y != 0.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;
|
||||
SetWindowPos(moving_window, moving_window->Pos + move_delta * move_speed, ImGuiCond_Always);
|
||||
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.
|
||||
// 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_KeyRight_, // move right
|
||||
ImGuiNavInput_KeyUp_, // move up
|
||||
ImGuiNavInput_KeyDown_, // move down
|
||||
ImGuiNavInput_COUNT,
|
||||
ImGuiNavInput_InternalStart_ = ImGuiNavInput_KeyMenu_
|
||||
ImGuiNavInput_InternalStart_ = ImGuiNavInput_KeyLeft_
|
||||
};
|
||||
|
||||
// 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 KeyModsPrev; // Previous key mods
|
||||
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
|
||||
double MouseClickedTime[5]; // Time of last click (used to figure out double-click)
|
||||
|
Loading…
Reference in New Issue
Block a user