Merge branch 'master' into docking

# Conflicts:
#	backends/imgui_impl_sdlgpu3.cpp
#	imgui.cpp
This commit is contained in:
ocornut
2025-08-08 15:51:56 +02:00
11 changed files with 111 additions and 64 deletions

View File

@@ -2,7 +2,7 @@
// This needs to be used along with the SDL3 Platform Backend
// Implemented features:
// [X] Renderer: User texture binding. Use simply cast a reference to your SDL_GPUTextureSamplerBinding to ImTextureID.
// [X] Renderer: User texture binding. Use 'SDL_GPUTexture*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef! **IMPORTANT** Before 2025/08/08, ImTextureID was a reference to a SDL_GPUTextureSamplerBinding struct.
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
@@ -24,6 +24,8 @@
// CHANGELOG
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2025-08-08: *BREAKING* Changed ImTextureID type from SDL_GPUTextureSamplerBinding* to SDL_GPUTexture*, which is more natural and easier for user to manage. If you need to change the current sampler, you can access the ImGui_ImplSDLGPU3_RenderState struct. (#8866, #8163, #7998, #7988)
// 2025-08-08: Expose SamplerDefault and SamplerCurrent in ImGui_ImplSDLGPU3_RenderState. Allow callback to change sampler.
// 2025-06-25: Mapping transfer buffer for texture update use cycle=true. Fixes artifacts e.g. on Metal backend.
// 2025-06-11: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas. Removed ImGui_ImplSDLGPU3_CreateFontsTexture() and ImGui_ImplSDLGPU3_DestroyFontsTexture().
// 2025-04-28: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
@@ -38,11 +40,6 @@
#include "imgui_impl_sdlgpu3_shaders.h"
// SDL_GPU Data
struct ImGui_ImplSDLGPU3_Texture
{
SDL_GPUTexture* Texture = nullptr;
SDL_GPUTextureSamplerBinding TextureSamplerBinding = { nullptr, nullptr };
};
// Reusable buffers used for rendering 1 current in-flight frame, for ImGui_ImplSDLGPU3_RenderDrawData()
struct ImGui_ImplSDLGPU3_FrameData
@@ -86,12 +83,13 @@ static ImGui_ImplSDLGPU3_Data* ImGui_ImplSDLGPU3_GetBackendData()
return ImGui::GetCurrentContext() ? (ImGui_ImplSDLGPU3_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
}
static void ImGui_ImplSDLGPU3_SetupRenderState(ImDrawData* draw_data, SDL_GPUGraphicsPipeline* pipeline, SDL_GPUCommandBuffer* command_buffer, SDL_GPURenderPass * render_pass, ImGui_ImplSDLGPU3_FrameData* fd, uint32_t fb_width, uint32_t fb_height)
static void ImGui_ImplSDLGPU3_SetupRenderState(ImDrawData* draw_data, ImGui_ImplSDLGPU3_RenderState* render_state, SDL_GPUGraphicsPipeline* pipeline, SDL_GPUCommandBuffer* command_buffer, SDL_GPURenderPass* render_pass, ImGui_ImplSDLGPU3_FrameData* fd, uint32_t fb_width, uint32_t fb_height)
{
//ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
render_state->SamplerCurrent = render_state->SamplerCurrent = bd->TexSampler;
// Bind graphics pipeline
SDL_BindGPUGraphicsPipeline(render_pass,pipeline);
SDL_BindGPUGraphicsPipeline(render_pass, pipeline);
// Bind Vertex And Index Buffers
if (draw_data->TotalVtxCount > 0)
@@ -229,12 +227,19 @@ void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffe
if (pipeline == nullptr)
pipeline = bd->Pipeline;
ImGui_ImplSDLGPU3_SetupRenderState(draw_data, pipeline, command_buffer, render_pass, fd, fb_width, fb_height);
// Will project scissor/clipping rectangles into framebuffer space
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
// Setup render state structure (for callbacks and custom texture bindings)
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
ImGui_ImplSDLGPU3_RenderState render_state;
render_state.Device = bd->InitInfo.Device;
render_state.SamplerDefault = render_state.SamplerCurrent = bd->TexSampler;
platform_io.Renderer_RenderState = &render_state;
ImGui_ImplSDLGPU3_SetupRenderState(draw_data, &render_state, pipeline, command_buffer, render_pass, fd, fb_width, fb_height);
// Render command lists
// (Because we merged all buffers into a single one, we maintain our own offset into them)
int global_vtx_offset = 0;
@@ -249,7 +254,7 @@ void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffe
// User callback, registered via ImDrawList::AddCallback()
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplSDLGPU3_SetupRenderState(draw_data, pipeline, command_buffer, render_pass, fd, fb_width, fb_height);
ImGui_ImplSDLGPU3_SetupRenderState(draw_data, &render_state, pipeline, command_buffer, render_pass, fd, fb_width, fb_height);
else
pcmd->UserCallback(draw_list, pcmd);
}
@@ -276,9 +281,14 @@ void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffe
SDL_SetGPUScissor(render_pass,&scissor_rect);
// Bind DescriptorSet with font or user texture
SDL_BindGPUFragmentSamplers(render_pass, 0, (SDL_GPUTextureSamplerBinding*)pcmd->GetTexID(), 1);
SDL_GPUTextureSamplerBinding texture_sampler_binding;
texture_sampler_binding.texture = (SDL_GPUTexture*)(intptr_t)pcmd->GetTexID();
texture_sampler_binding.sampler = render_state.SamplerCurrent;
SDL_BindGPUFragmentSamplers(render_pass, 0, &texture_sampler_binding, 1);
// Draw
// **IF YOU GET A CRASH HERE** In 1.92.2 on 2025/08/08 we have changed ImTextureID to store 'SDL_GPUTexture*' instead of storing 'SDL_GPUTextureSamplerBinding'.
// Any code loading custom texture using this backend needs to be updated.
SDL_DrawGPUIndexedPrimitives(render_pass, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
}
}
@@ -297,18 +307,13 @@ void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffe
static void ImGui_ImplSDLGPU3_DestroyTexture(ImTextureData* tex)
{
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
ImGui_ImplSDLGPU3_Texture* backend_tex = (ImGui_ImplSDLGPU3_Texture*)tex->BackendUserData;
if (backend_tex == nullptr)
return;
SDL_GPUTextureSamplerBinding* binding = (SDL_GPUTextureSamplerBinding*)(intptr_t)tex->BackendUserData;
IM_ASSERT(backend_tex->Texture == binding->texture);
SDL_ReleaseGPUTexture(bd->InitInfo.Device, backend_tex->Texture);
IM_DELETE(backend_tex);
SDL_GPUTexture* raw_tex = (SDL_GPUTexture*)(intptr_t)tex->GetTexID();
if (raw_tex != nullptr)
SDL_ReleaseGPUTexture(bd->InitInfo.Device, raw_tex);
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
tex->SetTexID(ImTextureID_Invalid);
tex->SetStatus(ImTextureStatus_Destroyed);
tex->BackendUserData = nullptr;
}
void ImGui_ImplSDLGPU3_UpdateTexture(ImTextureData* tex)
@@ -322,7 +327,6 @@ void ImGui_ImplSDLGPU3_UpdateTexture(ImTextureData* tex)
//IMGUI_DEBUG_LOG("UpdateTexture #%03d: WantCreate %dx%d\n", tex->UniqueID, tex->Width, tex->Height);
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == nullptr);
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
ImGui_ImplSDLGPU3_Texture* backend_tex = IM_NEW(ImGui_ImplSDLGPU3_Texture)();
// Create texture
SDL_GPUTextureCreateInfo texture_info = {};
@@ -335,19 +339,16 @@ void ImGui_ImplSDLGPU3_UpdateTexture(ImTextureData* tex)
texture_info.num_levels = 1;
texture_info.sample_count = SDL_GPU_SAMPLECOUNT_1;
backend_tex->Texture = SDL_CreateGPUTexture(v->Device, &texture_info);
backend_tex->TextureSamplerBinding.texture = backend_tex->Texture;
backend_tex->TextureSamplerBinding.sampler = bd->TexSampler;
IM_ASSERT(backend_tex->Texture && "Failed to create font texture, call SDL_GetError() for more info");
SDL_GPUTexture* raw_tex = SDL_CreateGPUTexture(v->Device, &texture_info);
IM_ASSERT(raw_tex != nullptr && "Failed to create font texture, call SDL_GetError() for more info");
// Store identifiers
tex->SetTexID((ImTextureID)(intptr_t)&backend_tex->TextureSamplerBinding);
tex->BackendUserData = backend_tex;
tex->SetTexID((ImTextureID)(intptr_t)raw_tex);
}
if (tex->Status == ImTextureStatus_WantCreate || tex->Status == ImTextureStatus_WantUpdates)
{
ImGui_ImplSDLGPU3_Texture* backend_tex = (ImGui_ImplSDLGPU3_Texture*)tex->BackendUserData;
SDL_GPUTexture* raw_tex = (SDL_GPUTexture*)(intptr_t)tex->GetTexID();
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
// Update full texture or selected blocks. We only ever write to textures regions which have never been used before!
@@ -385,7 +386,7 @@ void ImGui_ImplSDLGPU3_UpdateTexture(ImTextureData* tex)
transfer_info.transfer_buffer = bd->TexTransferBuffer;
SDL_GPUTextureRegion texture_region = {};
texture_region.texture = backend_tex->Texture;
texture_region.texture = raw_tex;
texture_region.x = (Uint32)upload_x;
texture_region.y = (Uint32)upload_y;
texture_region.w = (Uint32)upload_w;

View File

@@ -2,7 +2,7 @@
// This needs to be used along with the SDL3 Platform Backend
// Implemented features:
// [X] Renderer: User texture binding. Use simply cast a reference to your SDL_GPUTextureSamplerBinding to ImTextureID.
// [X] Renderer: User texture binding. Use 'SDL_GPUTexture*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef! **IMPORTANT** Before 2025/08/08, ImTextureID was a reference to a SDL_GPUTextureSamplerBinding struct.
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
@@ -50,4 +50,14 @@ IMGUI_IMPL_API void ImGui_ImplSDLGPU3_DestroyDeviceObjects();
// (Advanced) Use e.g. if you need to precisely control the timing of texture updates (e.g. for staged rendering), by setting ImDrawData::Textures = NULL to handle this manually.
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_UpdateTexture(ImTextureData* tex);
// [BETA] Selected render state data shared with callbacks.
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplSDLGPU3_RenderDrawData() call.
// (Please open an issue if you feel you need access to more data)
struct ImGui_ImplSDLGPU3_RenderState
{
SDL_GPUDevice* Device;
SDL_GPUSampler* SamplerDefault; // Default sampler (bilinear filtering)
SDL_GPUSampler* SamplerCurrent; // Current sampler (may be changed by callback)
};
#endif // #ifndef IMGUI_DISABLE

View File

@@ -617,6 +617,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
// Render command lists
// (Because we merged all buffers into a single one, we maintain our own offset into them)
VkDescriptorSet last_desc_set = VK_NULL_HANDLE;
int global_vtx_offset = 0;
int global_idx_offset = 0;
for (const ImDrawList* draw_list : draw_data->CmdLists)
@@ -632,6 +633,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
ImGui_ImplVulkan_SetupRenderState(draw_data, pipeline, command_buffer, rb, fb_width, fb_height);
else
pcmd->UserCallback(draw_list, pcmd);
last_desc_set = VK_NULL_HANDLE;
}
else
{
@@ -657,7 +659,9 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
// Bind DescriptorSet with font or user texture
VkDescriptorSet desc_set = (VkDescriptorSet)pcmd->GetTexID();
if (desc_set != last_desc_set)
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bd->PipelineLayout, 0, 1, &desc_set, 0, nullptr);
last_desc_set = desc_set;
// Draw
vkCmdDrawIndexed(command_buffer, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);

