From e0f5f9a14c4d11ea1c9fd1f7978a444333aa9993 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 12 May 2026 17:40:28 +0200 Subject: [PATCH 1/7] Amend AddRect(), AddPolyline() error detection to safely return an trigger error handling mechanism. Amend 6df50a0667a --- imgui.h | 2 +- imgui_draw.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui.h b/imgui.h index 9fdce397d..9a21e003d 100644 --- a/imgui.h +++ b/imgui.h @@ -30,7 +30,7 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') #define IMGUI_VERSION "1.92.8" -#define IMGUI_VERSION_NUM 19280 +#define IMGUI_VERSION_NUM 19281 #define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000 #define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198 diff --git a/imgui_draw.cpp b/imgui_draw.cpp index cfea11c0c..4cc709514 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -823,7 +823,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 const ImVec2 opaque_uv = _Data->TexUvWhitePixel; const int count = closed ? points_count : points_count - 1; // The number of line segments we need to draw const bool thick_line = (thickness > _FringeScale); - IM_ASSERT((flags & ImDrawFlags_InvalidMask_) == 0 && "Incorrect parameter. Did you swapped 'thickness' and 'flags'?"); + IM_ASSERT_USER_ERROR_RET((flags & ImDrawFlags_InvalidMask_) == 0, "Incorrect parameter. Did you swap 'thickness' and 'flags'?"); if (Flags & ImDrawListFlags_AntiAliasedLines) { @@ -1510,7 +1510,7 @@ void ImDrawList::AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, fl // - Hard coded support for values 0x01 to 0x0F (matching 15 out of 16 old flags combinations) --> see FixRectCornerFlags() in <1.90 code. // - Hard coded 0x00 with 'float rounding > 0.0f' --> replace with ImDrawFlags_RoundCornersNone or use 'float rounding = 0.0f'. // See "API BREAKING CHANGES" section for 1.82 and 1.90. - IM_ASSERT((flags & ImDrawFlags_InvalidMask_) == 0 && "Incorrect parameter. Did you swapped 'thickness' and 'flags'?"); // Or misuse of legacy hard-coded ImDrawCornerFlags values + IM_ASSERT_USER_ERROR_RET((flags & ImDrawFlags_InvalidMask_) == 0, "Incorrect parameter. Did you swap 'thickness' and 'flags'?"); // Or misuse of legacy hard-coded ImDrawCornerFlags values if ((col & IM_COL32_A_MASK) == 0) return; From b2546a5c93090c70610046fe547b946ee3d8d986 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 13 May 2026 12:46:07 +0200 Subject: [PATCH 2/7] Comments on not needing to use ImDrawFlags_RoundCornersAll. --- docs/CHANGELOG.txt | 1 + imgui.h | 20 ++++++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 83f19a88a..e66a79ad5 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -64,6 +64,7 @@ Breaking Changes: The new order is also more convenient as `flags` are less frequently used than `thickness` in real code. - As a general policy in Dear ImGui, all our flags default to 0 so ImDrawFlags_None was likely written 0 in some call sites. - Consider adding `#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS` in your imconfig.h, even temporarily, to clean up legacy code. + - Reminder: you do NOT need to specify `ImDrawFlags_RoundCornersAll` for rounding, it is already the default! - DrawList: obsoleted `ImDrawCallback_ResetRenderState` in favor of using `ImGui::GetPlatformIO().DrawCallback_ResetRenderState`, which is part of our new standard draw callbacks. (#9378) Redirecting the earlier value into the later one when set, so both old and new code should work. diff --git a/imgui.h b/imgui.h index 9a21e003d..a978ab735 100644 --- a/imgui.h +++ b/imgui.h @@ -3245,19 +3245,23 @@ struct ImDrawListSplitter enum ImDrawFlags_ { ImDrawFlags_None = 0, - ImDrawFlags_RoundCornersTopLeft = 1 << 4, // AddRect(), AddRectFilled(), PathRect(): enable rounding top-left corner only (when rounding > 0.0f, we default to all corners). Was 0x01. - ImDrawFlags_RoundCornersTopRight = 1 << 5, // AddRect(), AddRectFilled(), PathRect(): enable rounding top-right corner only (when rounding > 0.0f, we default to all corners). Was 0x02. - ImDrawFlags_RoundCornersBottomLeft = 1 << 6, // AddRect(), AddRectFilled(), PathRect(): enable rounding bottom-left corner only (when rounding > 0.0f, we default to all corners). Was 0x04. - ImDrawFlags_RoundCornersBottomRight = 1 << 7, // AddRect(), AddRectFilled(), PathRect(): enable rounding bottom-right corner only (when rounding > 0.0f, we default to all corners). Wax 0x08. - ImDrawFlags_RoundCornersNone = 1 << 8, // AddRect(), AddRectFilled(), PathRect(): disable rounding on all corners (when rounding > 0.0f). This is NOT zero, NOT an implicit flag! - ImDrawFlags_Closed = 1 << 9, // PathStroke(), AddPolyline(): specify that shape should be closed (Important: this is always == 1 for legacy reason) + + // Rounding for AddRect(), AddRectFilled(), PathRect() + // - When not specified, we defaults to ImDrawFlags_RoundCornersAll! So you only need to use those flags if you want another configuration. + ImDrawFlags_RoundCornersTopLeft = 1 << 4, // Round top-left corner only (when rounding > 0.0f, we default to all corners). + ImDrawFlags_RoundCornersTopRight = 1 << 5, // Round top-right corner only (when rounding > 0.0f, we default to all corners). + ImDrawFlags_RoundCornersBottomLeft = 1 << 6, // Round bottom-left corner only (when rounding > 0.0f, we default to all corners). + ImDrawFlags_RoundCornersBottomRight = 1 << 7, // Round bottom-right corner only (when rounding > 0.0f, we default to all corners). + ImDrawFlags_RoundCornersNone = 1 << 8, // Disable rounding even if `float rounding > 0.0f`. This is NOT zero, NOT an implicit flag! + ImDrawFlags_RoundCornersAll = ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight | ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersBottomRight, // (Default!!) + ImDrawFlags_RoundCornersDefault_ = ImDrawFlags_RoundCornersAll, // Default to ALL corners if none of the _RoundCornersXX flags are specified! ImDrawFlags_RoundCornersTop = ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight, ImDrawFlags_RoundCornersBottom = ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersBottomRight, ImDrawFlags_RoundCornersLeft = ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersTopLeft, ImDrawFlags_RoundCornersRight = ImDrawFlags_RoundCornersBottomRight | ImDrawFlags_RoundCornersTopRight, - ImDrawFlags_RoundCornersAll = ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight | ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersBottomRight, - ImDrawFlags_RoundCornersDefault_ = ImDrawFlags_RoundCornersAll, // Default to ALL corners if none of the _RoundCornersXX flags are specified. ImDrawFlags_RoundCornersMask_ = ImDrawFlags_RoundCornersAll | ImDrawFlags_RoundCornersNone, + + ImDrawFlags_Closed = 1 << 9, // PathStroke(), AddPolyline(): specify that shape should be closed. ImDrawFlags_InvalidMask_ = (ImDrawFlags)0x8000000F, }; From 310c719a1fb6fce7c117f84aaa1075c2d9b20b35 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 15 May 2026 10:48:24 +0200 Subject: [PATCH 3/7] Rework definition of ImDrawFlags_InvalidMask_ so it more strictly fits in an int32 for non C/C++ languages where it matters. (#9396, #9397) --- imgui.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.h b/imgui.h index a978ab735..3b7cde0fa 100644 --- a/imgui.h +++ b/imgui.h @@ -3262,7 +3262,7 @@ enum ImDrawFlags_ ImDrawFlags_RoundCornersMask_ = ImDrawFlags_RoundCornersAll | ImDrawFlags_RoundCornersNone, ImDrawFlags_Closed = 1 << 9, // PathStroke(), AddPolyline(): specify that shape should be closed. - ImDrawFlags_InvalidMask_ = (ImDrawFlags)0x8000000F, + ImDrawFlags_InvalidMask_ = ~0x7FFFFFF0, // == 0x8000000F, }; // Flags for ImDrawList instance. Those are set automatically by ImGui:: functions from ImGuiIO settings, and generally not manipulated directly. From c7767926ce2bc4b6520d43849ee66f4baff68454 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 15 May 2026 11:31:46 +0200 Subject: [PATCH 4/7] Version 1.92.9 WIP --- docs/CHANGELOG.txt | 9 +++++++++ imgui.cpp | 2 +- imgui.h | 4 ++-- imgui_demo.cpp | 2 +- imgui_draw.cpp | 2 +- imgui_internal.h | 2 +- imgui_tables.cpp | 2 +- imgui_widgets.cpp | 2 +- 8 files changed, 17 insertions(+), 8 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index e66a79ad5..e13e2c319 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -35,6 +35,15 @@ HOW TO UPDATE? and API updates have been a little more frequent lately. They are documented below and in imgui.cpp and should not affect all users. - Please report any issue! +----------------------------------------------------------------------- + VERSION 1.92.9 WIP (In Progress) +----------------------------------------------------------------------- + +Breaking Changes: + +Other Changes: + + ----------------------------------------------------------------------- VERSION 1.92.8 (Released 2026-05-12) ----------------------------------------------------------------------- diff --git a/imgui.cpp b/imgui.cpp index 2edb22be2..04eea7f24 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.92.8 +// dear imgui, v1.92.9 WIP // (main code and documentation) // Help: diff --git a/imgui.h b/imgui.h index 3b7cde0fa..816642ed2 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.92.8 +// dear imgui, v1.92.9 WIP // (headers) // Help: @@ -29,7 +29,7 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') -#define IMGUI_VERSION "1.92.8" +#define IMGUI_VERSION "1.92.9 WIP" #define IMGUI_VERSION_NUM 19281 #define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000 #define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198 diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 7d882f803..b95dd8a2b 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.92.8 +// dear imgui, v1.92.9 WIP // (demo code) // Help: diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 4cc709514..d3041d5f9 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.92.8 +// dear imgui, v1.92.9 WIP // (drawing and font code) /* diff --git a/imgui_internal.h b/imgui_internal.h index d66b6a9db..b2d8c974a 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.92.8 +// dear imgui, v1.92.9 WIP // (internal structures/api) // You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility. diff --git a/imgui_tables.cpp b/imgui_tables.cpp index 135410a0d..98dd7baad 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.92.8 +// dear imgui, v1.92.9 WIP // (tables and columns code) /* diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index ea792f9e8..55b9e4cd8 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.92.8 +// dear imgui, v1.92.9 WIP // (widgets code) /* From 46a050fff2d9290803a1838ad64815e306eb89f0 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 15 May 2026 13:38:32 +0200 Subject: [PATCH 5/7] Nav: minor optimization NavUpdate(). To be honest this is mostly to ease debug stepping in the common case. --- imgui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 04eea7f24..01067abe7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -13797,13 +13797,13 @@ static void ImGui::NavUpdate() // FIXME-NAV: Now that keys are separated maybe we can get rid of NavInputSource? const bool nav_gamepad_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (io.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0; const ImGuiKey nav_gamepad_keys_to_change_source[] = { ImGuiKey_GamepadFaceRight, ImGuiKey_GamepadFaceLeft, ImGuiKey_GamepadFaceUp, ImGuiKey_GamepadFaceDown, ImGuiKey_GamepadDpadRight, ImGuiKey_GamepadDpadLeft, ImGuiKey_GamepadDpadUp, ImGuiKey_GamepadDpadDown }; - if (nav_gamepad_active) + if (nav_gamepad_active && g.NavInputSource != ImGuiInputSource_Gamepad) for (ImGuiKey key : nav_gamepad_keys_to_change_source) if (IsKeyDown(key)) g.NavInputSource = ImGuiInputSource_Gamepad; const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0; const ImGuiKey nav_keyboard_keys_to_change_source[] = { ImGuiKey_Space, ImGuiKey_Enter, ImGuiKey_Escape, ImGuiKey_RightArrow, ImGuiKey_LeftArrow, ImGuiKey_UpArrow, ImGuiKey_DownArrow }; - if (nav_keyboard_active) + if (nav_keyboard_active && g.NavInputSource != ImGuiInputSource_Keyboard) for (ImGuiKey key : nav_keyboard_keys_to_change_source) if (IsKeyDown(key)) g.NavInputSource = ImGuiInputSource_Keyboard; From 4088a4f40c25f143bddac3393a1f922426b379f5 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 15 May 2026 13:33:51 +0200 Subject: [PATCH 6/7] Windows: clicking on a window's empty-space to move/focus a window checks for lack of mouse button ownership. (#9382) --- docs/CHANGELOG.txt | 5 +++++ imgui.cpp | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index e13e2c319..c69f33f3c 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -43,6 +43,11 @@ Breaking Changes: Other Changes: +- Windows: + - Clicking on a window's empty-space to move/focus a window checks + for lack of mouse button ownership. This gives an additional opportunity + for user code to bypass it without using a clickable item. (#9382) + ----------------------------------------------------------------------- VERSION 1.92.8 (Released 2026-05-12) diff --git a/imgui.cpp b/imgui.cpp index 01067abe7..a9677390f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5357,7 +5357,7 @@ void ImGui::UpdateMouseMovingWindowEndFrame() // Click on empty space to focus window and start moving // (after we're done with all our widgets) - if (g.IO.MouseClicked[0]) + if (IsMouseClicked(0, ImGuiInputFlags_None, ImGuiKeyOwner_NoOwner)) { // Handle the edge case of a popup being closed while clicking in its empty space. // If we try to focus it, FocusWindow() > ClosePopupsOverWindow() will accidentally close any parent popups because they are not linked together any more. @@ -5395,7 +5395,7 @@ void ImGui::UpdateMouseMovingWindowEndFrame() // With right mouse button we close popups without changing focus based on where the mouse is aimed // Instead, focus will be restored to the window under the bottom-most closed popup. // (The left mouse button path calls FocusWindow on the hovered window, which will lead NewFrame->ClosePopupsOverWindow to trigger) - if (g.IO.MouseClicked[1] && g.HoveredId == 0) + if (g.HoveredId == 0 && IsMouseClicked(1, ImGuiInputFlags_None, ImGuiKeyOwner_NoOwner)) { // Find the top-most window between HoveredWindow and the top-most Modal Window. // This is where we can trim the popup stack. From db161b84c9866ac29ea67608a45aa9385584a8eb Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 15 May 2026 13:45:03 +0200 Subject: [PATCH 7/7] Windows: clicking on a window's empty-space to move/focus a window checks for lack of queued focus request. (#9382) --- docs/CHANGELOG.txt | 2 ++ imgui.cpp | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index c69f33f3c..abea19dc9 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -47,6 +47,8 @@ Other Changes: - Clicking on a window's empty-space to move/focus a window checks for lack of mouse button ownership. This gives an additional opportunity for user code to bypass it without using a clickable item. (#9382) + - Clicking on a window's empty-space to move/focus a window checks + for lack of queued focus request. (#9382) ----------------------------------------------------------------------- diff --git a/imgui.cpp b/imgui.cpp index a9677390f..c7557c8b9 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5363,8 +5363,9 @@ void ImGui::UpdateMouseMovingWindowEndFrame() // If we try to focus it, FocusWindow() > ClosePopupsOverWindow() will accidentally close any parent popups because they are not linked together any more. ImGuiWindow* hovered_root = hovered_window ? hovered_window->RootWindow : NULL; const bool is_closed_popup = hovered_root && (hovered_root->Flags & ImGuiWindowFlags_Popup) && !IsPopupOpen(hovered_root->PopupId, ImGuiPopupFlags_AnyPopupLevel); + const bool is_queued_focus_request = g.NavMoveSubmitted && (g.NavMoveFlags & ImGuiNavMoveFlags_FocusApi); - if (hovered_window != NULL && !is_closed_popup) + if (hovered_window != NULL && !is_closed_popup && !is_queued_focus_request) { StartMouseMovingWindow(hovered_window); //-V595