diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 5cc4f75f..3d3abd49 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -63,6 +63,7 @@ Other Changes: - Misc: Added ImGuiMouseCursor_Hand cursor enum + corresponding software cursor. (#1913, 1914) [@aiekick, @ocornut] - Misc: Tweaked software mouse cursor offset to match the offset of the corresponding Windows 10 cursors. - Made assertion more clear when trying to call Begin() outside of the NewFrame()..EndFrame() scope. (#1987) + - Fixed assertion when transitioning from an active ID to another within a group, affecting ColorPicker (broken in 1.62). (#2023, #820, #956, #1875). - Fixed PushID() from keeping alive the new ID Stack top value (if a previously active widget shared the ID it would be erroneously kept alive). - Fixed horizontal mouse wheel not forwarding the request to the parent window if ImGuiWindowFlags_NoScrollWithMouse is set. (#1463, #1380, #1502) - Fixed a include build issue for Cygwin in non-POSIX (Win32) mode. (#1917, #1319, #276) diff --git a/imgui.cpp b/imgui.cpp index 09dde3f5..85910a6e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2271,7 +2271,7 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window) g.ActiveIdWindow = window; if (id) { - g.ActiveIdIsAlive = true; + g.ActiveIdIsAlive = id; g.ActiveIdSource = (g.NavActivateId == id || g.NavInputId == id || g.NavJustTabbedId == id || g.NavJustMovedToId == id) ? ImGuiInputSource_Nav : ImGuiInputSource_Mouse; } } @@ -2322,7 +2322,7 @@ void ImGui::KeepAliveID(ImGuiID id) { ImGuiContext& g = *GImGui; if (g.ActiveId == id) - g.ActiveIdIsAlive = true; + g.ActiveIdIsAlive = id; if (g.ActiveIdPreviousFrame == id) g.ActiveIdPreviousFrameIsAlive = true; } @@ -3934,7 +3934,7 @@ void ImGui::NewFrame() g.HoveredIdPreviousFrame = g.HoveredId; g.HoveredId = 0; g.HoveredIdAllowOverlap = false; - if (!g.ActiveIdIsAlive && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0) + if (g.ActiveIdIsAlive != g.ActiveId && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0) ClearActiveID(); if (g.ActiveId) g.ActiveIdTimer += g.IO.DeltaTime; @@ -3942,7 +3942,8 @@ void ImGui::NewFrame() g.ActiveIdPreviousFrame = g.ActiveId; g.ActiveIdPreviousFrameWindow = g.ActiveIdWindow; g.ActiveIdPreviousFrameValueChanged = g.ActiveIdValueChanged; - g.ActiveIdIsAlive = g.ActiveIdPreviousFrameIsAlive = false; + g.ActiveIdIsAlive = 0; + g.ActiveIdPreviousFrameIsAlive = false; g.ActiveIdIsJustActivated = false; if (g.ScalarAsInputTextId && g.ActiveId != g.ScalarAsInputTextId) g.ScalarAsInputTextId = 0; @@ -13155,7 +13156,7 @@ void ImGui::EndGroup() // If the current ActiveId was declared within the boundary of our group, we copy it to LastItemId so IsItemActive(), IsItemDeactivated() etc. will be functional on the entire group. // It would be be neater if we replaced window.DC.LastItemId by e.g. 'bool LastItemIsActive', but put a little more burden on individual widgets. // (and if you grep for LastItemId you'll notice it is only used in that context. - if (!group_data.BackupActiveIdIsAlive && g.ActiveIdIsAlive && g.ActiveId) // && g.ActiveIdWindow->RootWindow == window->RootWindow) + if ((group_data.BackupActiveIdIsAlive != g.ActiveId) && (g.ActiveIdIsAlive == g.ActiveId) && g.ActiveId) // && g.ActiveIdWindow->RootWindow == window->RootWindow) window->DC.LastItemId = g.ActiveId; else if (!group_data.BackupActiveIdPreviousFrameIsAlive && g.ActiveIdPreviousFrameIsAlive) // && g.ActiveIdPreviousFrameWindow->RootWindow == window->RootWindow) window->DC.LastItemId = g.ActiveIdPreviousFrame; diff --git a/imgui_internal.h b/imgui_internal.h index c3aee425..11e00fa8 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -408,7 +408,7 @@ struct ImGuiGroupData float BackupCurrentLineHeight; float BackupCurrentLineTextBaseOffset; float BackupLogLinePosY; - bool BackupActiveIdIsAlive; + ImGuiID BackupActiveIdIsAlive; bool BackupActiveIdPreviousFrameIsAlive; bool AdvanceCursor; }; @@ -637,8 +637,8 @@ struct ImGuiContext float HoveredIdTimer; ImGuiID ActiveId; // Active widget ImGuiID ActiveIdPreviousFrame; + ImGuiID ActiveIdIsAlive; // Active widget has been seen this frame (we can't use a bool as the ActiveId may change within the frame) float ActiveIdTimer; - bool ActiveIdIsAlive; // Active widget has been seen this frame bool ActiveIdIsJustActivated; // Set at the time of activation for one frame bool ActiveIdAllowOverlap; // Active widget allows another widget to steal active id (generally for overlapping widgets, but not always) bool ActiveIdValueChanged; @@ -784,8 +784,8 @@ struct ImGuiContext HoveredIdTimer = 0.0f; ActiveId = 0; ActiveIdPreviousFrame = 0; + ActiveIdIsAlive = 0; ActiveIdTimer = 0.0f; - ActiveIdIsAlive = false; ActiveIdIsJustActivated = false; ActiveIdAllowOverlap = false; ActiveIdValueChanged = false;