1
0
Fork 0
mirror of https://github.com/ocornut/imgui.git synced 2026-01-08 23:44:19 +00:00

Nav, Shortcuts, Tooltips: tooltip reference position not affected by remote shortcut activation. (#9138, #456)

NavCalcPreferredRefPos() has different path for popups vs tooltip.
Amend 197f8904fe
This commit is contained in:
ocornut 2026-01-08 17:14:38 +01:00
parent ca9b7b4071
commit 7a02f4b545

View file

@ -1347,8 +1347,8 @@ static bool NavScoreItem(ImGuiNavItemData* result, const ImRect& nav
static void NavApplyItemToResult(ImGuiNavItemData* result);
static void NavProcessItem();
static void NavProcessItemForTabbingRequest(ImGuiID id, ImGuiItemFlags item_flags, ImGuiNavMoveFlags move_flags);
static ImGuiInputSource NavCalcPreferredRefPosSource();
static ImVec2 NavCalcPreferredRefPos();
static ImGuiInputSource NavCalcPreferredRefPosSource(ImGuiWindowFlags window_type);
static ImVec2 NavCalcPreferredRefPos(ImGuiWindowFlags window_type);
static void NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window);
static ImGuiWindow* NavRestoreLastChildNavWindow(ImGuiWindow* window);
static void NavRestoreLayer(ImGuiNavLayer layer);
@ -12203,7 +12203,7 @@ void ImGui::OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags)
popup_ref.RestoreNavWindow = g.NavWindow; // When popup closes focus may be restored to NavWindow (depend on window type).
popup_ref.OpenFrameCount = g.FrameCount;
popup_ref.OpenParentId = parent_window->IDStack.back();
popup_ref.OpenPopupPos = NavCalcPreferredRefPos();
popup_ref.OpenPopupPos = NavCalcPreferredRefPos(ImGuiWindowFlags_Popup);
popup_ref.OpenMousePos = IsMousePosValid(&g.IO.MousePos) ? g.IO.MousePos : popup_ref.OpenPopupPos;
IMGUI_DEBUG_LOG_POPUP("[popup] OpenPopupEx(0x%08X)\n", id);
@ -12681,9 +12681,9 @@ ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window)
// as drag and drop tooltips are calling SetNextWindowPos() leading to 'window_pos_set_by_api' being set in Begin().
IM_ASSERT(g.CurrentWindow == window);
const float scale = g.Style.MouseCursorScale;
const ImVec2 ref_pos = NavCalcPreferredRefPos();
const ImVec2 ref_pos = NavCalcPreferredRefPos(ImGuiWindowFlags_Tooltip);
if (g.IO.MouseSource == ImGuiMouseSource_TouchScreen && NavCalcPreferredRefPosSource() == ImGuiInputSource_Mouse)
if (g.IO.MouseSource == ImGuiMouseSource_TouchScreen && NavCalcPreferredRefPosSource(ImGuiWindowFlags_Tooltip) == ImGuiInputSource_Mouse)
{
ImVec2 tooltip_pos = ref_pos + TOOLTIP_DEFAULT_OFFSET_TOUCH * scale - (TOOLTIP_DEFAULT_PIVOT_TOUCH * window->Size);
if (r_outer.Contains(ImRect(tooltip_pos, tooltip_pos + window->Size)))
@ -13568,33 +13568,29 @@ void ImGui::NavInitWindow(ImGuiWindow* window, bool force_reinit)
}
}
static ImGuiInputSource ImGui::NavCalcPreferredRefPosSource()
// Positioning logic altered slightly for remote activation: for Popup we want to use item rect, for Tooltip we leave things alone. (#9138)
// When calling for ImGuiWindowFlags_Popup we use LastItemData.
static ImGuiInputSource ImGui::NavCalcPreferredRefPosSource(ImGuiWindowFlags window_type)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.NavWindow;
const bool activated_shortcut = g.ActiveId != 0 && g.ActiveIdFromShortcut && g.ActiveId == g.LastItemData.ID;
//const bool activated_shortcut = false
// Testing for !activated_shortcut here could in theory be removed if we decided that activating a remote shortcut altered one of the g.NavDisableXXX flag.
if ((!g.NavCursorVisible || !g.NavHighlightItemUnderNav || !window) && !activated_shortcut)
const bool activated_shortcut = g.ActiveId != 0 && g.ActiveIdFromShortcut && g.ActiveId == g.LastItemData.ID;
if ((window_type & ImGuiWindowFlags_Popup) && activated_shortcut)
return ImGuiInputSource_Keyboard;
if (!g.NavCursorVisible || !g.NavHighlightItemUnderNav || !window)
return ImGuiInputSource_Mouse;
else
return ImGuiInputSource_Keyboard; // or Nav in general
}
static ImVec2 ImGui::NavCalcPreferredRefPos()
static ImVec2 ImGui::NavCalcPreferredRefPos(ImGuiWindowFlags window_type)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.NavWindow;
ImGuiInputSource source = NavCalcPreferredRefPosSource();
ImGuiInputSource source = NavCalcPreferredRefPosSource(window_type);
const bool activated_shortcut = g.ActiveId != 0 && g.ActiveIdFromShortcut && g.ActiveId == g.LastItemData.ID;
//const bool activated_shortcut = false
if (source != ImGuiInputSource_Mouse && !activated_shortcut && window == NULL)
source = ImGuiInputSource_Mouse;
// Testing for !activated_shortcut here could in theory be removed if we decided that activating a remote shortcut altered one of the g.NavDisableXXX flag.
if (source == ImGuiInputSource_Mouse)
{
// Mouse (we need a fallback in case the mouse becomes invalid after being used)
@ -13606,8 +13602,9 @@ static ImVec2 ImGui::NavCalcPreferredRefPos()
else
{
// When navigation is active and mouse is disabled, pick a position around the bottom left of the currently navigated item
const bool activated_shortcut = g.ActiveId != 0 && g.ActiveIdFromShortcut && g.ActiveId == g.LastItemData.ID;
ImRect ref_rect;
if (activated_shortcut)
if (activated_shortcut && (window_type & ImGuiWindowFlags_Popup))
ref_rect = g.LastItemData.NavRect;
else if (window != NULL)
ref_rect = WindowRectRelToAbs(window, window->NavRectRel[g.NavLayer]);
@ -13806,7 +13803,7 @@ static void ImGui::NavUpdate()
// Update mouse position if requested
// (This will take into account the possibility that a Scroll was queued in the window to offset our absolute mouse position before scroll has been applied)
if (set_mouse_pos && io.ConfigNavMoveSetMousePos && (io.BackendFlags & ImGuiBackendFlags_HasSetMousePos))
TeleportMousePos(NavCalcPreferredRefPos());
TeleportMousePos(NavCalcPreferredRefPos(ImGuiWindowFlags_Popup));
// [DEBUG]
g.NavScoringDebugCount = 0;