From b78cc37891608c582cd71b2bdc299f6ff8392432 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 12 Feb 2025 19:27:43 +0100 Subject: [PATCH 01/11] Backends: SDL2: Fixed build for versions older than 2.0.14. (#7660) --- backends/imgui_impl_sdl2.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backends/imgui_impl_sdl2.cpp b/backends/imgui_impl_sdl2.cpp index abe0e4342..24585a9d3 100644 --- a/backends/imgui_impl_sdl2.cpp +++ b/backends/imgui_impl_sdl2.cpp @@ -116,6 +116,7 @@ #define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 0 #endif #define SDL_HAS_VULKAN SDL_VERSION_ATLEAST(2,0,6) +#define SDL_HAS_OPEN_URL SDL_VERSION_ATLEAST(2,0,14) #if SDL_HAS_VULKAN #include #endif @@ -481,7 +482,7 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void platform_io.Platform_SetImeDataFn = ImGui_ImplSDL2_PlatformSetImeData; #ifdef __EMSCRIPTEN__ platform_io.Platform_OpenInShellFn = [](ImGuiContext*, const char* url) { ImGui_ImplSDL2_EmscriptenOpenURL(url); return true; }; -#else +#elif SDL_HAS_OPEN_URL platform_io.Platform_OpenInShellFn = [](ImGuiContext*, const char* url) { return SDL_OpenURL(url) == 0; }; #endif From f94a5f0e8c4b22476891cc18372ff5caaebe8492 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Tassoux?= Date: Thu, 13 Feb 2025 14:30:49 +0100 Subject: [PATCH 02/11] Docs: Update doc about plutosvg (#8395) --- imconfig.h | 3 +-- misc/freetype/README.md | 16 ++++------------ 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/imconfig.h b/imconfig.h index 8f8bc3b9a..a1e29e849 100644 --- a/imconfig.h +++ b/imconfig.h @@ -88,8 +88,7 @@ //---- Use FreeType + plutosvg or lunasvg to render OpenType SVG fonts (SVGinOT) // Only works in combination with IMGUI_ENABLE_FREETYPE. -// - lunasvg is currently easier to acquire/install, as e.g. it is part of vcpkg. -// - plutosvg will support more fonts and may load them faster. It currently requires to be built manually but it is fairly easy. See misc/freetype/README for instructions. +// - plutosvg is currently easier to install, as e.g. it is part of vcpkg. It will support more fonts and may load them faster. See misc/freetype/README for instructions. // - Both require headers to be available in the include path + program to be linked with the library code (not provided). // - (note: lunasvg implementation is based on Freetype's rsvg-port.c which is licensed under CeCILL-C Free Software License Agreement) //#define IMGUI_ENABLE_FREETYPE_PLUTOSVG diff --git a/misc/freetype/README.md b/misc/freetype/README.md index 6e2e8671e..e1bd0198b 100644 --- a/misc/freetype/README.md +++ b/misc/freetype/README.md @@ -48,15 +48,7 @@ Requires: [lunasvg](https://github.com/sammycage/lunasvg) v2.3.2 and above #### Using plutosvg (and plutovg) - Add `#define IMGUI_ENABLE_FREETYPE_PLUTOSVG` in your `imconfig.h`. -- Compile and link with plutosvg *and* plutovg (which is required by plutosvg) - -_Compilation hints for plutovg_ -- Compile all source files in `plutovg/source/*.c` -- Add include directory: `plutovg/include` + `plutovg/stb` - -_Compilation hints for plutosvg_ -- Compile `plutosvg/source/plutosvg.c` -- Add include directory: `plutosvg/source` -- Add define: `PLUTOSVG_HAS_FREETYPE` -- Link with: plutovg, freetype - +- Get latest plutosvg binaries or build yourself. Under Windows you may use vcpkg with: `vcpkg install plutosvg --triplet=x64-windows`. Alternatively, if you build imgui from vcpkg, you just need to enable the plutosvg feature: `vcpkg install imgui[plutosvg] --triplet=x64-windows` +- If you prefer to build plutosvg manually: + - Compilation hints for plutovg: Compile all source files in `plutovg/source/*.c` + Add include directory: `plutovg/include` + `plutovg/stb` + - Compilation hints for plutosvg: Compile `plutosvg/source/plutosvg.c` + Add include directory: `plutosvg/source` + Add define: `PLUTOSVG_HAS_FREETYPE` + Link with: plutovg, freetype From 890ead6a718c95c730012d7c2c3e5844a4a93bb9 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 13 Feb 2025 15:40:49 +0100 Subject: [PATCH 03/11] Backends: Vulkan: Added ApiVersion field in ImGui_ImplVulkan_InitInfo. Dynamic rendering path loads "vkCmdBeginRendering/vkCmdEndRendering" without -KHR on API 1.3. (#8326, #8365) --- backends/imgui_impl_vulkan.cpp | 11 ++++++++--- backends/imgui_impl_vulkan.h | 13 +++++++------ docs/CHANGELOG.txt | 4 ++++ 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/backends/imgui_impl_vulkan.cpp b/backends/imgui_impl_vulkan.cpp index 2bd40f624..7be2ed1d1 100644 --- a/backends/imgui_impl_vulkan.cpp +++ b/backends/imgui_impl_vulkan.cpp @@ -26,6 +26,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2025-02-13: Vulkan: Added ApiVersion field in ImGui_ImplVulkan_InitInfo. Default to header version if unspecified. Dynamic rendering path loads "vkCmdBeginRendering/vkCmdEndRendering" (without -KHR suffix) on API 1.3. (#8326) // 2025-01-09: Vulkan: Added IMGUI_IMPL_VULKAN_MINIMUM_IMAGE_SAMPLER_POOL_SIZE to clarify how many image sampler descriptors are expected to be available in descriptor pool. (#6642) // 2025-01-06: Vulkan: Added more ImGui_ImplVulkanH_XXXX helper functions to simplify our examples. // 2024-12-11: Vulkan: Fixed setting VkSwapchainCreateInfoKHR::preTransform for platforms not supporting VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR. (#8222) @@ -1082,9 +1083,11 @@ void ImGui_ImplVulkan_DestroyDeviceObjects() #ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING static void ImGui_ImplVulkan_LoadDynamicRenderingFunctions(PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data) { - // Manually load those two (see #5446) - ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR = reinterpret_cast(loader_func("vkCmdBeginRenderingKHR", user_data)); - ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR = reinterpret_cast(loader_func("vkCmdEndRenderingKHR", user_data)); + // Manually load those two (see #5446, #8326, #8365) + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; + ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR = reinterpret_cast(loader_func(v->ApiVersion < VK_API_VERSION_1_3 ? "vkCmdBeginRenderingKHR" : "vkCmdBeginRendering", user_data)); + ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR = reinterpret_cast(loader_func(v->ApiVersion < VK_API_VERSION_1_3 ? "vkCmdEndRenderingKHR" : "vkCmdEndRendering", user_data)); } #endif @@ -1155,6 +1158,8 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info) IM_ASSERT(info->RenderPass != VK_NULL_HANDLE); bd->VulkanInitInfo = *info; + if (bd->VulkanInitInfo.ApiVersion == 0) + bd->VulkanInitInfo.ApiVersion = VK_HEADER_VERSION_COMPLETE; ImGui_ImplVulkan_CreateDeviceObjects(); diff --git a/backends/imgui_impl_vulkan.h b/backends/imgui_impl_vulkan.h index 6f4839c13..9b79d3250 100644 --- a/backends/imgui_impl_vulkan.h +++ b/backends/imgui_impl_vulkan.h @@ -75,16 +75,17 @@ // - When using dynamic rendering, set UseDynamicRendering=true and fill PipelineRenderingCreateInfo structure. struct ImGui_ImplVulkan_InitInfo { + uint32_t ApiVersion; // Fill with API version of Instance, e.g. VK_API_VERSION_1_3, which might be lower than header version (VK_HEADER_VERSION_COMPLETE) VkInstance Instance; VkPhysicalDevice PhysicalDevice; VkDevice Device; uint32_t QueueFamily; VkQueue Queue; - VkDescriptorPool DescriptorPool; // See requirements in note above; ignored if using DescriptorPoolSize > 0 - VkRenderPass RenderPass; // Ignored if using dynamic rendering - uint32_t MinImageCount; // >= 2 - uint32_t ImageCount; // >= MinImageCount - VkSampleCountFlagBits MSAASamples; // 0 defaults to VK_SAMPLE_COUNT_1_BIT + VkDescriptorPool DescriptorPool; // See requirements in note above; ignored if using DescriptorPoolSize > 0 + VkRenderPass RenderPass; // Ignored if using dynamic rendering + uint32_t MinImageCount; // >= 2 + uint32_t ImageCount; // >= MinImageCount + VkSampleCountFlagBits MSAASamples; // 0 defaults to VK_SAMPLE_COUNT_1_BIT // (Optional) VkPipelineCache PipelineCache; @@ -103,7 +104,7 @@ struct ImGui_ImplVulkan_InitInfo // (Optional) Allocation, Debugging const VkAllocationCallbacks* Allocator; void (*CheckVkResultFn)(VkResult err); - VkDeviceSize MinAllocationSize; // Minimum allocation size. Set to 1024*1024 to satisfy zealous best practices validation layer and waste a little memory. + VkDeviceSize MinAllocationSize; // Minimum allocation size. Set to 1024*1024 to satisfy zealous best practices validation layer and waste a little memory. }; // Follow "Getting Started" link and check examples/ folder to learn about using backends! diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index d897ace83..ec2180fac 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -80,6 +80,10 @@ Other changes: - Backends: SDL2, SDL3: Using SDL_OpenURL() in platform_io.Platform_OpenInShellFn handler. (#7660) [@achabense] - Backends: Metal: Fixed a crash on application resources. (#8367, #7419) [@anszom] +- Backends: Vulkan: Added ApiVersion field in ImGui_ImplVulkan_InitInfo. + Default to header version if unspecified. (#8326, #8365) [@mklefrancois] +- Backends: Vulkan: Dynamic rendering path loads "vkCmdBeginRendering/vkCmdEndRendering" + (without -KHR suffix) on API 1.3. (#8326, #8365) [@mklefrancois] - Backends: WebGPU: Fix for DAWN API rename WGPUProgrammableStageDescriptor -> WGPUComputeState. [@PhantomCloak] (#8369) From 12963f52314d126817da333675fe2f6bcde44ffe Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 13 Feb 2025 15:49:47 +0100 Subject: [PATCH 04/11] Examples: Vulkan: make ApiVersion a little more visible in examples. (#8326, #8365) --- backends/imgui_impl_vulkan.h | 2 +- examples/example_glfw_vulkan/main.cpp | 1 + examples/example_sdl2_vulkan/main.cpp | 1 + examples/example_sdl3_vulkan/main.cpp | 1 + examples/example_win32_vulkan/main.cpp | 1 + 5 files changed, 5 insertions(+), 1 deletion(-) diff --git a/backends/imgui_impl_vulkan.h b/backends/imgui_impl_vulkan.h index 9b79d3250..c8afc92ac 100644 --- a/backends/imgui_impl_vulkan.h +++ b/backends/imgui_impl_vulkan.h @@ -75,7 +75,7 @@ // - When using dynamic rendering, set UseDynamicRendering=true and fill PipelineRenderingCreateInfo structure. struct ImGui_ImplVulkan_InitInfo { - uint32_t ApiVersion; // Fill with API version of Instance, e.g. VK_API_VERSION_1_3, which might be lower than header version (VK_HEADER_VERSION_COMPLETE) + uint32_t ApiVersion; // Fill with API version of Instance, e.g. VK_API_VERSION_1_3 or your value of VkApplicationInfo::apiVersion. May be lower than header version (VK_HEADER_VERSION_COMPLETE) VkInstance Instance; VkPhysicalDevice PhysicalDevice; VkDevice Device; diff --git a/examples/example_glfw_vulkan/main.cpp b/examples/example_glfw_vulkan/main.cpp index 31da972df..ce7fcde5e 100644 --- a/examples/example_glfw_vulkan/main.cpp +++ b/examples/example_glfw_vulkan/main.cpp @@ -396,6 +396,7 @@ int main(int, char**) // Setup Platform/Renderer backends ImGui_ImplGlfw_InitForVulkan(window, true); ImGui_ImplVulkan_InitInfo init_info = {}; + //init_info.ApiVersion = VK_API_VERSION_1_3; // Pass in your value of VkApplicationInfo::apiVersion, otherwise will default to header version. init_info.Instance = g_Instance; init_info.PhysicalDevice = g_PhysicalDevice; init_info.Device = g_Device; diff --git a/examples/example_sdl2_vulkan/main.cpp b/examples/example_sdl2_vulkan/main.cpp index c0282f932..0c29154bc 100644 --- a/examples/example_sdl2_vulkan/main.cpp +++ b/examples/example_sdl2_vulkan/main.cpp @@ -396,6 +396,7 @@ int main(int, char**) // Setup Platform/Renderer backends ImGui_ImplSDL2_InitForVulkan(window); ImGui_ImplVulkan_InitInfo init_info = {}; + //init_info.ApiVersion = VK_API_VERSION_1_3; // Pass in your value of VkApplicationInfo::apiVersion, otherwise will default to header version. init_info.Instance = g_Instance; init_info.PhysicalDevice = g_PhysicalDevice; init_info.Device = g_Device; diff --git a/examples/example_sdl3_vulkan/main.cpp b/examples/example_sdl3_vulkan/main.cpp index 52544c342..99e441d7e 100644 --- a/examples/example_sdl3_vulkan/main.cpp +++ b/examples/example_sdl3_vulkan/main.cpp @@ -400,6 +400,7 @@ int main(int, char**) // Setup Platform/Renderer backends ImGui_ImplSDL3_InitForVulkan(window); ImGui_ImplVulkan_InitInfo init_info = {}; + //init_info.ApiVersion = VK_API_VERSION_1_3; // Pass in your value of VkApplicationInfo::apiVersion, otherwise will default to header version. init_info.Instance = g_Instance; init_info.PhysicalDevice = g_PhysicalDevice; init_info.Device = g_Device; diff --git a/examples/example_win32_vulkan/main.cpp b/examples/example_win32_vulkan/main.cpp index f337d8e7d..427a2494a 100644 --- a/examples/example_win32_vulkan/main.cpp +++ b/examples/example_win32_vulkan/main.cpp @@ -387,6 +387,7 @@ int main(int, char**) // Setup Platform/Renderer backends ImGui_ImplWin32_Init(hwnd); ImGui_ImplVulkan_InitInfo init_info = {}; + //init_info.ApiVersion = VK_API_VERSION_1_3; // Pass in your value of VkApplicationInfo::apiVersion, otherwise will default to header version. init_info.Instance = g_Instance; init_info.PhysicalDevice = g_PhysicalDevice; init_info.Device = g_Device; From e1ae7db4cccf1cb6a516a43dd8f63899f504ca52 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 13 Feb 2025 16:03:40 +0100 Subject: [PATCH 05/11] Backends: Vulkan: Fixed building with older headers not supporting VK_HEADER_VERSION_COMPLETE. (#8326, #8365) --- backends/imgui_impl_vulkan.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/backends/imgui_impl_vulkan.cpp b/backends/imgui_impl_vulkan.cpp index 7be2ed1d1..af084cc0e 100644 --- a/backends/imgui_impl_vulkan.cpp +++ b/backends/imgui_impl_vulkan.cpp @@ -1159,7 +1159,14 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info) bd->VulkanInitInfo = *info; if (bd->VulkanInitInfo.ApiVersion == 0) + { + // We don't care about other versions for now, so don't need to make this exhaustive (with #ifdef VK_VERSION_1_X checks) +#ifdef VK_HEADER_VERSION_COMPLETE bd->VulkanInitInfo.ApiVersion = VK_HEADER_VERSION_COMPLETE; +#else + bd->VulkanInitInfo.ApiVersion = VK_API_VERSION_1_0; +#endif + } ImGui_ImplVulkan_CreateDeviceObjects(); From 98c2f6b0c450b2401a2db97a6c96c042b2bfd404 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 13 Feb 2025 16:19:41 +0100 Subject: [PATCH 06/11] Tables, Error Handling: Recovery from invalid index in TableSetColumnIndex(). (#1651) --- docs/CHANGELOG.txt | 1 + imgui_tables.cpp | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index ec2180fac..283d485df 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -66,6 +66,7 @@ Other changes: overridden when hot-reloading .ini state. (#7934) - Tables: tamed some .ini settings optimizations to more accurately allow overwriting/hot-reloading settings in more situations. (#7934) +- Tables, Error Handling: Recovery from invalid index in TableSetColumnIndex(). (#1651) - Styles, Tabs: made the Close Button of selected tabs always visible by default, without requiring to hover the tab. (#8387) - Added style.TabCloseButtonMinWidthSelected/TabCloseButtonMinWidthUnselected settings diff --git a/imgui_tables.cpp b/imgui_tables.cpp index b7726e908..6486dccd6 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -2106,7 +2106,11 @@ bool ImGui::TableSetColumnIndex(int column_n) { if (table->CurrentColumn != -1) TableEndCell(table); - IM_ASSERT(column_n >= 0 && table->ColumnsCount); + if ((column_n >= 0 && column_n < table->ColumnsCount) == false) + { + IM_ASSERT_USER_ERROR(column_n >= 0 && column_n < table->ColumnsCount, "TableSetColumnIndex() invalid column index!"); + return false; + } TableBeginCell(table, column_n); } From ec4cd2cb8cf144ea16935806d11d5639a84f73dd Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 14 Feb 2025 12:19:24 +0100 Subject: [PATCH 07/11] Backends: Vulkan: Fixed crash with using no prototypes + *BREAKING* Added ApiVersion to ImGui_ImplVulkan_LoadFunctions(). (#8326, #8365, #8400) --- backends/imgui_impl_vulkan.cpp | 43 ++++++++++++++++++++-------------- backends/imgui_impl_vulkan.h | 2 +- docs/CHANGELOG.txt | 4 ++++ 3 files changed, 30 insertions(+), 19 deletions(-) diff --git a/backends/imgui_impl_vulkan.cpp b/backends/imgui_impl_vulkan.cpp index af084cc0e..7379e000b 100644 --- a/backends/imgui_impl_vulkan.cpp +++ b/backends/imgui_impl_vulkan.cpp @@ -26,6 +26,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2025-02-14: *BREAKING CHANGE*: Added uint32_t api_version to ImGui_ImplVulkan_LoadFunctions(). // 2025-02-13: Vulkan: Added ApiVersion field in ImGui_ImplVulkan_InitInfo. Default to header version if unspecified. Dynamic rendering path loads "vkCmdBeginRendering/vkCmdEndRendering" (without -KHR suffix) on API 1.3. (#8326) // 2025-01-09: Vulkan: Added IMGUI_IMPL_VULKAN_MINIMUM_IMAGE_SAMPLER_POOL_SIZE to clarify how many image sampler descriptors are expected to be available in descriptor pool. (#6642) // 2025-01-06: Vulkan: Added more ImGui_ImplVulkanH_XXXX helper functions to simplify our examples. @@ -1081,22 +1082,34 @@ void ImGui_ImplVulkan_DestroyDeviceObjects() } #ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING -static void ImGui_ImplVulkan_LoadDynamicRenderingFunctions(PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data) +static void ImGui_ImplVulkan_LoadDynamicRenderingFunctions(uint32_t api_version, PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data) { // Manually load those two (see #5446, #8326, #8365) - ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); - ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; - ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR = reinterpret_cast(loader_func(v->ApiVersion < VK_API_VERSION_1_3 ? "vkCmdBeginRenderingKHR" : "vkCmdBeginRendering", user_data)); - ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR = reinterpret_cast(loader_func(v->ApiVersion < VK_API_VERSION_1_3 ? "vkCmdEndRenderingKHR" : "vkCmdEndRendering", user_data)); + ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR = reinterpret_cast(loader_func(api_version < VK_API_VERSION_1_3 ? "vkCmdBeginRenderingKHR" : "vkCmdBeginRendering", user_data)); + ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR = reinterpret_cast(loader_func(api_version < VK_API_VERSION_1_3 ? "vkCmdEndRenderingKHR" : "vkCmdEndRendering", user_data)); } #endif -bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data) +// If unspecified by user, assume that ApiVersion == HeaderVersion + // We don't care about other versions than 1.3 for our checks, so don't need to make this exhaustive (e.g. with all #ifdef VK_VERSION_1_X checks) +static uint32_t ImGui_ImplVulkan_GetDefaultApiVersion() +{ +#ifdef VK_HEADER_VERSION_COMPLETE + return VK_HEADER_VERSION_COMPLETE; +#else + return VK_API_VERSION_1_0; +#endif +} + +bool ImGui_ImplVulkan_LoadFunctions(uint32_t api_version, PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data) { // Load function pointers // You can use the default Vulkan loader using: - // ImGui_ImplVulkan_LoadFunctions([](const char* function_name, void*) { return vkGetInstanceProcAddr(your_vk_isntance, function_name); }); + // ImGui_ImplVulkan_LoadFunctions(VK_API_VERSION_1_3, [](const char* function_name, void*) { return vkGetInstanceProcAddr(your_vk_isntance, function_name); }); // But this would be roughly equivalent to not setting VK_NO_PROTOTYPES. + if (api_version == 0) + api_version = ImGui_ImplVulkan_GetDefaultApiVersion(); + #ifdef IMGUI_IMPL_VULKAN_USE_LOADER #define IMGUI_VULKAN_FUNC_LOAD(func) \ func = reinterpret_cast(loader_func(#func, user_data)); \ @@ -1106,7 +1119,7 @@ bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const ch #undef IMGUI_VULKAN_FUNC_LOAD #ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING - ImGui_ImplVulkan_LoadDynamicRenderingFunctions(loader_func, user_data); + ImGui_ImplVulkan_LoadDynamicRenderingFunctions(api_version, loader_func, user_data); #endif #else IM_UNUSED(loader_func); @@ -1121,11 +1134,14 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info) { IM_ASSERT(g_FunctionsLoaded && "Need to call ImGui_ImplVulkan_LoadFunctions() if IMGUI_IMPL_VULKAN_NO_PROTOTYPES or VK_NO_PROTOTYPES are set!"); + if (info->ApiVersion == 0) + info->ApiVersion = ImGui_ImplVulkan_GetDefaultApiVersion(); + if (info->UseDynamicRendering) { #ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING #ifndef IMGUI_IMPL_VULKAN_USE_LOADER - ImGui_ImplVulkan_LoadDynamicRenderingFunctions([](const char* function_name, void* user_data) { return vkGetInstanceProcAddr((VkInstance)user_data, function_name); }, (void*)info->Instance); + ImGui_ImplVulkan_LoadDynamicRenderingFunctions(info->ApiVersion, [](const char* function_name, void* user_data) { return vkGetInstanceProcAddr((VkInstance)user_data, function_name); }, (void*)info->Instance); #endif IM_ASSERT(ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR != nullptr); IM_ASSERT(ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR != nullptr); @@ -1158,15 +1174,6 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info) IM_ASSERT(info->RenderPass != VK_NULL_HANDLE); bd->VulkanInitInfo = *info; - if (bd->VulkanInitInfo.ApiVersion == 0) - { - // We don't care about other versions for now, so don't need to make this exhaustive (with #ifdef VK_VERSION_1_X checks) -#ifdef VK_HEADER_VERSION_COMPLETE - bd->VulkanInitInfo.ApiVersion = VK_HEADER_VERSION_COMPLETE; -#else - bd->VulkanInitInfo.ApiVersion = VK_API_VERSION_1_0; -#endif - } ImGui_ImplVulkan_CreateDeviceObjects(); diff --git a/backends/imgui_impl_vulkan.h b/backends/imgui_impl_vulkan.h index c8afc92ac..c3f40e138 100644 --- a/backends/imgui_impl_vulkan.h +++ b/backends/imgui_impl_vulkan.h @@ -124,7 +124,7 @@ IMGUI_IMPL_API void ImGui_ImplVulkan_RemoveTexture(VkDescriptorSet d // Optional: load Vulkan functions with a custom function loader // This is only useful with IMGUI_IMPL_VULKAN_NO_PROTOTYPES / VK_NO_PROTOTYPES -IMGUI_IMPL_API bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data = nullptr); +IMGUI_IMPL_API bool ImGui_ImplVulkan_LoadFunctions(uint32_t api_version, PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data = nullptr); // [BETA] Selected render state data shared with callbacks. // This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplVulkan_RenderDrawData() call. diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 283d485df..9ca3a0c81 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -43,6 +43,10 @@ Breaking changes: - Renamed ImFontConfig::GlyphExtraSpacing.x option to GlyphExtraAdvanceX. (#242) - Renamed style.TabMinWidthForCloseButton to style.TabCloseButtonMinWidthUnselected. +- Backends: Vulkan: Added 'uint32_t api_version' argument to ImGui_ImplVulkan_LoadFunctions(). + Note that it was also added to ImGui_ImplVulkan_InitInfo but for the later it is optional. + (#8326, #8365, #8400) + Other changes: From 474305c476a777c94db750c961af5a94c6df4237 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 14 Feb 2025 16:15:09 +0100 Subject: [PATCH 08/11] ImFont: simpler constructor. --- imgui_draw.cpp | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 5bf0f0b18..ca66b6d79 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -3685,21 +3685,8 @@ void ImFontGlyphRangesBuilder::BuildRanges(ImVector* out_ranges) ImFont::ImFont() { - FontSize = 0.0f; - FallbackAdvanceX = 0.0f; - FallbackChar = 0; - EllipsisChar = 0; - EllipsisWidth = EllipsisCharStep = 0.0f; - EllipsisCharCount = 0; - FallbackGlyph = NULL; - ContainerAtlas = NULL; - ConfigData = NULL; - ConfigDataCount = 0; - DirtyLookupTables = false; + memset(this, 0, sizeof(*this)); Scale = 1.0f; - Ascent = Descent = 0.0f; - MetricsTotalSurface = 0; - memset(Used8kPagesMap, 0, sizeof(Used8kPagesMap)); } ImFont::~ImFont() From 2860d7ba05667be5e2e51cf27d658352884800b8 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 14 Feb 2025 19:44:35 +0100 Subject: [PATCH 09/11] Selectable: Fixed horizontal label alignment with SelectableTextAlign.x > 0 and specifying a selectable size. (#8338) Regression from ed7551c1d --- docs/CHANGELOG.txt | 3 ++- imgui_widgets.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 9ca3a0c81..938b83aaf 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -47,7 +47,6 @@ Breaking changes: Note that it was also added to ImGui_ImplVulkan_InitInfo but for the later it is optional. (#8326, #8365, #8400) - Other changes: - Fixed IsItemDeactivatedAfterEdit() signal being broken for Checkbox(), @@ -71,6 +70,8 @@ Other changes: - Tables: tamed some .ini settings optimizations to more accurately allow overwriting/hot-reloading settings in more situations. (#7934) - Tables, Error Handling: Recovery from invalid index in TableSetColumnIndex(). (#1651) +- Selectable: Fixed horizontal label alignment with SelectableTextAlign.x > 0 and + specifying a selectable size. (#8338) - Styles, Tabs: made the Close Button of selected tabs always visible by default, without requiring to hover the tab. (#8387) - Added style.TabCloseButtonMinWidthSelected/TabCloseButtonMinWidthUnselected settings diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 1b56d5944..eb2b26bd0 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -7101,7 +7101,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl // Text stays at the submission position. Alignment/clipping extents ignore SpanAllColumns. if (is_visible) - RenderTextClipped(pos, ImVec2(window->WorkRect.Max.x, pos.y + size.y), label, NULL, &label_size, style.SelectableTextAlign, &bb); + RenderTextClipped(pos, ImVec2(ImMin(pos.x + size.x, window->WorkRect.Max.x), pos.y + size.y), label, NULL, &label_size, style.SelectableTextAlign, &bb); // Automatically close popups if (pressed && (window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiSelectableFlags_NoAutoClosePopups) && (g.LastItemData.ItemFlags & ImGuiItemFlags_AutoClosePopups)) From 78ec1272e962ec9ca5515222cde87ee9f0b1c105 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 14 Feb 2025 21:39:45 +0100 Subject: [PATCH 10/11] ImDrawList: added InitialFringeScale in ImDrawListSharedData. Default to 1.0f. This is to allow some DPI mods with less changes. Only the initial value in SetupDrawListSharedData() will need change. --- imgui.cpp | 1 + imgui_draw.cpp | 3 ++- imgui_internal.h | 3 ++- imgui_widgets.cpp | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 251e46819..c27095fd4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5136,6 +5136,7 @@ static void SetupDrawListSharedData() g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedFill; if (g.IO.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset) g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AllowVtxOffset; + g.DrawListSharedData.InitialFringeScale = 1.0f; // FIXME-DPI: Change this for some DPI scaling experiments. } void ImGui::NewFrame() diff --git a/imgui_draw.cpp b/imgui_draw.cpp index ca66b6d79..3953212a1 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -374,6 +374,7 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst) ImDrawListSharedData::ImDrawListSharedData() { memset(this, 0, sizeof(*this)); + InitialFringeScale = 1.0f; for (int i = 0; i < IM_ARRAYSIZE(ArcFastVtx); i++) { const float a = ((float)i * 2 * IM_PI) / (float)IM_ARRAYSIZE(ArcFastVtx); @@ -433,7 +434,7 @@ void ImDrawList::_ResetForNewFrame() _Path.resize(0); _Splitter.Clear(); CmdBuffer.push_back(ImDrawCmd()); - _FringeScale = 1.0f; + _FringeScale = _Data->InitialFringeScale; } void ImDrawList::_ClearFreeMemory() diff --git a/imgui_internal.h b/imgui_internal.h index b904909d7..e272d5479 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -786,8 +786,9 @@ struct IMGUI_API ImDrawListSharedData float FontScale; // Current/default font scale (== FontSize / Font->FontSize) float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo() float CircleSegmentMaxError; // Number of circle segments to use per pixel of radius for AddCircle() etc - ImVec4 ClipRectFullscreen; // Value for PushClipRectFullscreen() + float InitialFringeScale; // Initial scale to apply to AA fringe ImDrawListFlags InitialFlags; // Initial flags at the beginning of the frame (it is possible to alter flags on a per-drawlist basis afterwards) + ImVec4 ClipRectFullscreen; // Value for PushClipRectFullscreen() ImVector TempBuffer; // Temporary write buffer // Lookup tables diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index eb2b26bd0..2d45c5d51 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -913,7 +913,7 @@ ImRect ImGui::GetWindowScrollbarRect(ImGuiWindow* window, ImGuiAxis axis) const ImRect outer_rect = window->Rect(); const ImRect inner_rect = window->InnerRect; const float scrollbar_size = window->ScrollbarSizes[axis ^ 1]; // (ScrollbarSizes.x = width of Y scrollbar; ScrollbarSizes.y = height of X scrollbar) - IM_ASSERT(scrollbar_size > 0.0f); + IM_ASSERT(scrollbar_size >= 0.0f); const float border_size = IM_ROUND(window->WindowBorderSize * 0.5f); const float border_top = (window->Flags & ImGuiWindowFlags_MenuBar) ? IM_ROUND(g.Style.FrameBorderSize * 0.5f) : 0.0f; if (axis == ImGuiAxis_X) From c4a32a129d55eb66158408b61f51d40907a5aace Mon Sep 17 00:00:00 2001 From: Nico van Bentum Date: Thu, 13 Feb 2025 21:50:12 +0100 Subject: [PATCH 11/11] Tabs: fixed middle-button to close not checking hovering, only close button visibility. (#8399, #8387) Main bug has been here since 54a60aaa4, but it's only ef7ffaff7 which made it very visible. --- docs/CHANGELOG.txt | 4 +++- imgui_widgets.cpp | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 938b83aaf..19b334ba6 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -72,13 +72,15 @@ Other changes: - Tables, Error Handling: Recovery from invalid index in TableSetColumnIndex(). (#1651) - Selectable: Fixed horizontal label alignment with SelectableTextAlign.x > 0 and specifying a selectable size. (#8338) -- Styles, Tabs: made the Close Button of selected tabs always visible by default, +- Tabs, Style: made the Close Button of selected tabs always visible by default, without requiring to hover the tab. (#8387) - Added style.TabCloseButtonMinWidthSelected/TabCloseButtonMinWidthUnselected settings to configure visibility of the Close Button for selected and unselected tabs. (-1: always visible. 0.0f: visible when hovered. >0.0f: visible when hovered if minimum width) - Default for selected tabs: TabCloseButtonMinWidthSelected = -1.0f (always visible) - Default for unselected tabs: TabCloseButtonMinWidthUnselected = 0.0f (visible when hovered) +- Tabs: fixed middle-mouse-button to close tab not checking that close button + is hovered, merely it's visibility. (#8399, #8387) [@nicovanbentum] - TextLinkOpenURL(): fixed default Win32 io.PlatformOpenInShellFn handler to handle UTF-8 regardless of system regional settings. (#7660) [@achabense] - Demo: Combos: demonstrate a very simple way to add a filter to a combo, diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 2d45c5d51..6e08cec22 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -10368,9 +10368,10 @@ void ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb, // 'g.ActiveId==close_button_id' will be true when we are holding on the close button, in which case both hovered booleans are false bool close_button_pressed = false; bool close_button_visible = false; + bool is_hovered = g.HoveredId == tab_id || g.HoveredId == close_button_id || g.ActiveId == tab_id || g.ActiveId == close_button_id; // Any interaction account for this too. + if (close_button_id != 0) { - bool is_hovered = g.HoveredId == tab_id || g.HoveredId == close_button_id || g.ActiveId == tab_id || g.ActiveId == close_button_id; // Any interaction account for this too. if (is_contents_visible) close_button_visible = (g.Style.TabCloseButtonMinWidthSelected < 0.0f) ? true : (is_hovered && bb.GetWidth() >= ImMax(button_sz, g.Style.TabCloseButtonMinWidthSelected)); else @@ -10386,7 +10387,7 @@ void ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb, g.LastItemData = last_item_backup; // Close with middle mouse button - if (!(flags & ImGuiTabItemFlags_NoCloseWithMiddleMouseButton) && IsMouseClicked(2)) + if (is_hovered && !(flags & ImGuiTabItemFlags_NoCloseWithMiddleMouseButton) && IsMouseClicked(2)) close_button_pressed = true; } else if (unsaved_marker_visible)