From ff36fe365e042a6b72b9a20767fcb4b2c0571d42 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 18 Sep 2023 17:07:35 +0200 Subject: [PATCH] IO, Inputs: setting io.WantSetMousePos ignores incoming MousePos events. (#6837, #228) Allow easily implementing wrapping behaviors. --- docs/CHANGELOG.txt | 1 + imgui.cpp | 18 +++++++++++++----- imgui_internal.h | 1 + 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index b43ab60eb..4d769176c 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -92,6 +92,7 @@ Other changes: - MenuBar: Fixed an issue where layouting an item in the menu-bar would erroneously register contents size in a way that would affect the scrolling layer. Was most often noticable when using an horizontal scrollbar. (#6789) +- IO: Setting io.WantSetMousePos ignores incoming MousePos events. (#6837, #228) - ImDrawList: Added AddEllipse(), AddEllipseFilled(), PathEllipticalArcTo(). (#2743) [@Doohl] - ImVector: Added find_index() helper. - Backends: GLFW: Clear emscripten's MouseWheel callback before shutdown. (#6790, #6096, #4019) [@halx99] diff --git a/imgui.cpp b/imgui.cpp index 5ac64edf1..3f730e7a1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7888,6 +7888,7 @@ bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max) // - IsMouseDragPastThreshold() [Internal] // - IsMouseDragging() // - GetMousePos() +// - SetMousePos() [Internal] // - GetMousePosOnOpeningCurrentPopup() // - IsMousePosValid() // - IsAnyMouseDown() @@ -8415,6 +8416,15 @@ ImVec2 ImGui::GetMousePos() return g.IO.MousePos; } +// It is expected you only call this if (io.BackendFlags & ImGuiBackendFlags_HasSetMousePos) is set and supported by backend. +void ImGui::SetMousePos(const ImVec2& pos) +{ + ImGuiContext& g = *GImGui; + g.IO.MousePos = g.IO.MousePosPrev = pos; + g.IO.WantSetMousePos = true; + //IMGUI_DEBUG_LOG_IO("SetMousePos: (%.1f,%.1f)\n", io.MousePos.x, io.MousePos.y); +} + // NB: prefer to call right after BeginPopup(). At the time Selectable/MenuItem is activated, the popup is already closed! ImVec2 ImGui::GetMousePosOnOpeningCurrentPopup() { @@ -8903,6 +8913,8 @@ void ImGui::UpdateInputEvents(bool trickle_fast_inputs) ImGuiInputEvent* e = &g.InputEventsQueue[event_n]; if (e->Type == ImGuiInputEventType_MousePos) { + if (g.IO.WantSetMousePos) + continue; // Trickling Rule: Stop processing queued events if we already handled a mouse button change ImVec2 event_pos(e->MousePos.PosX, e->MousePos.PosY); if (trickle_fast_inputs && (mouse_button_changed != 0 || mouse_wheeled || key_changed || text_inputted)) @@ -11550,11 +11562,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.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) && (io.BackendFlags & ImGuiBackendFlags_HasSetMousePos)) - { - io.MousePos = io.MousePosPrev = NavCalcPreferredRefPos(); - io.WantSetMousePos = true; - //IMGUI_DEBUG_LOG_IO("SetMousePos: (%.1f,%.1f)\n", io.MousePos.x, io.MousePos.y); - } + SetMousePos(NavCalcPreferredRefPos()); // [DEBUG] g.NavScoringDebugCount = 0; diff --git a/imgui_internal.h b/imgui_internal.h index 4dcdf97fc..6596a67ef 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -3059,6 +3059,7 @@ namespace ImGui IMGUI_API float GetNavTweakPressedAmount(ImGuiAxis axis); IMGUI_API int CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, float repeat_rate); IMGUI_API void GetTypematicRepeatRate(ImGuiInputFlags flags, float* repeat_delay, float* repeat_rate); + IMGUI_API void SetMousePos(const ImVec2& pos); IMGUI_API void SetActiveIdUsingAllKeyboardKeys(); inline bool IsActiveIdUsingNavDir(ImGuiDir dir) { ImGuiContext& g = *GImGui; return (g.ActiveIdUsingNavDirMask & (1 << dir)) != 0; }