Skip to content

Commit e55a81d

Browse files
authored
Merge branch 'ocornut:master' into master
2 parents c1dbf43 + 922a11f commit e55a81d

51 files changed

Lines changed: 1458 additions & 675 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/build.yml

Lines changed: 53 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ jobs:
525525
- name: Build example_null (extra warnings, clang 64-bit)
526526
run: make -C examples/example_null WITH_EXTRA_WARNINGS=1
527527

528-
- name: Build example_null (single file build)
528+
- name: Build macOS example_null (single file build)
529529
run: |
530530
cat > example_single_file.cpp <<'EOF'
531531
@@ -536,7 +536,7 @@ jobs:
536536
EOF
537537
clang++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
538538
539-
- name: Build example_null (single file build, c++20)
539+
- name: Build macOS example_null (single file build, c++20)
540540
run: |
541541
cat > example_single_file.cpp <<'EOF'
542542
@@ -547,7 +547,7 @@ jobs:
547547
EOF
548548
clang++ -I. -std=c++20 -Wall -Wformat -o example_single_file example_single_file.cpp
549549
550-
- name: Build example_null (without c++ runtime)
550+
- name: Build macOS example_null (without c++ runtime)
551551
run: |
552552
cat > example_single_file.cpp <<'EOF'
553553
@@ -558,34 +558,38 @@ jobs:
558558
EOF
559559
clang++ -I. -std=c++11 -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp
560560
561-
- name: Build example_glfw_opengl2
561+
- name: Build macOS example_glfw_opengl2
562562
run: make -C examples/example_glfw_opengl2
563+
if: github.event_name == 'workflow_run'
563564

564-
- name: Build example_glfw_opengl3
565+
- name: Build macOS example_glfw_opengl3
565566
run: make -C examples/example_glfw_opengl3
566567
if: github.event_name == 'workflow_run'
567568

568-
- name: Build example_glfw_metal
569+
- name: Build macOS example_glfw_metal
569570
run: make -C examples/example_glfw_metal
570571

571-
- name: Build example_sdl2_metal
572+
- name: Build macOS example_sdl2_metal
572573
run: make -C examples/example_sdl2_metal
573574

574-
- name: Build example_sdl2_opengl2
575+
- name: Build macOS example_sdl2_opengl2
575576
run: make -C examples/example_sdl2_opengl2
576577
if: github.event_name == 'workflow_run'
577578

578-
- name: Build example_sdl2_opengl3
579+
- name: Build macOS example_sdl2_opengl3
579580
run: make -C examples/example_sdl2_opengl3
581+
if: github.event_name == 'workflow_run'
580582

581-
- name: Build example_sdl3_opengl3
583+
- name: Build macOS example_sdl3_opengl3
582584
run: make -C examples/example_sdl3_opengl3
583585

584-
- name: Build example_apple_metal
586+
- name: Build macOS example_apple_metal
585587
run: xcodebuild -project examples/example_apple_metal/example_apple_metal.xcodeproj -target example_apple_metal_macos
588+
if: github.event_name == 'workflow_run'
586589

587-
- name: Build example_apple_opengl2
590+
- name: Build macOS example_apple_opengl2
588591
run: xcodebuild -project examples/example_apple_opengl2/example_apple_opengl2.xcodeproj -target example_osx_opengl2
592+
if: github.event_name == 'workflow_run'
589593

590594
Build-iOS:
591595
runs-on: macos-14
@@ -750,40 +754,40 @@ jobs:
750754
working-directory: ${{ github.workspace }}/imgui_test_engine/imgui_test_suite
751755
run: ./imgui_test_suite -nogui -nopause -v2 -ve4 -viewport-mock viewport
752756

