From 47a07d8476b4f1b0438902ff322433eab0256051 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 4 Apr 2023 21:43:48 +0200 Subject: [PATCH] ButtonBehavior: Fixed an edge case where changing widget type/behavior while active and using same id could lead to an assert. (#6304) + Demo: use BeginDisabled() block in BackendFlags section. I'd still consider this undefined behavior as some combination may not work properly, but let's fix things while we can as we encounter them. --- docs/CHANGELOG.txt | 2 ++ imgui.h | 2 +- imgui_demo.cpp | 14 +++++++------- imgui_widgets.cpp | 7 ++++++- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index a96410b0..123985a6 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -56,6 +56,8 @@ Other changes: horizontal mouse-wheel (or Shift + WheelY). (#2702) - Rendering: Using adaptative tesselation for: RadioButton, ColorEdit preview circles, Windows Close and Collapse Buttons. +- ButtonBehavior: Fixed an edge case where changing widget type/behavior while active + and using same id could lead to an assert. (#6304) - Misc: Fixed ImVec2 operator[] violating aliasing rules causing issue with Intel C++ compiler. (#6272) [@BayesBug] - IO: Input queue trickling adjustment for touch screens. (#2702, #4921) diff --git a/imgui.h b/imgui.h index c974d9c7..02ef16f3 100644 --- a/imgui.h +++ b/imgui.h @@ -23,7 +23,7 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM > 12345') #define IMGUI_VERSION "1.89.5 WIP" -#define IMGUI_VERSION_NUM 18948 +#define IMGUI_VERSION_NUM 18949 #define IMGUI_HAS_TABLE /* diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 051f6f5b..5849ffbe 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -483,13 +483,13 @@ void ImGui::ShowDemoWindow(bool* p_open) "Those flags are set by the backends (imgui_impl_xxx files) to specify their capabilities.\n" "Here we expose them as read-only fields to avoid breaking interactions with your backend."); - // Make a local copy to avoid modifying actual backend flags. - // FIXME: We don't use BeginDisabled() to keep label bright, maybe we need a BeginReadonly() equivalent.. - ImGuiBackendFlags backend_flags = io.BackendFlags; - ImGui::CheckboxFlags("io.BackendFlags: HasGamepad", &backend_flags, ImGuiBackendFlags_HasGamepad); - ImGui::CheckboxFlags("io.BackendFlags: HasMouseCursors", &backend_flags, ImGuiBackendFlags_HasMouseCursors); - ImGui::CheckboxFlags("io.BackendFlags: HasSetMousePos", &backend_flags, ImGuiBackendFlags_HasSetMousePos); - ImGui::CheckboxFlags("io.BackendFlags: RendererHasVtxOffset", &backend_flags, ImGuiBackendFlags_RendererHasVtxOffset); + // FIXME: Maybe we need a BeginReadonly() equivalent to keep label bright? + ImGui::BeginDisabled(); + ImGui::CheckboxFlags("io.BackendFlags: HasGamepad", &io.BackendFlags, ImGuiBackendFlags_HasGamepad); + ImGui::CheckboxFlags("io.BackendFlags: HasMouseCursors", &io.BackendFlags, ImGuiBackendFlags_HasMouseCursors); + ImGui::CheckboxFlags("io.BackendFlags: HasSetMousePos", &io.BackendFlags, ImGuiBackendFlags_HasSetMousePos); + ImGui::CheckboxFlags("io.BackendFlags: RendererHasVtxOffset", &io.BackendFlags, ImGuiBackendFlags_RendererHasVtxOffset); + ImGui::EndDisabled(); ImGui::TreePop(); ImGui::Spacing(); } diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index a80fe0a6..8ea6e443 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -638,7 +638,12 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool g.ActiveIdClickOffset = g.IO.MousePos - bb.Min; const int mouse_button = g.ActiveIdMouseButton; - if (IsMouseDown(mouse_button, test_owner_id)) + if (mouse_button == -1) + { + // Fallback for the rare situation were g.ActiveId was set programmatically or from another widget (e.g. #6304). + ClearActiveID(); + } + else if (IsMouseDown(mouse_button, test_owner_id)) { held = true; }