Merge branch 'ocornut:master' into master

This commit is contained in:
Turtle Dove 2026-07-25 00:15:12 -05:00 committed by GitHub
commit 0d9df9426a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 108 additions and 66 deletions

View File

@ -47,7 +47,14 @@ Breaking Changes:
of directly poking to io.ConfigColorEditFlags. More consistent and easier to discover.
- Drag and Drop: commented out legacy name `ImGuiDragDropFlags_SourceAutoExpirePayload`
which obsoleted in 1.90.9 (July 2024). Use `ImGuiDragDropFlags_PayloadAutoExpire`.
- DragXXX, SliderXXX, InputScalar: with `ImGuiItemFlags_LiveEditOnInputScalar` now
defaulting to being disabled: inputting a value with the keyboard doesn't write
intermediate values to the backing variable. (#9476)
Before: DragFloat() with user typing "123" --> write back 1, then 12, then 123.
After: DragFloat() with user typing "123" --> write back 123 when validated/unfocused.
You can enable the flag back for a given scope if needed by specific widget/behavior.
- ImDrawData: marked `CmdListsCount` as obsolete (technically was obsoleted in 1.89.8).
Before: `draw_data->CmdListsCount`, After: `draw_data->CmdLists.Size`.
Other Changes:
@ -63,9 +70,13 @@ Other Changes:
- Added `ImGuiItemFlags_LiveEditOnInputText` and `ImGuiItemFlags_LiveEditOnInputScalar`
flags to configure the timing of applying edits of backing variables when typing
values using a keyboard.
(#701, #9476, #3936, #3946, #5904, #6284, #8149, #8065, #8665, #9117, #9299, #700, #1351,
(#9476, #701, #3936, #3946, #5904, #6284, #8149, #8065, #8665, #9117, #9299, #700, #1351,
#1875, #2060, #2215, #2380, #2550, #3083, #3338, #3556, #4373, #4714, #4885, #5184,
#5777, #6707, #6766, #8004, #8303, #8915, #9308)
- ImGuiItemFlags_LiveEditOnInputText is enabled by default (same as before):
- The expectation is that for strings/text, enabling LiveEdit is a better default.
- ImGuiItemFlags_LiveEditOnInputScalar is disabled by default (new behavior):
- The expectation is that for numeric/scalars values, disabling LiveEdit is a better default.
- Until now:
- Edits where always applied immediately to backing variable, which is equivalent
to the `ImGuiItemFlags_LiveEditXXX` flags being enabled.
@ -76,29 +87,29 @@ Other Changes:
Workarounds often required a backing store for scalar values, and there were
also a few niggles related to `IsItemDeactivatedAfterEdit()` when using +/-
buttons of an `InputInt()` widgets.
Many of those situations can now be naturally simplified by disabling
`ImGuiItemFlags_LiveEditOnInputScalar`, which is expected to become the default.
- Many of those situations can now be naturally simplified when disabling
`ImGuiItemFlags_LiveEditOnInputScalar` is disabled.
- The new flags allows disabling this behavior selectively for strings fields
such as `InputText()` vs scalar fields: `SliderInt()`, `InputFloat()`, etc.
- When LiveEdit is disabled, edits are applied when pressing enter, tabbing out,
clearing a field or deactivating due to a focus loss.
- The flag may be altered programmatically:
PushItemFlag(ImGuiItemFlags_LiveEditOnInputScalar, false); // Disable for scalars
- The flag may be altered programmatically, e.g. for the entire frame scope:
NewFrame();
PushItemFlag(ImGuiItemFlags_LiveEditOnInputScalar, true); // Enable for scalars for the whole frame
....
PopItemFlag();
EndFrame();
Or for a specific widget:
PushItemFlag(ImGuiItemFlags_LiveEditOnInput, true); // Enable for one widget
SliderInt(...);
PopItemFlag();
PushItemFlag(ImGuiItemFlags_LiveEditOnInput, true); // Enable for all
SliderInt(...);
PopItemFlag();
But with upcoming new defaults it is expected you shouldn't touch them much.
- Both flags currently defaults to true, which matches previous behavior.
- The expectation is that for strings/text, enabling LiveEdit is a better default.
- The expectation is that for scalars, disable LiveEdit is a better default.
- The short-term intent is to change `ImGuiItemFlags_LiveEditOnInputScalar` to
default to being disabled, as soon as we get more feedback from users (SOON).
- We intentionally are not adding `io.ConfigLiveEditXXX` fields to dictate the
default value of each `ImGuiItemFlags_LiveEditXXX`, because this is not
expected to be a user preference but a programmer/widget preferences.
default value of each `ImGuiItemFlags_LiveEditXXX`, because this is not expected
to be a user preference but a programmer/widget preferences.
Also, we strive to make the toolkit consistent.
- Popups:
- Added bool return value to `OpenPopup()`, `OpenPopupOnItemClick()` functions
to notify when the popup was just opened. (#9429)
- InputText:
- Added `style.InputTextCursorSize` to configure cursor/caret thickness. (#7031, #9409)
This is automatically scaled by `style.ScaleAllSizes()`.
@ -123,7 +134,7 @@ Other Changes:
- Headers: fixed label being clipped early to reserve space for a sort marker
even when no sort marker is displayed. Auto-fitting a column still accounts
for the possible marker, so that sorting after an auto-fit doesn't clip the label.
- Multi-Select
- Multi-Select:
- Reworked ImGuiMultiSelectFlags_NoAutoSelect as it carried side-effects that
were hardcoded/designed to use multi-selection on checkboxes. (#9391)
Specifically removed those undocumented behaviors from _NoAutoSelect:
@ -3549,8 +3560,10 @@ Breaking changes:
input queue. This is automatically cleared by io.ClearInputKeys(). (#4921)
- ImDrawData: CmdLists[] array is now owned, changed from 'ImDrawList**' to
'ImVector<ImDrawList*>'. Majority of users shouldn't be affected, but you
cannot compare to NULL nor reassign manually anymore.
Instead use AddDrawList(). Allocation count are identical. (#6406, #4879, #1878)
cannot compare to NULL nor reassign manually anymore. (#6406, #4879, #1878)
- Allocation count are identical.
- Use `draw_data->CmdLists.Size` instead of `draw_list->CmdListsCount`!
- Use `AddDrawList()` to add to a `ImDrawData`.
Other changes:

View File

@ -85,16 +85,17 @@ Here's a very simplified comparison between the approach taken by Dear ImGui vs
|--------------------------|--------------------------|
| UI fully issued on every update. | UI issued once then later modified. |
| UI layout is fully dynamic and can change at any time.<BR>UI is generally emitted programmatically, which empowers reflecting a dynamic set of data. | UI layout is mostly static.<BR>UI may be emitted programmatically or from data created by offline tools. UI need extra code to evolve, which is often tedious and error-prone if it needs to be reflecting dynamic data and systems. |
| Application can submit UI based on arbitrary logic and then forget about it. | Application needs more bookkeeping of UI elements. |
| UI system is optimized for the worst case and designed to be optimal even under frequent changes. | UI system is optimized for the case where nothing changes. Performances tends to degrade when anything changes. |
| Application can submit UI based on arbitrary logic without bookkeeping all aspects of that logic. | Application needs more bookkeeping of UI elements. |
| UI library stores minimal amounts of data. At one point in time, it typically doesn't know or remember which other widgets are displayed and which widgets are coming next. As a result, certain layout features (alignment, resizing) are not as easy to implement or require ad-hoc code. | UI library stores entire widgets tree and state. UI library can use this retained data to easily layout things. |
| UI code may be added anywhere.<BR>You can even create UI to edit a local variable! | UI code needs to be added in dedicated spots. |
| UI layout/logic/action/data bindings are all nearby in the code. | UI layout/logic/action/data bindings in distinct functions, files or formats. |
| Data is naturally always synchronized. | Use callback/signal/slot for synchronizing data (error-prone). |
| API is simple and easy to learn. In particular, doing basic things is very easy. | API is more complex and specialized. |
| API is low-level (raw language types). | API are higher-level (more abstractions, advanced language features). |
| Less fancy look and feel. | Standard look and feel. |
| API is simple and easy to learn. In particular, doing basic things is very easy.<BR>Attractive to more programmers. | API is more complex and specialized.<BR>Tends to require specialized programmers. |
| API is low-level. Few abstractions, uses raw language types and your existing data. | API are higher-level. More abstractions, advanced language features. |
| Less fancy look and feel. But keeps improving :) | Standard look and feel. |
| Compile yourself. Easy to debug, hack, modify, study. | Mostly use precompiled libraries. Compiling, modifying or studying is daunting if not impossible. |
| Run on every platform. | Run on limited desktop platforms. |
| Run on every platform (incl. web, consoles, mobiles, legacy systems). | Run on major desktop platforms. |
Idiomatic Dear ImGui code:
```cpp

View File

@ -162,7 +162,7 @@ else() # Native/Desktop build
endif()
list(APPEND WGVK_PLATFORM_LIBS m dl pthread)
endif()
set(LIBRARIES glfw Vulkan::Vulkan ${WGVK_PLATFORM_LIBS})
set(LIBRARIES Vulkan::Vulkan ${WGVK_PLATFORM_LIBS})
endif()
endif()

View File

@ -162,7 +162,7 @@ else() # Native/Desktop build
endif()
list(APPEND WGVK_PLATFORM_LIBS m dl pthread)
endif()
set(LIBRARIES glfw Vulkan::Vulkan ${WGVK_PLATFORM_LIBS})
set(LIBRARIES Vulkan::Vulkan ${WGVK_PLATFORM_LIBS})
endif()
endif()

View File

@ -395,6 +395,14 @@ IMPLEMENTING SUPPORT for ImGuiBackendFlags_RendererHasTextures:
When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files.
You can read releases logs https://github.com/ocornut/imgui/releases for more details.
- 2026/07/20 (1.92.9) - DragXXX, SliderXXX, InputScalar: with `ImGuiItemFlags_LiveEditOnInputScalar` now defaulting to being disabled:
inputting a value with the keyboard doesn't write intermediate values to backing variable. (#9476)
- Before: DragFloat() with user typing "123" --> write back 1, then 12, then 123.
- After: DragFloat() with user typing "123" --> write back 123 when validated/unfocused.
You can enable the flag back for a given scope if needed by specific widget/behavior.
- 2026/07/20 (1.92.9) - ImDrawData: marked ImDrawData::CmdListsCount as obsolete (technically was obsoleted in 1.89.8).
- Before: draw_data->CmdListsCount
- After: draw_data->CmdLists.Size
- 2026/07/08 (1.92.9) - Drag and Drop: commented out legacy name `ImGuiDragDropFlags_SourceAutoExpirePayload` which obsoleted in 1.90.9 (July 2024). Use `ImGuiDragDropFlags_PayloadAutoExpire`.
- 2026/07/06 (1.92.9) - ColorEdit: obsoleted SetColorEditOptions() function added in 1.51 (June 2017) in favor of directly poking to io.ConfigColorEditFlags. More consistent and easier to discover.
- 2026/06/02 (1.92.9) - TreeNode: commented out legacy name ImGuiTreeNodeFlags_SpanTextWidth which was obsoleted in 1.90.7 (May 2024). Use ImGuiTreeNodeFlags_SpanLabelWidth instead.
@ -731,7 +739,9 @@ IMPLEMENTING SUPPORT for ImGuiBackendFlags_RendererHasTextures:
- ImDrawCornerFlags_XXX -> use ImDrawFlags_RoundCornersXXX flags. Read 1.82 Changelog for details + grep commented names in sources.
- commented out runtime support for hardcoded ~0 or 0x01..0x0F rounding flags values for AddRect()/AddRectFilled()/PathRect()/AddImageRounded() -> use ImDrawFlags_RoundCornersXXX flags. Read 1.82 Changelog for details
- 2023/08/25 (1.89.9) - clipper: Renamed IncludeRangeByIndices() (also called ForceDisplayRangeByIndices() before 1.89.6) to IncludeItemsByIndex(). Kept inline redirection function. Sorry!
- 2023/07/12 (1.89.8) - ImDrawData: CmdLists now owned, changed from ImDrawList** to ImVector<ImDrawList*>. Majority of users shouldn't be affected, but you cannot compare to NULL nor reassign manually anymore. Instead use AddDrawList(). (#6406, #4879, #1878)
- 2023/07/12 (1.89.8) - ImDrawData: CmdLists now owned, changed from ImDrawList** to ImVector<ImDrawList*>. Majority of users shouldn't be affected, but you cannot compare to NULL nor reassign manually anymore. (#6406, #4879, #1878)
- use `draw_data->CmdLists.Size` instead of `draw_list->CmdListsCount`.
- use `draw_data->AddDrawList()` to add to a ImDrawData.
- 2023/06/28 (1.89.7) - overlapping items: obsoleted 'SetItemAllowOverlap()' (called after item) in favor of calling 'SetNextItemAllowOverlap()' (called before item). 'SetItemAllowOverlap()' didn't and couldn't work reliably since 1.89 (2022-11-15).
- 2023/06/28 (1.89.7) - overlapping items: renamed 'ImGuiTreeNodeFlags_AllowItemOverlap' to 'ImGuiTreeNodeFlags_AllowOverlap', 'ImGuiSelectableFlags_AllowItemOverlap' to 'ImGuiSelectableFlags_AllowOverlap'. Kept redirecting enums (will obsolete).
- 2023/06/28 (1.89.7) - overlapping items: IsItemHovered() now by default return false when querying an item using AllowOverlap mode which is being overlapped. Use ImGuiHoveredFlags_AllowWhenOverlappedByItem to revert to old behavior.
@ -5944,7 +5954,7 @@ static void FlattenDrawDataIntoSingleLayer(ImDrawDataBuilder* builder)
static void InitViewportDrawData(ImGuiViewportP* viewport)
{
ImGuiIO& io = ImGui::GetIO();
ImGuiContext& g = *GImGui;
ImDrawData* draw_data = &viewport->DrawDataP;
viewport->DrawDataBuilder.Layers[0] = &draw_data->CmdLists;
@ -5953,13 +5963,16 @@ static void InitViewportDrawData(ImGuiViewportP* viewport)
viewport->DrawDataBuilder.Layers[1]->resize(0);
draw_data->Valid = true;
draw_data->CmdListsCount = 0;
draw_data->FrameCount = g.FrameCount;
draw_data->TotalVtxCount = draw_data->TotalIdxCount = 0;
draw_data->DisplayPos = viewport->Pos;
draw_data->DisplaySize = viewport->Size;
draw_data->FramebufferScale = io.DisplayFramebufferScale;
draw_data->FramebufferScale = g.IO.DisplayFramebufferScale;
draw_data->OwnerViewport = viewport;
draw_data->Textures = &ImGui::GetPlatformIO().Textures;
draw_data->Textures = &g.PlatformIO.Textures;
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
draw_data->CmdListsCount = 0;
#endif
}
// Push a clipping rectangle for both ImGui logic (hit-testing etc.) and low-level ImDrawList rendering.
@ -6227,7 +6240,6 @@ void ImGui::Render()
// We call _PopUnusedDrawCmd() last thing, as RenderDimmedBackgrounds() rely on a valid command being there (especially in docking branch).
ImDrawData* draw_data = &viewport->DrawDataP;
IM_ASSERT(draw_data->CmdLists.Size == draw_data->CmdListsCount);
for (ImDrawList* draw_list : draw_data->CmdLists)
draw_list->_PopUnusedDrawCmd();
@ -11520,7 +11532,7 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
*p_highlight = g.FrameCount;
*p_alive = g.FrameCount;
if (*p_highlight >= g.FrameCount - 1)
window->DrawList->AddRect(bb.Min - ImVec2(1, 1), bb.Max + ImVec2(1, 1), IM_COL32(255, 0, 0, 255), 0.0f, ImDrawFlags_None, 2.0f);
window->DrawList->AddRect(bb.Min - ImVec2(1, 1), bb.Max + ImVec2(1, 1), IM_COL32(255, 0, 0, 255), 0.0f, 2.0f);
}
#endif
}
@ -12418,24 +12430,26 @@ ImGuiWindow* ImGui::FindBlockingModal(ImGuiWindow* window)
return NULL;
}
void ImGui::OpenPopup(const char* str_id, ImGuiPopupFlags popup_flags)
bool ImGui::OpenPopup(const char* str_id, ImGuiPopupFlags popup_flags)
{
ImGuiContext& g = *GImGui;
ImGuiID id = g.CurrentWindow->GetID(str_id);
IMGUI_DEBUG_LOG_POPUP("[popup] OpenPopup(\"%s\" -> 0x%08X)\n", str_id, id);
OpenPopupEx(id, popup_flags);
return OpenPopupEx(id, popup_flags);
}
void ImGui::OpenPopup(ImGuiID id, ImGuiPopupFlags popup_flags)
bool ImGui::OpenPopup(ImGuiID id, ImGuiPopupFlags popup_flags)
{
OpenPopupEx(id, popup_flags);
return OpenPopupEx(id, popup_flags);
}
// Mark popup as open (toggle toward open state).
// Popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block.
// Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level).
// One open popup per level of the popup hierarchy (NB: when assigning we reset the Window member of ImGuiPopupRef to NULL)
void ImGui::OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags)
// - Return true when the popup is toggled open, which allows you to capture local state if needed.
// You may also call IsWindowAppearing() inside the later BeginPopup() scope if you need to prepare/compute data for the popup.
// - Popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block.
// - Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level).
// - One open popup per level of the popup hierarchy (NB: when assigning we reset the Window member of ImGuiPopupRef to NULL).
bool ImGui::OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* parent_window = g.CurrentWindow;
@ -12443,7 +12457,7 @@ void ImGui::OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags)
if (popup_flags & ImGuiPopupFlags_NoOpenOverExistingPopup)
if (IsPopupOpen((ImGuiID)0, ImGuiPopupFlags_AnyPopupId))
return;
return false;
ImGuiPopupData popup_ref; // Tagged as new ref as Window will be set back to NULL if we write this into OpenPopupStack.
popup_ref.PopupId = id;
@ -12458,6 +12472,7 @@ void ImGui::OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags)
if (g.OpenPopupStack.Size < current_stack_size + 1)
{
g.OpenPopupStack.push_back(popup_ref);
return true;
}
else
{
@ -12485,6 +12500,8 @@ void ImGui::OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags)
// This is equivalent to what ClosePopupToLevel() does.
//if (g.OpenPopupStack[current_stack_size].PopupId == id)
// FocusWindow(parent_window);
return !keep_existing;
}
}
@ -12769,16 +12786,17 @@ bool ImGui::IsPopupOpenRequestForWindow(ImGuiPopupFlags popup_flags)
// Helper to open a popup if mouse button is released over the item
// - This is essentially the same as BeginPopupContextItem() but without the trailing BeginPopup()
void ImGui::OpenPopupOnItemClick(const char* str_id, ImGuiPopupFlags popup_flags)
bool ImGui::OpenPopupOnItemClick(const char* str_id, ImGuiPopupFlags popup_flags)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
if (IsPopupOpenRequestForItem(popup_flags, g.LastItemData.ID))
{
ImGuiWindow* window = g.CurrentWindow;
ImGuiID id = str_id ? window->GetID(str_id) : g.LastItemData.ID; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict!
IM_ASSERT(id != 0); // You cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item)
OpenPopupEx(id, popup_flags);
return OpenPopupEx(id, popup_flags);
}
return false;
}
// This is a helper to handle the simplest case of associating one named popup to one given widget.

33
imgui.h
View File

@ -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.9 WIP"
#define IMGUI_VERSION_NUM 19286
#define IMGUI_VERSION_NUM 19287
#define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000
#define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198
@ -850,15 +850,17 @@ namespace ImGui
IMGUI_API void EndPopup(); // only call EndPopup() if BeginPopupXXX() returns true!
// Popups: open/close functions
// - OpenPopup(): set popup state to open. ImGuiPopupFlags are available for opening options.
// - OpenPopup(): set popup state to open (unless one of the specified ImGuiPopupFlags prevent opening).
// - OpenPopupXXX() functions return true when the popup is toggled open, which allows you to capture local state if needed.
// You may also call IsWindowAppearing() inside the later BeginPopup() scope if you need to prepare/compute data for the popup.
// - If not modal: they can be closed by clicking anywhere outside them, or by pressing ESCAPE.
// - CloseCurrentPopup(): use inside the BeginPopup()/EndPopup() scope to close manually.
// - CloseCurrentPopup() is called by default by Selectable()/MenuItem() when activated (FIXME: need some options).
// - Use ImGuiPopupFlags_NoOpenOverExistingPopup to avoid opening a popup if there's already one at the same level. This is equivalent to e.g. testing for !IsAnyPopupOpen() prior to OpenPopup().
// - Use IsWindowAppearing() after BeginPopup() to tell if a window just opened.
IMGUI_API void OpenPopup(const char* str_id, ImGuiPopupFlags popup_flags = 0); // call to mark popup as open (don't call every frame!).
IMGUI_API void OpenPopup(ImGuiID id, ImGuiPopupFlags popup_flags = 0); // id overload to facilitate calling from nested stacks
IMGUI_API void OpenPopupOnItemClick(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 0); // helper to open popup when clicked on last item. Default to ImGuiPopupFlags_MouseButtonRight == 1. (note: actually triggers on the mouse _released_ event to be consistent with popup behaviors)
IMGUI_API bool OpenPopup(const char* str_id, ImGuiPopupFlags popup_flags = 0); // call to mark popup as open (don't call every frame!).
IMGUI_API bool OpenPopup(ImGuiID id, ImGuiPopupFlags popup_flags = 0); // id overload to facilitate calling from nested stacks
IMGUI_API bool OpenPopupOnItemClick(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 0); // helper to open popup when clicked on last item. Default to ImGuiPopupFlags_MouseButtonRight == 1. (note: actually triggers on the mouse _released_ event to be consistent with popup behaviors)
IMGUI_API void CloseCurrentPopup(); // manually close the popup we have begin-ed into.
// Popups: Open+Begin popup combined functions helpers to create context menus.
@ -1248,18 +1250,16 @@ enum ImGuiItemFlags_
ImGuiItemFlags_Disabled = 1 << 6, // false // [Internal] Disable interactions. DOES NOT affect visuals. This is used by BeginDisabled()/EndDisabled() and only provided here so you can read back via GetItemFlags().
//---------------------------------------------------------------------------------
// LiveEdit refers to applying edits to backing variables _while_ typing.
// LiveEdit refers to applying edits to backing variables _while_ typing a value using the keyboard.
// Widget: | Input: | w/ LiveEdit: | Output:
// InputText() | "123" | on(default) | "1" then "12" then "123"
// InputText() | "123" | off | "123" after validating or tabbing out or losing focus.
// DragFloat(), SliderInt(), etc. | "123" | on(default)* | 1 then 12 then 123
// DragFloat(), SliderInt(), etc. | "123" | off* | 123 after validation or tabbing out or losing focus.
//---------------------------------------------------------------------------------
// (*) The feature is currently being evaluated, and the aim is to change ImGuiItemFlags_LiveEditOnInputScalar to OFF by default.
// The legacy behavior until July 2026 was that LiveEdit was always ON for everything.
// DragFloat(), SliderInt(), etc. | "123" | on* | 1 then 12 then 123
// DragFloat(), SliderInt(), etc. | "123" | off(default)* | 123 after validation or tabbing out or losing focus.
// (*) Since 1.92.9 (July 2026), ImGuiItemFlags_LiveEditOnInputScalar is OFF by default. In prior version it was ON for everything.
//---------------------------------------------------------------------------------
ImGuiItemFlags_LiveEditOnInputText = 1 << 7, // true // InputText: apply keyboard edits to backing value while typing. Otherwise, edits are applied when validating, tabbing out or losing focus.
ImGuiItemFlags_LiveEditOnInputScalar = 1 << 8, // true* // DragXXX, SliderXXX, InputScalar: apply keyboard edits to backing value while typing. Otherwise, edits are applied when validating, tabbing out or losing focus.
ImGuiItemFlags_LiveEditOnInputScalar = 1 << 8, // false // DragXXX, SliderXXX, InputScalar: apply keyboard edits to backing value while typing. Otherwise, edits are applied when validating, tabbing out or losing focus.
ImGuiItemFlags_LiveEditOnInput = ImGuiItemFlags_LiveEditOnInputText | ImGuiItemFlags_LiveEditOnInputScalar,
};
@ -3495,7 +3495,7 @@ struct ImDrawList
struct ImDrawData
{
bool Valid; // Only valid after Render() is called and before the next NewFrame() is called.
int CmdListsCount; // == CmdLists.Size. (OBSOLETE: exists for legacy reasons). Number of ImDrawList* to render.
int FrameCount; // Frame counter of the emitter context. Mostly for debugging purpose.
int TotalIdxCount; // For convenience, sum of all ImDrawList's IdxBuffer.Size
int TotalVtxCount; // For convenience, sum of all ImDrawList's VtxBuffer.Size
ImVector<ImDrawList*> CmdLists; // Array of ImDrawList* to render. The ImDrawLists are owned by ImGuiContext and only pointed to from here.
@ -3505,6 +3505,10 @@ struct ImDrawData
ImGuiViewport* OwnerViewport; // Viewport carrying the ImDrawData instance, might be of use to the renderer (generally not).
ImVector<ImTextureData*>* Textures; // List of textures to update. Most of the times the list is shared by all ImDrawData, has only 1 texture and it doesn't need any update. This almost always points to ImGui::GetPlatformIO().Textures[]. May be overridden or set to NULL if you want to manually update textures.
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
int CmdListsCount; // Use CmdLists.Size instead. Number of ImDrawList* to render.
#endif
// Functions
ImDrawData() { Clear(); }
IMGUI_API void Clear();
@ -3556,13 +3560,14 @@ struct ImTextureRect
// Why does we store two identifiers: TexID and BackendUserData?
// - ImTextureID TexID = lower-level identifier stored in ImDrawCmd. ImDrawCmd can refer to textures not created by the backend, and for which there's no ImTextureData.
// - void* BackendUserData = higher-level opaque storage for backend own book-keeping. Some backends may have enough with TexID and not need both.
// In columns below: who reads/writes each fields? 'r'=read, 'w'=write, 'core'=main library, 'backend'=renderer backend
// In columns below: who reads/writes each fields? 'r'=read, 'w'=write, 'core'=main library, 'backend'=renderer backend
struct ImTextureData
{
//------------------------------------------ core / backend ---------------------------------------
int UniqueID; // w - // [DEBUG] Sequential index to facilitate identifying a texture when debugging/printing. Unique per atlas.
ImTextureStatus Status; // rw rw // ImTextureStatus_OK/_WantCreate/_WantUpdates/_WantDestroy. Always use SetStatus() to modify!
void* BackendUserData; // - rw // Convenience storage for backend. Some backends may have enough with TexID.
void* QueueUserData; // r - // Convenience storage for a staged/multi-threaded rendering texture queue (e.g. imgui_threaded_rendering.h. See #8597). When != NULL, core assumes the texture is referenced by the queue.
ImTextureID TexID; // r w // Backend-specific texture identifier. Always use SetTexID() to modify! The identifier will stored in ImDrawCmd::GetTexID() and passed to backend's RenderDrawData function.
ImTextureFormat Format; // w r // ImTextureFormat_RGBA32 (default) or ImTextureFormat_Alpha8
int Width; // w r // Texture width

View File

@ -2280,11 +2280,14 @@ void ImDrawListSplitter::SetCurrentChannel(ImDrawList* draw_list, int idx)
void ImDrawData::Clear()
{
Valid = false;
CmdListsCount = TotalIdxCount = TotalVtxCount = 0;
FrameCount = TotalIdxCount = TotalVtxCount = 0;
CmdLists.resize(0); // The ImDrawList are NOT owned by ImDrawData but e.g. by ImGuiContext, so we don't clear them.
DisplayPos = DisplaySize = FramebufferScale = ImVec2(0.0f, 0.0f);
OwnerViewport = NULL;
Textures = NULL;
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
CmdListsCount = 0;
#endif
}
// Important: 'out_list' is generally going to be draw_data->CmdLists, but may be another temporary list
@ -2329,16 +2332,17 @@ void ImGui::AddDrawListToDrawDataEx(ImDrawData* draw_data, ImVector<ImDrawList*>
// Add to output list + records state in ImDrawData
out_list->push_back(draw_list);
draw_data->CmdListsCount++;
draw_data->TotalVtxCount += draw_list->VtxBuffer.Size;
draw_data->TotalIdxCount += draw_list->IdxBuffer.Size;
}
void ImDrawData::AddDrawList(ImDrawList* draw_list)
{
IM_ASSERT(CmdLists.Size == CmdListsCount);
draw_list->_PopUnusedDrawCmd();
ImGui::AddDrawListToDrawDataEx(this, &CmdLists, draw_list);
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
CmdListsCount = CmdLists.Size;
#endif
}
// For backward compatibility: convert all buffers from indexed to de-indexed, in case you cannot render indexed. Note: this is slow and most likely a waste of resources. Always prefer indexed rendering!
@ -2862,13 +2866,14 @@ bool ImTextureDataUpdateNewFrame(ImTextureData* tex)
// If a texture has never reached the backend, they don't need to know about it.
// (note: backends between 1.92.0 and 1.92.4 could set an already destroyed texture to ImTextureStatus_WantDestroy
// when invalidating graphics objects twice, which would previously remove it from the list and crash.)
if (tex->Status == ImTextureStatus_WantDestroy && tex->TexID == ImTextureID_Invalid && tex->BackendUserData == NULL)
if (tex->Status == ImTextureStatus_WantDestroy && tex->TexID == ImTextureID_Invalid && tex->BackendUserData == NULL && tex->QueueUserData == NULL)
tex->Status = ImTextureStatus_Destroyed;
// Process texture being destroyed
if (tex->Status == ImTextureStatus_Destroyed)
{
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == NULL && "Backend set texture Status to Destroyed but did not clear TexID/BackendUserData!");
IM_ASSERT(tex->QueueUserData == NULL && "Texture queue set Status to Destroyed but did not clear QueueUserData!");
if (tex->WantDestroyNextFrame)
remove_from_list = true; // Destroy was scheduled by us
else

View File

@ -1006,7 +1006,7 @@ enum ImGuiItemFlagsPrivate_
ImGuiItemFlags_HasSelectionUserData = 1 << 21, // false // Set by SetNextItemSelectionUserData()
ImGuiItemFlags_IsMultiSelect = 1 << 22, // false // Set by SetNextItemSelectionUserData()
ImGuiItemFlags_Default_ = ImGuiItemFlags_AutoClosePopups | ImGuiItemFlags_LiveEditOnInputText | ImGuiItemFlags_LiveEditOnInputScalar, // Please don't change, use PushItemFlag() instead.
ImGuiItemFlags_Default_ = ImGuiItemFlags_AutoClosePopups | ImGuiItemFlags_LiveEditOnInputText, // Please don't change, use PushItemFlag() instead.
// Obsolete
//ImGuiItemFlags_SelectableDontClosePopup = !ImGuiItemFlags_AutoClosePopups, // Can't have a redirect as we inverted the behavior
@ -3504,7 +3504,7 @@ namespace ImGui
// Popups, Modals
IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_window_flags);
IMGUI_API bool BeginPopupMenuEx(ImGuiID id, const char* label, ImGuiWindowFlags extra_window_flags);
IMGUI_API void OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags = ImGuiPopupFlags_None);
IMGUI_API bool OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags = ImGuiPopupFlags_None);
IMGUI_API void ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_popup);
IMGUI_API void ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to_window_under_popup);
IMGUI_API void ClosePopupsExceptModals();