753-
Test-MacOS:
754-
runs-on: macos-latest
755-
name: Test - MacOS
756-
757-
defaults:
758-
run:
759-
working-directory: ${{ github.workspace }}/imgui
760-
761-
steps:
762-
- uses: actions/checkout@v5
763-
with:
764-
path: ${{ github.workspace }}/imgui
765-
766-
- uses: actions/checkout@v5
767-
with:
768-
fetch-depth: 1
769-
repository: ocornut/imgui_test_engine
770-
path: ${{ github.workspace }}/imgui_test_engine
771-
submodules: true
772-
773-
- name: Build Tests
774-
working-directory: ${{ github.workspace }}/imgui_test_engine/imgui_test_suite
775-
run: make -j$(nproc)
776-
777-
- name: Run Tests
778-
working-directory: ${{ github.workspace }}/imgui_test_engine/imgui_test_suite
779-
run: ./imgui_test_suite -nogui -nopause -v2 -ve4 tests
780-
781-
- name: Check for Docking
782-
id: check_docking
783-
working-directory: ${{ github.workspace }}/imgui
784-
run: echo "has_dock=$(grep -q "#define IMGUI_HAS_DOCK" imgui.h && echo true || echo false)" >> $GITHUB_OUTPUT
785-
786-
- name: Run Viewport Tests
787-
if: steps.check_docking.outputs.has_dock == 'true'
788-
working-directory: ${{ github.workspace }}/imgui_test_engine/imgui_test_suite
789-
run: ./imgui_test_suite -nogui -nopause -v2 -ve4 -viewport-mock viewport
757+
# Test-MacOS:
758+
# runs-on: macos-latest
759+
# name: Test - MacOS
760+
#
761+
# defaults:
762+
# run:
763+
# working-directory: ${{ github.workspace }}/imgui
764+
#
765+
# steps:
766+
# - uses: actions/checkout@v5
767+
# with:
768+
# path: ${{ github.workspace }}/imgui
769+
#
770+
# - uses: actions/checkout@v5
771+
# with:
772+
# fetch-depth: 1
773+
# repository: ocornut/imgui_test_engine
774+
# path: ${{ github.workspace }}/imgui_test_engine
775+
# submodules: true
776+
#
777+
# - name: Build Tests
778+
# working-directory: ${{ github.workspace }}/imgui_test_engine/imgui_test_suite
779+
# run: make -j$(nproc)
780+
#
781+
# - name: Run Tests
782+
# working-directory: ${{ github.workspace }}/imgui_test_engine/imgui_test_suite
783+
# run: ./imgui_test_suite -nogui -nopause -v2 -ve4 tests
784+
#
785+
# - name: Check for Docking
786+
# id: check_docking
787+
# working-directory: ${{ github.workspace }}/imgui
788+
# run: echo "has_dock=$(grep -q "#define IMGUI_HAS_DOCK" imgui.h && echo true || echo false)" >> $GITHUB_OUTPUT
789+
#
790+
# - name: Run Viewport Tests
791+
# if: steps.check_docking.outputs.has_dock == 'true'
792+
# working-directory: ${{ github.workspace }}/imgui_test_engine/imgui_test_suite
793+
# run: ./imgui_test_suite -nogui -nopause -v2 -ve4 -viewport-mock viewport

backends/imgui_impl_dx12.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,7 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
624624
// (2) there exists a version of d3d12.dll for Windows 7 (D3D12On7) in one of the following directories.
625625
// See https://github.com/ocornut/imgui/pull/3696 for details.
626626
const char* localD3d12Paths[] = { ".\\d3d12.dll", ".\\d3d12on7\\d3d12.dll", ".\\12on7\\d3d12.dll" }; // A. current directory, B. used by some games, C. used in Microsoft D3D12On7 sample
627-
for (int i = 0; i < IM_ARRAYSIZE(localD3d12Paths); i++)
627+
for (int i = 0; i < IM_COUNTOF(localD3d12Paths); i++)
628628
if ((d3d12_dll = ::LoadLibraryA(localD3d12Paths[i])) != nullptr)
629629
break;
630630

backends/imgui_impl_glfw.cpp

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929