View File

@@ -43,12 +43,24 @@ Breaking Changes:
- Tabs: Renamed ImGuiTabBarFlags_FittingPolicyResizeDown to ImGuiTabBarFlags_FittingPolicyShrink.
Kept inline redirection enum (will obsolete). (#261, #351)
- Backends: SDL_GPU3: changed ImTextureID type from SDL_GPUTextureSamplerBinding* to SDL_GPUTexture*,
which is more natural and easier for user to manage. If you need to change the current sampler,
you can access the ImGui_ImplSDLGPU3_RenderState struct. (#8866, #8163, #7998, #7988)
Other Changes:
- Fonts: fixed an issue when a font using MergeMode has a reference size
specified but the target font doesn't. Usually either all fonts should
have a reference size (only required when specifying e.g. GlyphOffset),
or none should have a reference size.
- Fonts: fixed a crash when changing texture format when using a legacy
backend. Most commonly would happen when calling GetTexDataAsRGBA32()
then immediately GetTexDataAsAlpha8(). (#8824)
- Windows: fixed an issue where resizable child windows would emit border
logic when hidden/non-visible (e.g. when in a docked window that is not
selected), impacting code not checking for BeginChild() return value. (#8815)
- Textures: Fixed support for `#define ImTextureID_Invalid` to non-zero value:
ImFontAtlas() was incorrectly cleared with zeroes. (#8860, #8745) [@cfillion]
- Tables: fixed TableGetRowIndex() which never correctly worked when using
a clipper (it exists for consistency but is almost never used, as it is
often more convenient to use index in caller-code, whereas TableGetRowIndex()
@@ -68,6 +80,9 @@ Other Changes:
any potential shrinking is applied.
- Tabs: fixed tab bar underline not drawing below scroll buttons, when
they are enabled (minor regression from 1.90). (#6820, #4859, #5022, #5239)
- Tabs: made scrolling buttons never keyboard/gamepad navigation candidates.
- Nav: fixed a bug where GamepadMenu button couldn't toggle between main and
menu layers while navigating a Modal window. (#8834)
- Error Handling: minor improvements to error handling for TableGetSortSpecs()
and TableSetBgColor() calls. (#1651, #8499)
- Misc: fixed building with IMGUI_DISABLE_DEBUG_TOOLS only. (#8796)
@@ -77,12 +92,18 @@ Other Changes:
- CI: Added SDL3 builds to MacOS and Windows. (#8819, #8778) [@scribam]
- CI: Updated Windows CI to use a more recent SDL2. (#8819, #8778) [@scribam]
- Examples: SDL3+Metal: added SDL3+Metal example. (#8827, #8825) [@shi-yan]
- Examples: SDL3+SDL_GPU: use SDL_WaitAndAcquireGPUSwapchainTexture() instead
of SDL_AcquireGPUSwapchainTexture(). (#8830) [@itsdanott]
- Backends: OpenGL3: add and call embedded loader shutdown in ImGui_ImplOpenGL3_Shutdown()
to facilitate multiple init/shutdown cycles in same process. (#8792) [@tim-rex]
- Backends: OpenGL2, OpenGL3: set GL_UNPACK_ALIGNMENT to 1 before updating
textures. (#8802) [@Daandelange]
- Backends: SDL_GPU3: expose current SDL_GPUSampler* in the ImGui_ImplSDLGPU3_RenderState
struct. (#8866, #8163, #7998, #7988)
- Backends: Vulkan: Fixed texture update corruption introduced in 1.92.0,
affecting some drivers/setups. (#8801, #8755, #8840) [@Retro52, @Miolith]
- Backends: Vulkan: Avoid calling vkCmdBindDescriptorSets() when texture
has not changed. (#8666) [@micb25]
Docking+Viewports Branch:
@@ -113,6 +134,8 @@ Changes:
to pass full range of information into e.g. FreeType's face_index, as higher
bits are used from FreeType 2.6.1. (#8775) [@Valakor]
(the field has been erroneously reduced from 32-bits to 8-bit in 1.92.0)
- Fonts, Tables: fixed PushFont() having no effect when called after submitting
a hidden column. (#8865)
- Textures: Fixed support for `#define ImTextureID_Invalid` to non-zero value:
ImTextureData() was incorrectly cleared with zeroes. (#8745) [@rachit7645]
- Demo: Added "Text -> Font Size" demo section. (#8738) [@Demonese]

View File

@@ -60,7 +60,7 @@ int main(int, char**)
printf("Error: SDL_ClaimWindowForGPUDevice(): %s\n", SDL_GetError());
return -1;
}
SDL_SetGPUSwapchainParameters(gpu_device, window, SDL_GPU_SWAPCHAINCOMPOSITION_SDR, SDL_GPU_PRESENTMODE_MAILBOX);
SDL_SetGPUSwapchainParameters(gpu_device, window, SDL_GPU_SWAPCHAINCOMPOSITION_SDR, SDL_GPU_PRESENTMODE_VSYNC);
// Setup Dear ImGui context
IMGUI_CHECKVERSION();
@@ -195,7 +195,7 @@ int main(int, char**)
SDL_GPUCommandBuffer* command_buffer = SDL_AcquireGPUCommandBuffer(gpu_device); // Acquire a GPU command buffer
SDL_GPUTexture* swapchain_texture;
SDL_AcquireGPUSwapchainTexture(command_buffer, window, &swapchain_texture, nullptr, nullptr); // Acquire a swapchain texture
SDL_WaitAndAcquireGPUSwapchainTexture(command_buffer, window, &swapchain_texture, nullptr, nullptr); // Acquire a swapchain texture
if (swapchain_texture != nullptr && !is_minimized)
{

View File

@@ -15,7 +15,7 @@
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <GL/GL.h>
#include <GL/gl.h>
#include <tchar.h>
// Data stored per platform window

View File

@@ -400,6 +400,7 @@ IMPLEMENTING SUPPORT for ImGuiBackendFlags_RendererHasTextures:
- likewise io.MousePos and GetMousePos() will use OS coordinates.
If you query mouse positions to interact with non-imgui coordinates you will need to offset them, e.g. subtract GetWindowViewport()->Pos.
- 2025/08/08 (1.92.2) - Backends: SDL_GPU3: Changed ImTextureID type from SDL_GPUTextureSamplerBinding* to SDL_GPUTexture*, which is more natural and easier for user to manage. If you need to change the current sampler, you can access the ImGui_ImplSDLGPU3_RenderState struct. (#8866, #8163, #7998, #7988)
- 2025/07/31 (1.92.2) - Tabs: Renamed ImGuiTabBarFlags_FittingPolicyResizeDown to ImGuiTabBarFlags_FittingPolicyShrink. Kept inline redirection enum (will obsolete).
- 2025/06/25 (1.92.0) - Layout: commented out legacy ErrorCheckUsingSetCursorPosToExtendParentBoundaries() fallback obsoleted in 1.89 (August 2022) which allowed a SetCursorPos()/SetCursorScreenPos() call WITHOUT AN ITEM
to extend parent window/cell boundaries. Replaced with assert/tooltip that would already happens if previously using IMGUI_DISABLE_OBSOLETE_FUNCTIONS. (#5548, #4510, #3355, #1760, #1490, #4152, #150)
@@ -9447,11 +9448,14 @@ void ImGui::UpdateCurrentFontSize(float restore_font_size_after_scaling)
g.Style.FontSizeBase = g.FontSizeBase;
// Early out to avoid hidden window keeping bakes referenced and out of GC reach.
// However this would leave a pretty subtle and damning error surface area if g.FontBaked was mismatching, so for now we null it.
// However this would leave a pretty subtle and damning error surface area if g.FontBaked was mismatching.
// FIXME: perhaps g.FontSize should be updated?
if (window != NULL && window->SkipItems)
if (g.CurrentTable == NULL || g.CurrentTable->CurrentColumn != -1) // See 8465#issuecomment-2951509561. Ideally the SkipItems=true in tables would be amended with extra data.
{
ImGuiTable* table = g.CurrentTable;
if (table == NULL || (table->CurrentColumn != -1 && table->Columns[table->CurrentColumn].IsSkipItems == false)) // See 8465#issuecomment-2951509561 and #8865. Ideally the SkipItems=true in tables would be amended with extra data.
return;
}
// Restoring is pretty much only used by PopFont()
float final_size = (restore_font_size_after_scaling > 0.0f) ? restore_font_size_after_scaling : 0.0f;
@@ -14907,9 +14911,16 @@ static void ImGui::NavUpdateWindowing()
const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0;
const bool keyboard_next_window = allow_windowing && g.ConfigNavWindowingKeyNext && Shortcut(g.ConfigNavWindowingKeyNext, ImGuiInputFlags_Repeat | ImGuiInputFlags_RouteAlways, owner_id);
const bool keyboard_prev_window = allow_windowing && g.ConfigNavWindowingKeyPrev && Shortcut(g.ConfigNavWindowingKeyPrev, ImGuiInputFlags_Repeat | ImGuiInputFlags_RouteAlways, owner_id);
const bool start_windowing_with_gamepad = allow_windowing && nav_gamepad_active && !g.NavWindowingTarget && Shortcut(ImGuiKey_NavGamepadMenu, ImGuiInputFlags_RouteAlways, owner_id);
const bool start_toggling_with_gamepad = nav_gamepad_active && !g.NavWindowingTarget && Shortcut(ImGuiKey_NavGamepadMenu, ImGuiInputFlags_RouteAlways, owner_id);
const bool start_windowing_with_gamepad = allow_windowing && start_toggling_with_gamepad;
const bool start_windowing_with_keyboard = allow_windowing && !g.NavWindowingTarget && (keyboard_next_window || keyboard_prev_window); // Note: enabled even without NavEnableKeyboard!
bool just_started_windowing_from_null_focus = false;
if (start_toggling_with_gamepad)
{
g.NavWindowingToggleLayer = true; // Gamepad starts toggling layer
g.NavWindowingToggleKey = ImGuiKey_NavGamepadMenu;
g.NavWindowingInputSource = g.NavInputSource = ImGuiInputSource_Gamepad;
}
if (start_windowing_with_gamepad || start_windowing_with_keyboard)
if (ImGuiWindow* window = g.NavWindow ? g.NavWindow : FindWindowNavFocusable(g.WindowsFocusOrder.Size - 1, -INT_MAX, -1))
{
@@ -14917,7 +14928,6 @@ static void ImGui::NavUpdateWindowing()
g.NavWindowingTarget = g.NavWindowingTargetAnim = window->RootWindow; // Current location
g.NavWindowingTimer = g.NavWindowingHighlightAlpha = 0.0f;
g.NavWindowingAccumDeltaPos = g.NavWindowingAccumDeltaSize = ImVec2(0.0f, 0.0f);
g.NavWindowingToggleLayer = start_windowing_with_gamepad ? true : false; // Gamepad starts toggling layer
g.NavWindowingInputSource = g.NavInputSource = start_windowing_with_keyboard ? ImGuiInputSource_Keyboard : ImGuiInputSource_Gamepad;
if (g.NavWindow == NULL)
just_started_windowing_from_null_focus = true;
@@ -22805,8 +22815,8 @@ void ImGui::DebugNodeFont(ImFont* font)
for (int src_n = 0; src_n < font->Sources.Size; src_n++)
{
ImFontConfig* src = font->Sources[src_n];
if (TreeNode(src, "Input %d: \'%s\', Oversample: %d,%d, PixelSnapH: %d, Offset: (%.1f,%.1f)",
src_n, src->Name, src->OversampleH, src->OversampleV, src->PixelSnapH, src->GlyphOffset.x, src->GlyphOffset.y))
if (TreeNode(src, "Input %d: \'%s\' [%d], Oversample: %d,%d, PixelSnapH: %d, Offset: (%.1f,%.1f)",
src_n, src->Name, src->FontNo, src->OversampleH, src->OversampleV, src->PixelSnapH, src->GlyphOffset.x, src->GlyphOffset.y))
{
const ImFontLoader* loader = src->FontLoader ? src->FontLoader : atlas->FontLoader;
Text("Loader: '%s'", loader->Name ? loader->Name : "N/A");

18
imgui.h
View File

@@ -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.2 WIP"
#define IMGUI_VERSION_NUM 19213
#define IMGUI_VERSION_NUM 19214
#define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000
#define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198
#define IMGUI_HAS_VIEWPORT // In 'docking' WIP branch.
@@ -4228,24 +4228,24 @@ struct ImGuiPlatformImeData
namespace ImGui
{
// OBSOLETED in 1.92.0 (from June 2025)
static inline void PushFont(ImFont* font) { PushFont(font, font ? font->LegacySize : 0.0f); }
inline void PushFont(ImFont* font) { PushFont(font, font ? font->LegacySize : 0.0f); }
IMGUI_API void SetWindowFontScale(float scale); // Set font scale factor for current window. Prefer using PushFont(NULL, style.FontSizeBase * factor) or use style.FontScaleMain to scale all windows.
// OBSOLETED in 1.91.9 (from February 2025)
IMGUI_API void Image(ImTextureRef tex_ref, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col); // <-- 'border_col' was removed in favor of ImGuiCol_ImageBorder. If you use 'tint_col', use ImageWithBg() instead.
// OBSOLETED in 1.91.0 (from July 2024)
static inline void PushButtonRepeat(bool repeat) { PushItemFlag(ImGuiItemFlags_ButtonRepeat, repeat); }
static inline void PopButtonRepeat() { PopItemFlag(); }
static inline void PushTabStop(bool tab_stop) { PushItemFlag(ImGuiItemFlags_NoTabStop, !tab_stop); }
static inline void PopTabStop() { PopItemFlag(); }
inline void PushButtonRepeat(bool repeat) { PushItemFlag(ImGuiItemFlags_ButtonRepeat, repeat); }
inline void PopButtonRepeat() { PopItemFlag(); }
inline void PushTabStop(bool tab_stop) { PushItemFlag(ImGuiItemFlags_NoTabStop, !tab_stop); }
inline void PopTabStop() { PopItemFlag(); }
IMGUI_API ImVec2 GetContentRegionMax(); // Content boundaries max (e.g. window boundaries including scrolling, or current column boundaries). You should never need this. Always use GetCursorScreenPos() and GetContentRegionAvail()!
IMGUI_API ImVec2 GetWindowContentRegionMin(); // Content boundaries min for the window (roughly (0,0)-Scroll), in window-local coordinates. You should never need this. Always use GetCursorScreenPos() and GetContentRegionAvail()!
IMGUI_API ImVec2 GetWindowContentRegionMax(); // Content boundaries max for the window (roughly (0,0)+Size-Scroll), in window-local coordinates. You should never need this. Always use GetCursorScreenPos() and GetContentRegionAvail()!
// OBSOLETED in 1.90.0 (from September 2023)
static inline bool BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags window_flags = 0) { return BeginChild(id, size, ImGuiChildFlags_FrameStyle, window_flags); }
static inline void EndChildFrame() { EndChild(); }
inline bool BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags window_flags = 0) { return BeginChild(id, size, ImGuiChildFlags_FrameStyle, window_flags); }
inline void EndChildFrame() { EndChild(); }
//static inline bool BeginChild(const char* str_id, const ImVec2& size_arg, bool borders, ImGuiWindowFlags window_flags){ return BeginChild(str_id, size_arg, borders ? ImGuiChildFlags_Borders : ImGuiChildFlags_None, window_flags); } // Unnecessary as true == ImGuiChildFlags_Borders
//static inline bool BeginChild(ImGuiID id, const ImVec2& size_arg, bool borders, ImGuiWindowFlags window_flags) { return BeginChild(id, size_arg, borders ? ImGuiChildFlags_Borders : ImGuiChildFlags_None, window_flags); } // Unnecessary as true == ImGuiChildFlags_Borders
static inline void ShowStackToolWindow(bool* p_open = NULL) { ShowIDStackToolWindow(p_open); }
inline void ShowStackToolWindow(bool* p_open = NULL) { ShowIDStackToolWindow(p_open); }
IMGUI_API bool Combo(const char* label, int* current_item, bool (*old_callback)(void* user_data, int idx, const char** out_text), void* user_data, int items_count, int popup_max_height_in_items = -1);
IMGUI_API bool ListBox(const char* label, int* current_item, bool (*old_callback)(void* user_data, int idx, const char** out_text), void* user_data, int items_count, int height_in_items = -1);
// OBSOLETED in 1.89.7 (from June 2023)

View File

@@ -2637,6 +2637,7 @@ ImFontAtlas::ImFontAtlas()
TexMinHeight = 128;
TexMaxWidth = 8192;
TexMaxHeight = 8192;
TexRef._TexID = ImTextureID_Invalid;
RendererHasTextures = false; // Assumed false by default, as apps can call e.g Atlas::Build() after backend init and before ImGui can update.
TexNextUniqueID = 1;
FontNextUniqueID = 1;
@@ -3368,11 +3369,7 @@ void ImFontAtlasBuildMain(ImFontAtlas* atlas)
{
IM_ASSERT(!atlas->Locked && "Cannot modify a locked ImFontAtlas!");
if (atlas->TexData && atlas->TexData->Format != atlas->TexDesiredFormat)
{
ImVec2i new_tex_size = ImFontAtlasTextureGetSizeEstimate(atlas);
ImFontAtlasBuildDestroy(atlas);
ImFontAtlasTextureAdd(atlas, new_tex_size.x, new_tex_size.y);
}
ImFontAtlasBuildClear(atlas);
if (atlas->Builder == NULL)
ImFontAtlasBuildInit(atlas);
@@ -4578,15 +4575,16 @@ static bool ImGui_ImplStbTrueType_FontSrcInit(ImFontAtlas* atlas, ImFontConfig*
}
src->FontLoaderData = bd_font_data;
const float ref_size = src->DstFont->Sources[0]->SizePixels;
if (src->MergeMode && src->SizePixels == 0.0f)
src->SizePixels = src->DstFont->Sources[0]->SizePixels;
src->SizePixels = ref_size;
if (src->SizePixels >= 0.0f)
bd_font_data->ScaleFactor = stbtt_ScaleForPixelHeight(&bd_font_data->FontInfo, 1.0f);
else
bd_font_data->ScaleFactor = stbtt_ScaleForMappingEmToPixels(&bd_font_data->FontInfo, 1.0f);
if (src->MergeMode && src->SizePixels != 0.0f)
bd_font_data->ScaleFactor *= src->SizePixels / src->DstFont->Sources[0]->SizePixels; // FIXME-NEWATLAS: Should tidy up that a bit
if (src->MergeMode && src->SizePixels != 0.0f && ref_size != 0.0f)
bd_font_data->ScaleFactor *= src->SizePixels / ref_size; // FIXME-NEWATLAS: Should tidy up that a bit
return true;
}

View File

@@ -2533,8 +2533,8 @@ struct ImGuiContext
float NavWindowingTimer;
float NavWindowingHighlightAlpha;
ImGuiInputSource NavWindowingInputSource;
bool NavWindowingToggleLayer;
ImGuiKey NavWindowingToggleKey;
bool NavWindowingToggleLayer; // Set while Alt or GamepadMenu is held, may be cleared by other operations, and processed when releasing the key.
ImGuiKey NavWindowingToggleKey; // Keyboard/gamepad key used when toggling to menu layer.
ImVec2 NavWindowingAccumDeltaPos;
ImVec2 NavWindowingAccumDeltaSize;

View File

@@ -1846,7 +1846,7 @@ void ImGui::ShrinkWidths(ImGuiShrinkWidthItem* items, int count, float width_exc
}
ImQsort(items, (size_t)count, sizeof(ImGuiShrinkWidthItem), ShrinkWidthItemComparer); // Sort largest first, smallest last.
int count_same_width = 1;
while (width_excess > 0.0f && count_same_width < count)
while (width_excess > 0.001f && count_same_width < count)
{
while (count_same_width < count && items[0].Width <= items[count_same_width].Width)
count_same_width++;
@@ -4950,7 +4950,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
{
// Determine if we turn Enter into a \n character
bool ctrl_enter_for_new_line = (flags & ImGuiInputTextFlags_CtrlEnterForNewLine) != 0;
if (!is_multiline || is_gamepad_validate || (ctrl_enter_for_new_line && !io.KeyCtrl) || (!ctrl_enter_for_new_line && io.KeyCtrl))
if (!is_multiline || is_gamepad_validate || (ctrl_enter_for_new_line != io.KeyCtrl))
{
validated = true;
if (io.ConfigInputTextEnterKeepActive && !is_multiline)
@@ -9703,7 +9703,8 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
// Horizontal scrolling buttons
// Important: note that TabBarScrollButtons() will alter BarRect.Max.x.
const bool can_scroll = (tab_bar->Flags & ImGuiTabBarFlags_FittingPolicyScroll) || (tab_bar->Flags & ImGuiTabBarFlags_FittingPolicyMixed);
tab_bar->ScrollButtonEnabled = ((width_all_tabs_after_min_width_shrink > tab_bar->BarRect.GetWidth() && tab_bar->Tabs.Size > 1) && !(tab_bar->Flags & ImGuiTabBarFlags_NoTabListScrollingButtons) && can_scroll);
const float width_all_tabs_to_use_for_scroll = (tab_bar->Flags & ImGuiTabBarFlags_FittingPolicyScroll) ? tab_bar->WidthAllTabs : width_all_tabs_after_min_width_shrink;
tab_bar->ScrollButtonEnabled = ((width_all_tabs_to_use_for_scroll > tab_bar->BarRect.GetWidth() && tab_bar->Tabs.Size > 1) && !(tab_bar->Flags & ImGuiTabBarFlags_NoTabListScrollingButtons) && can_scroll);
if (tab_bar->ScrollButtonEnabled)
if (ImGuiTabItem* scroll_and_select_tab = TabBarScrollingButtons(tab_bar))
{
@@ -10101,7 +10102,7 @@ static ImGuiTabItem* ImGui::TabBarScrollingButtons(ImGuiTabBar* tab_bar)
PushStyleColor(ImGuiCol_Text, arrow_col);
PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
PushItemFlag(ImGuiItemFlags_ButtonRepeat, true);
PushItemFlag(ImGuiItemFlags_ButtonRepeat | ImGuiItemFlags_NoNav, true);
const float backup_repeat_delay = g.IO.KeyRepeatDelay;
const float backup_repeat_rate = g.IO.KeyRepeatRate;
g.IO.KeyRepeatDelay = 0.250f;