3030
// CHANGELOG
3131
// (minor and older changes stripped away, please see git history for details)
32+
// 2025-12-12: Added IMGUI_IMPL_GLFW_DISABLE_X11 / IMGUI_IMPL_GLFW_DISABLE_WAYLAND to forcefully disable either.
33+
// 2025-12-10: Avoid repeated glfwSetCursor()/glfwSetInputMode() calls when unnecessary. Lowers overhead for very high framerates (e.g. 10k+ FPS).
3234
// 2025-11-06: Lower minimum requirement to GLFW 3.0. Though a recent version e.g GLFW 3.4 is highly recommended.
3335
// 2025-09-18: Call platform_io.ClearPlatformHandlers() on shutdown.
3436
// 2025-09-15: Content Scales are always reported as 1.0 on Wayland. FramebufferScale are always reported as 1.0 on X11. (#8920, #8921)
@@ -108,10 +110,15 @@
108110
#endif
109111

110112
// GLFW
111-
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
112-
#define GLFW_HAS_X11_OR_WAYLAND 1
113+
#if !defined(IMGUI_IMPL_GLFW_DISABLE_X11) && (defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__))
114+
#define GLFW_HAS_X11 1
113115
#else
114-
#define GLFW_HAS_X11_OR_WAYLAND 0
116+
#define GLFW_HAS_X11 0
117+
#endif
118+
#if !defined(IMGUI_IMPL_GLFW_DISABLE_WAYLAND) && (defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__))
119+
#define GLFW_HAS_WAYLAND 1
120+
#else
121+
#define GLFW_HAS_WAYLAND 0
115122
#endif
116123
#include <GLFW/glfw3.h>
117124
#ifdef _WIN32
@@ -125,7 +132,7 @@
125132
#define GLFW_EXPOSE_NATIVE_COCOA
126133
#endif
127134
#include <GLFW/glfw3native.h>
128-
#elif GLFW_HAS_X11_OR_WAYLAND
135+
#elif GLFW_HAS_X11
129136
#ifndef GLFW_EXPOSE_NATIVE_X11 // for glfwGetX11Display(), glfwGetX11Window() on Freedesktop (Linux, BSD, etc.)
130137
#define GLFW_EXPOSE_NATIVE_X11
131138
#endif
@@ -188,6 +195,7 @@ struct ImGui_ImplGlfw_Data
188195
GLFWwindow* MouseWindow;
189196
#if GLFW_HAS_CREATECURSOR
190197
GLFWcursor* MouseCursors[ImGuiMouseCursor_COUNT];
198+
GLFWcursor* LastMouseCursor;
191199
#endif
192200
ImVec2 LastValidMousePos;
193201
bool IsWayland;
@@ -237,7 +245,7 @@ static ImGui_ImplGlfw_Data* ImGui_ImplGlfw_GetBackendData(GLFWwindow* window)
237245
// Functions
238246
static bool ImGui_ImplGlfw_IsWayland()
239247
{
240-
#if !GLFW_HAS_X11_OR_WAYLAND
248+
#if !GLFW_HAS_WAYLAND
241249
return false;
242250
#elif GLFW_HAS_GETPLATFORM
243251
return glfwGetPlatform() == GLFW_PLATFORM_WAYLAND;
@@ -446,7 +454,7 @@ static int ImGui_ImplGlfw_TranslateUntranslatedKey(int key, int scancode)
446454
{
447455
const char char_names[] = "`-=[]\\,;\'./";
448456
const int char_keys[] = { GLFW_KEY_GRAVE_ACCENT, GLFW_KEY_MINUS, GLFW_KEY_EQUAL, GLFW_KEY_LEFT_BRACKET, GLFW_KEY_RIGHT_BRACKET, GLFW_KEY_BACKSLASH, GLFW_KEY_COMMA, GLFW_KEY_SEMICOLON, GLFW_KEY_APOSTROPHE, GLFW_KEY_PERIOD, GLFW_KEY_SLASH, 0 };
449-
IM_ASSERT(IM_ARRAYSIZE(char_names) == IM_ARRAYSIZE(char_keys));
457+
IM_ASSERT(IM_COUNTOF(char_names) == IM_COUNTOF(char_keys));
450458
if (key_name[0] >= '0' && key_name[0] <= '9') { key = GLFW_KEY_0 + (key_name[0] - '0'); }
451459
else if (key_name[0] >= 'A' && key_name[0] <= 'Z') { key = GLFW_KEY_A + (key_name[0] - 'A'); }
452460
else if (key_name[0] >= 'a' && key_name[0] <= 'z') { key = GLFW_KEY_A + (key_name[0] - 'a'); }
@@ -849,15 +857,24 @@ static void ImGui_ImplGlfw_UpdateMouseCursor()
849857
GLFWwindow* window = bd->Window;
850858
if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor)
851859
{
852-
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
853-
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
860+
if (bd->LastMouseCursor != nullptr)
861+
{
862+
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
863+
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
864+
bd->LastMouseCursor = nullptr;
865+
}
854866
}
855867
else
856868
{
857869
// Show OS mouse cursor
858870
// FIXME-PLATFORM: Unfocused windows seems to fail changing the mouse cursor with GLFW 3.2, but 3.3 works here.
859871
#if GLFW_HAS_CREATECURSOR
860-
glfwSetCursor(window, bd->MouseCursors[imgui_cursor] ? bd->MouseCursors[imgui_cursor] : bd->MouseCursors[ImGuiMouseCursor_Arrow]);
872+
GLFWcursor* cursor = bd->MouseCursors[imgui_cursor] ? bd->MouseCursors[imgui_cursor] : bd->MouseCursors[ImGuiMouseCursor_Arrow];
873+
if (bd->LastMouseCursor != cursor)
874+
{
875+
glfwSetCursor(window, cursor);
876+
bd->LastMouseCursor = cursor;
877+
}
861878
#endif
862879
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
863880
}
@@ -922,7 +939,7 @@ static void ImGui_ImplGlfw_UpdateGamepads()
922939
// - Some accessibility applications are declaring virtual monitors with a DPI of 0.0f, see #7902. We preserve this value for caller to handle.
923940
float ImGui_ImplGlfw_GetContentScaleForWindow(GLFWwindow* window)
924941
{
925-
#if GLFW_HAS_X11_OR_WAYLAND
942+
#if GLFW_HAS_WAYLAND
926943
if (ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window))
927944
if (bd->IsWayland)
928945
return 1.0f;
@@ -939,7 +956,7 @@ float ImGui_ImplGlfw_GetContentScaleForWindow(GLFWwindow* window)
939956

940957
float ImGui_ImplGlfw_GetContentScaleForMonitor(GLFWmonitor* monitor)
941958
{
942-
#if GLFW_HAS_X11_OR_WAYLAND
959+
#if GLFW_HAS_WAYLAND
943960
if (ImGui_ImplGlfw_IsWayland()) // We can't access our bd->IsWayland cache for a monitor.
944961
return 1.0f;
945962
#endif
@@ -961,7 +978,7 @@ static void ImGui_ImplGlfw_GetWindowSizeAndFramebufferScale(GLFWwindow* window,
961978
glfwGetFramebufferSize(window, &display_w, &display_h);
962979
float fb_scale_x = (w > 0) ? (float)display_w / (float)w : 1.0f;
963980
float fb_scale_y = (h > 0) ? (float)display_h / (float)h : 1.0f;
964-
#if GLFW_HAS_X11_OR_WAYLAND
981+
#if GLFW_HAS_WAYLAND
965982
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window);
966983
if (!bd->IsWayland)
967984
fb_scale_x = fb_scale_y = 1.0f;

backends/imgui_impl_glfw.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// dear imgui: Platform Backend for GLFW
22
// This needs to be used along with a Renderer (e.g. OpenGL3, Vulkan, WebGPU..)
33
// (Info: GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.)
4+
// (Requires: GLFW 3.0+. Prefer GLFW 3.3+/3.4+ for full feature support.)
45

56
// Implemented features:
67
// [X] Platform: Clipboard support.

backends/imgui_impl_opengl3.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
// CHANGELOG
2525
// (minor and older changes stripped away, please see git history for details)
26+
// 2025-12-11: OpenGL: Fixed embedded loader multiple init/shutdown cycles broken on some platforms. (#8792, #9112)
2627
// 2025-09-18: Call platform_io.ClearRendererHandlers() on shutdown.
2728
// 2025-07-22: OpenGL: Add and call embedded loader shutdown during ImGui_ImplOpenGL3_Shutdown() to facilitate multiple init/shutdown cycles in same process. (#8792)
2829
// 2025-07-15: OpenGL: Set GL_UNPACK_ALIGNMENT to 1 before updating textures (#8802) + restore non-WebGL/ES update path that doesn't require a CPU-side copy.
@@ -386,7 +387,7 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
386387
glsl_version = "#version 130";
387388
#endif
388389
}
389-
IM_ASSERT((int)strlen(glsl_version) + 2 < IM_ARRAYSIZE(bd->GlslVersionString));
390+
IM_ASSERT((int)strlen(glsl_version) + 2 < IM_COUNTOF(bd->GlslVersionString));
390391
strcpy(bd->GlslVersionString, glsl_version);
391392
strcat(bd->GlslVersionString, "\n");
392393

backends/imgui_impl_opengl3_loader.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,7 @@ static int parse_version(void)
836836
}
837837

838838
static void load_procs(GL3WGetProcAddressProc proc);
839+
static void clear_procs();
839840

840841
int imgl3wInit(void)
841842
{
@@ -855,6 +856,7 @@ int imgl3wInit2(GL3WGetProcAddressProc proc)
855856
void imgl3wShutdown(void)
856857
{
857858
close_libgl();
859+
clear_procs();
858860
}
859861

860862
int imgl3wIsSupported(int major, int minor)
@@ -943,6 +945,13 @@ static void load_procs(GL3WGetProcAddressProc proc)
943945
imgl3wProcs.ptr[i] = proc(proc_names[i]);
944946
}
945947

948+
static void clear_procs()
949+
{
950+
size_t i;
951+
for (i = 0; i < GL3W_ARRAY_SIZE(proc_names); i++)
952+
imgl3wProcs.ptr[i] = nullptr;
953+
}
954+
946955
#ifdef __cplusplus
947956
}
948957
#endif

backends/imgui_impl_vulkan.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,7 +1002,7 @@ static VkPipeline ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAlloc
10021002
VkDynamicState dynamic_states[2] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
10031003
VkPipelineDynamicStateCreateInfo dynamic_state = {};
10041004
dynamic_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
1005-
dynamic_state.dynamicStateCount = (uint32_t)IM_ARRAYSIZE(dynamic_states);
1005+
dynamic_state.dynamicStateCount = (uint32_t)IM_COUNTOF(dynamic_states);
10061006
dynamic_state.pDynamicStates = dynamic_states;
10071007

10081008
VkGraphicsPipelineCreateInfo create_info = {};
@@ -1667,7 +1667,7 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
16671667
check_vk_result(err);
16681668
VkImage backbuffers[16] = {};
16691669
IM_ASSERT(wd->ImageCount >= min_image_count);
1670-
IM_ASSERT(wd->ImageCount < IM_ARRAYSIZE(backbuffers));
1670+
IM_ASSERT(wd->ImageCount < IM_COUNTOF(backbuffers));
16711671
err = vkGetSwapchainImagesKHR(device, wd->Swapchain, &wd->ImageCount, backbuffers);
16721672
check_vk_result(err);
16731673

backends/imgui_impl_win32.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ static bool ImGui_ImplWin32_InitEx(void* hwnd, bool platform_has_own_dc)
197197
"xinput1_2.dll", // DirectX SDK
198198
"xinput1_1.dll" // DirectX SDK
199199
};
200-
for (int n = 0; n < IM_ARRAYSIZE(xinput_dll_names); n++)
200+
for (int n = 0; n < IM_COUNTOF(xinput_dll_names); n++)
201201
if (HMODULE dll = ::LoadLibraryA(xinput_dll_names[n]))
202202
{
203203
bd->XInputDLL = dll;

0 commit comments

Comments
 (0)