From eb19a77848a0e0a581441df47a2e0ec1ab0bebf2 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 17 Nov 2025 15:51:39 +0100 Subject: [PATCH 01/16] Examples: fix example_null Makefile. Amend b885382 --- docs/TODO.txt | 2 +- examples/example_null/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/TODO.txt b/docs/TODO.txt index 111852b43..6107e5dc0 100644 --- a/docs/TODO.txt +++ b/docs/TODO.txt @@ -308,7 +308,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - examples: window minimize, maximize (#583) - examples: provide a zero frame-rate/idle example. - - examples: dx11/dx12: try to use new swapchain blit models (#2970) + - examples: dx11/dx12: try to use new swapchain blit models (#2970, #9031) - backends: report it better when not able to create texture? - backends: glfw: could go idle when minimized? if (glfwGetWindowAttrib(window, GLFW_ICONIFIED)) { glfwWaitEvents(); continue; } // issue: DeltaTime will be super high on resume, perhaps provide a way to let impl know (#440) - backends: opengl: rename imgui_impl_opengl2 to impl_opengl_legacy and imgui_impl_opengl3 to imgui_impl_opengl? (#1900) diff --git a/examples/example_null/Makefile b/examples/example_null/Makefile index 4a67cecd8..9cd0d0635 100644 --- a/examples/example_null/Makefile +++ b/examples/example_null/Makefile @@ -17,7 +17,7 @@ SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) UNAME_S := $(shell uname -s) -CXXFLAGS += -std=c++11 -I$(IMGUI_DIR) +CXXFLAGS += -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends CXXFLAGS += -g -Wall -Wformat LIBS = From 7e919a543c350eb704f60dcddb7e9bc3cb88c3d3 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 17 Nov 2025 15:58:12 +0100 Subject: [PATCH 02/16] Examples: fix example_null Makefile. Amend b885382,eb19a77 --- examples/example_null/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/example_null/Makefile b/examples/example_null/Makefile index 9cd0d0635..91c8dd78c 100644 --- a/examples/example_null/Makefile +++ b/examples/example_null/Makefile @@ -14,6 +14,7 @@ EXE = example_null IMGUI_DIR = ../.. SOURCES = main.cpp SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/backends/imgui_impl_null.cpp OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) UNAME_S := $(shell uname -s) From d99baf332c5c1332c5c0edfe43fcc21875053ea1 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 17 Nov 2025 16:11:05 +0100 Subject: [PATCH 03/16] CI: fixes for example_null building. --- .github/workflows/build.yml | 28 +++++++++++++++++++++++----- docs/CHANGELOG.txt | 2 ++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 92d41dac1..97bd3c94e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -61,7 +61,7 @@ jobs: echo '#define IMGUI_IMPLEMENTATION' >> example_single_file.cpp echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp g++ -I. -Wall -Wformat -shared -o libimgui.dll -Wl,--out-implib,libimgui.a example_single_file.cpp -limm32 - g++ -I. -Wall -Wformat -DIMGUI_API='__declspec(dllimport)' -o example_null.exe examples/example_null/main.cpp -L. -limgui + g++ -I. -Ibackends -Wall -Wformat -DIMGUI_API='__declspec(dllimport)' -o example_null.exe examples/example_null/main.cpp backends/imgui_impl_null.cpp -L. -limgui rm -f example_null.exe libimgui.* example_single_file.* - name: Build example_null (extra warnings, msvc 64-bit) @@ -78,10 +78,11 @@ jobs: #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" + #include "examples/backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF - g++ -I. -Wall -Wformat -o example_single_file.exe example_single_file.cpp -limm32 + g++ -I. -Ibackends -Wall -Wformat -o example_single_file.exe example_single_file.cpp -limm32 - name: Build example_null (with IMGUI_DISABLE_WIN32_FUNCTIONS) shell: bash @@ -91,10 +92,11 @@ jobs: #define IMGUI_DISABLE_WIN32_FUNCTIONS #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" + #include "examples/backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF - g++ -I. -Wall -Wformat -o example_single_file.exe example_single_file.cpp -limm32 + g++ -I. -Ibackends -Wall -Wformat -o example_single_file.exe example_single_file.cpp -limm32 - name: Build example_null (as DLL) shell: cmd @@ -105,8 +107,8 @@ jobs: echo #define IMGUI_IMPLEMENTATION >> example_single_file.cpp echo #include "misc/single_file/imgui_single_file.h" >> example_single_file.cpp - cl.exe /D_USRDLL /D_WINDLL /I. example_single_file.cpp /LD /FeImGui.dll /link - cl.exe /DIMGUI_API=__declspec(dllimport) /I. ImGui.lib /Feexample_null.exe examples/example_null/main.cpp + cl.exe /D_USRDLL /D_WINDLL /I. /Ibackends example_single_file.cpp /LD /FeImGui.dll /link + cl.exe /DIMGUI_API=__declspec(dllimport) /I. ImGui.lib /Feexample_null.exe backends/imgui_impl_null.cpp examples/example_null/main.cpp # Win64 examples are more frequently compilted than the Win32 examples. # More of the Win32 examples requires 'workflow_run' to reduce waste. @@ -294,6 +296,7 @@ jobs: #define IM_ASSERT(x) #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" + #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF @@ -310,6 +313,7 @@ jobs: #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" + #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF @@ -322,6 +326,7 @@ jobs: #define IMGUI_USE_WCHAR32 #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" + #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF @@ -335,6 +340,7 @@ jobs: #define ImDrawIdx unsigned int #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" + #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF @@ -347,6 +353,7 @@ jobs: #define IMGUI_DISABLE_OBSOLETE_FUNCTIONS #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" + #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF @@ -359,6 +366,7 @@ jobs: #define IMGUI_DISABLE_OBSOLETE_KEYIO #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" + #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF @@ -371,6 +379,7 @@ jobs: #define IMGUI_DISABLE_OBSOLETE_KEYIO #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" + #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF @@ -384,6 +393,7 @@ jobs: #define IMGUI_DISABLE_DEBUG_TOOLS #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" + #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF @@ -396,6 +406,7 @@ jobs: #define IMGUI_DISABLE_FILE_FUNCTIONS #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" + #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF @@ -408,6 +419,7 @@ jobs: #define IMGUI_USE_BGRA_PACKED_COLOR #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" + #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF @@ -428,6 +440,7 @@ jobs: operator MyVec4() const { return MyVec4(x, y, z, w); } #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" + #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF @@ -440,6 +453,7 @@ jobs: #define IMGUI_IMPLEMENTATION #define IMGUI_DISABLE_DEMO_WINDOWS #include "misc/single_file/imgui_single_file.h" + #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF @@ -452,6 +466,7 @@ jobs: #define IMGUI_IMPLEMENTATION #define IMGUI_DISABLE_DEMO_WINDOWS #include "misc/single_file/imgui_single_file.h" + #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF @@ -492,6 +507,7 @@ jobs: #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" + #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF @@ -503,6 +519,7 @@ jobs: #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" + #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF @@ -514,6 +531,7 @@ jobs: #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" + #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index e0bf08e69..3ad4d4aa7 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -151,6 +151,8 @@ Other Changes: - Win32: Revert 1.92.4 change of comparing dwPacketNumber, which prevents refreshing accurate gamepad info after focus-out + io.ClearInputKeys(). (#8556) - Examples: + - Null: update examples_null to use imgui_impl_null (which is a bit overengineering + but somehow consistent). - GLFW+WebGPU: update example for latest specs, to work on Emscripten 4.0.10+, latest Dawn-Native and WGPU-Native. (#8381, #8567, #8191, #7435) [@brutpitt] - GLFW+WebGPU: removed unnecessary ImGui_ImplWGPU_InvalidateDeviceObjects() call From 0cf5b93a0a29fef0a367ca72fae818e7e5b8f70b Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 17 Nov 2025 16:18:12 +0100 Subject: [PATCH 04/16] CI, Backends: fixes for example_null building. Add consistent IMGUI_IMPL_API in backend. --- .github/workflows/build.yml | 34 +++++++++++++++++----------------- backends/imgui_impl_null.cpp | 20 ++++++++++---------- backends/imgui_impl_win32.cpp | 12 ++++++------ 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 97bd3c94e..b1403d394 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -300,7 +300,7 @@ jobs: #include "examples/example_null/main.cpp" EOF - g++ -I. -std=c++11 -Wall -Wformat -Wextra -Werror -Wno-zero-as-null-pointer-constant -Wno-double-promotion -Wno-variadic-macros -Wno-empty-body -o example_single_file example_single_file.cpp + g++ -I. -Ibackends -std=c++11 -Wall -Wformat -Wextra -Werror -Wno-zero-as-null-pointer-constant -Wno-double-promotion -Wno-variadic-macros -Wno-empty-body -o example_single_file example_single_file.cpp - name: Build example_null (freetype) run: | @@ -317,7 +317,7 @@ jobs: #include "examples/example_null/main.cpp" EOF - g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp + g++ -I. -Ibackends -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (with ImWchar32) run: | @@ -330,7 +330,7 @@ jobs: #include "examples/example_null/main.cpp" EOF - g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp + g++ -I. -Ibackends -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (with large ImDrawIdx + pointer ImTextureID) run: | @@ -344,7 +344,7 @@ jobs: #include "examples/example_null/main.cpp" EOF - g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp + g++ -I. -Ibackends -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (with IMGUI_DISABLE_OBSOLETE_FUNCTIONS) run: | @@ -357,7 +357,7 @@ jobs: #include "examples/example_null/main.cpp" EOF - g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp + g++ -I. -Ibackends -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (with IMGUI_DISABLE_OBSOLETE_KEYIO) run: | @@ -370,7 +370,7 @@ jobs: #include "examples/example_null/main.cpp" EOF - g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp + g++ -I. -Ibackends -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (with C++20) run: | @@ -383,7 +383,7 @@ jobs: #include "examples/example_null/main.cpp" EOF - g++ -I. -std=c++20 -Wall -Wformat -o example_single_file example_single_file.cpp + g++ -I. -Ibackends -std=c++20 -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (with IMGUI_DISABLE_DEMO_WINDOWS and IMGUI_DISABLE_DEBUG_TOOLS) run: | @@ -397,7 +397,7 @@ jobs: #include "examples/example_null/main.cpp" EOF - g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp + g++ -I. -Ibackends -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (with IMGUI_DISABLE_FILE_FUNCTIONS) run: | @@ -410,7 +410,7 @@ jobs: #include "examples/example_null/main.cpp" EOF - g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp + g++ -I. -Ibackends -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (with IMGUI_USE_BGRA_PACKED_COLOR) run: | @@ -423,7 +423,7 @@ jobs: #include "examples/example_null/main.cpp" EOF - g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp + g++ -I. -Ibackends -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (with IM_VEC2_CLASS_EXTRA and IM_VEC4_CLASS_EXTRA) run: | @@ -444,7 +444,7 @@ jobs: #include "examples/example_null/main.cpp" EOF - g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp + g++ -I. -Ibackends -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (C++26, Clang) run: | @@ -457,7 +457,7 @@ jobs: #include "examples/example_null/main.cpp" EOF - clang++ -I. -std=c++26 -Wall -Wformat -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp + clang++ -I. -Ibackends -std=c++26 -Wall -Wformat -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp - name: Build example_null (without c++ runtime, Clang) run: | @@ -470,7 +470,7 @@ jobs: #include "examples/example_null/main.cpp" EOF - 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 + clang++ -I. -Ibackends -std=c++11 -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp - name: Build example_glfw_opengl2 run: make -C examples/example_glfw_opengl2 @@ -487,7 +487,7 @@ jobs: run: make -C examples/example_sdl2_opengl3 - name: Build with IMGUI_IMPL_VULKAN_NO_PROTOTYPES - run: g++ -c -I. -std=c++11 -DIMGUI_IMPL_VULKAN_NO_PROTOTYPES=1 backends/imgui_impl_vulkan.cpp + run: g++ -c -I. -Ibackends -std=c++11 -DIMGUI_IMPL_VULKAN_NO_PROTOTYPES=1 backends/imgui_impl_vulkan.cpp MacOS: runs-on: macos-latest @@ -511,7 +511,7 @@ jobs: #include "examples/example_null/main.cpp" EOF - clang++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp + clang++ -I. -Ibackends -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (single file build, c++20) run: | @@ -523,7 +523,7 @@ jobs: #include "examples/example_null/main.cpp" EOF - clang++ -I. -std=c++20 -Wall -Wformat -o example_single_file example_single_file.cpp + clang++ -I. -Ibackends -std=c++20 -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (without c++ runtime) run: | @@ -535,7 +535,7 @@ jobs: #include "examples/example_null/main.cpp" EOF - 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 + clang++ -I. -Ibackends -std=c++11 -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp - name: Build example_glfw_opengl2 run: make -C examples/example_glfw_opengl2 diff --git a/backends/imgui_impl_null.cpp b/backends/imgui_impl_null.cpp index eb99f5313..9503b1789 100644 --- a/backends/imgui_impl_null.cpp +++ b/backends/imgui_impl_null.cpp @@ -17,46 +17,46 @@ #ifndef IMGUI_DISABLE #include "imgui_impl_null.h" -bool ImGui_ImplNull_Init() +IMGUI_IMPL_API bool ImGui_ImplNull_Init() { ImGui_ImplNullPlatform_Init(); ImGui_ImplNullRender_Init(); return true; } -void ImGui_ImplNull_Shutdown() +IMGUI_IMPL_API void ImGui_ImplNull_Shutdown() { ImGui_ImplNullRender_Shutdown(); ImGui_ImplNullPlatform_Shutdown(); } -void ImGui_ImplNull_NewFrame() +IMGUI_IMPL_API void ImGui_ImplNull_NewFrame() { ImGui_ImplNullPlatform_NewFrame(); ImGui_ImplNullRender_NewFrame(); } -bool ImGui_ImplNullPlatform_Init() +IMGUI_IMPL_API bool ImGui_ImplNullPlatform_Init() { ImGuiIO& io = ImGui::GetIO(); io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; return true; } -void ImGui_ImplNullPlatform_Shutdown() +IMGUI_IMPL_API void ImGui_ImplNullPlatform_Shutdown() { ImGuiIO& io = ImGui::GetIO(); io.BackendFlags &= ~ImGuiBackendFlags_HasMouseCursors; } -void ImGui_ImplNullPlatform_NewFrame() +IMGUI_IMPL_API void ImGui_ImplNullPlatform_NewFrame() { ImGuiIO& io = ImGui::GetIO(); io.DisplaySize = ImVec2(1920, 1080); io.DeltaTime = 1.0f / 60.0f; } -bool ImGui_ImplNullRender_Init() +IMGUI_IMPL_API bool ImGui_ImplNullRender_Init() { ImGuiIO& io = ImGui::GetIO(); io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; @@ -64,14 +64,14 @@ bool ImGui_ImplNullRender_Init() return true; } -void ImGui_ImplNullRender_Shutdown() +IMGUI_IMPL_API void ImGui_ImplNullRender_Shutdown() { ImGuiIO& io = ImGui::GetIO(); io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset; io.BackendFlags &= ~ImGuiBackendFlags_RendererHasTextures; } -void ImGui_ImplNullRender_NewFrame() +IMGUI_IMPL_API void ImGui_ImplNullRender_NewFrame() { } @@ -86,7 +86,7 @@ void ImGui_ImplNullRender_UpdateTexture(ImTextureData* tex) } } -void ImGui_ImplNullRender_RenderDrawData(ImDrawData* draw_data) +IMGUI_IMPL_API void ImGui_ImplNullRender_RenderDrawData(ImDrawData* draw_data) { if (draw_data->Textures != nullptr) for (ImTextureData* tex : *draw_data->Textures) diff --git a/backends/imgui_impl_win32.cpp b/backends/imgui_impl_win32.cpp index dc7e66f02..2973f6178 100644 --- a/backends/imgui_impl_win32.cpp +++ b/backends/imgui_impl_win32.cpp @@ -220,7 +220,7 @@ IMGUI_IMPL_API bool ImGui_ImplWin32_InitForOpenGL(void* hwnd) return ImGui_ImplWin32_InitEx(hwnd, true); } -void ImGui_ImplWin32_Shutdown() +IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown() { ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(); IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?"); @@ -392,7 +392,7 @@ static void ImGui_ImplWin32_UpdateGamepads(ImGuiIO& io) #endif } -void ImGui_ImplWin32_NewFrame() +IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame() { ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(); IM_ASSERT(bd != nullptr && "Context or backend not initialized? Did you call ImGui_ImplWin32_Init()?"); @@ -861,7 +861,7 @@ typedef HRESULT(WINAPI* PFN_GetDpiForMonitor)(HMONITOR, MONITOR_DPI_TYPE, UINT*, typedef DPI_AWARENESS_CONTEXT(WINAPI* PFN_SetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); // User32.lib + dll, Windows 10 v1607+ (Creators Update) // Helper function to enable DPI awareness without setting up a manifest -void ImGui_ImplWin32_EnableDpiAwareness() +IMGUI_IMPL_API void ImGui_ImplWin32_EnableDpiAwareness() { if (_IsWindows10OrGreater()) { @@ -890,7 +890,7 @@ void ImGui_ImplWin32_EnableDpiAwareness() #pragma comment(lib, "gdi32") // Link with gdi32.lib for GetDeviceCaps(). MinGW will require linking with '-lgdi32' #endif -float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor) +IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor) { UINT xdpi = 96, ydpi = 96; if (_IsWindows8Point1OrGreater()) @@ -916,7 +916,7 @@ float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor) return xdpi / 96.0f; } -float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd) +IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd) { HMONITOR monitor = ::MonitorFromWindow((HWND)hwnd, MONITOR_DEFAULTTONEAREST); return ImGui_ImplWin32_GetDpiScaleForMonitor(monitor); @@ -933,7 +933,7 @@ float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd) // [experimental] // Borrowed from GLFW's function updateFramebufferTransparency() in src/win32_window.c // (the Dwm* functions are Vista era functions but we are borrowing logic from GLFW) -void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd) +IMGUI_IMPL_API void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd) { if (!_IsWindowsVistaOrGreater()) return; From cfb48969afb3650e40cd5714517c555668894787 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 17 Nov 2025 16:36:54 +0100 Subject: [PATCH 05/16] Examples: CI: backtrack and make example_null embed backend: simpler for all sorts of quick build scripts. --- .github/workflows/build.yml | 62 +++++++------------ backends/imgui_impl_win32.cpp | 12 ++-- examples/example_null/Makefile | 3 +- examples/example_null/build_win32.bat | 2 +- examples/example_null/example_null.vcxproj | 1 - .../example_null/example_null.vcxproj.filters | 5 +- examples/example_null/main.cpp | 6 +- 7 files changed, 36 insertions(+), 55 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b1403d394..92d41dac1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -61,7 +61,7 @@ jobs: echo '#define IMGUI_IMPLEMENTATION' >> example_single_file.cpp echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp g++ -I. -Wall -Wformat -shared -o libimgui.dll -Wl,--out-implib,libimgui.a example_single_file.cpp -limm32 - g++ -I. -Ibackends -Wall -Wformat -DIMGUI_API='__declspec(dllimport)' -o example_null.exe examples/example_null/main.cpp backends/imgui_impl_null.cpp -L. -limgui + g++ -I. -Wall -Wformat -DIMGUI_API='__declspec(dllimport)' -o example_null.exe examples/example_null/main.cpp -L. -limgui rm -f example_null.exe libimgui.* example_single_file.* - name: Build example_null (extra warnings, msvc 64-bit) @@ -78,11 +78,10 @@ jobs: #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" - #include "examples/backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF - g++ -I. -Ibackends -Wall -Wformat -o example_single_file.exe example_single_file.cpp -limm32 + g++ -I. -Wall -Wformat -o example_single_file.exe example_single_file.cpp -limm32 - name: Build example_null (with IMGUI_DISABLE_WIN32_FUNCTIONS) shell: bash @@ -92,11 +91,10 @@ jobs: #define IMGUI_DISABLE_WIN32_FUNCTIONS #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" - #include "examples/backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF - g++ -I. -Ibackends -Wall -Wformat -o example_single_file.exe example_single_file.cpp -limm32 + g++ -I. -Wall -Wformat -o example_single_file.exe example_single_file.cpp -limm32 - name: Build example_null (as DLL) shell: cmd @@ -107,8 +105,8 @@ jobs: echo #define IMGUI_IMPLEMENTATION >> example_single_file.cpp echo #include "misc/single_file/imgui_single_file.h" >> example_single_file.cpp - cl.exe /D_USRDLL /D_WINDLL /I. /Ibackends example_single_file.cpp /LD /FeImGui.dll /link - cl.exe /DIMGUI_API=__declspec(dllimport) /I. ImGui.lib /Feexample_null.exe backends/imgui_impl_null.cpp examples/example_null/main.cpp + cl.exe /D_USRDLL /D_WINDLL /I. example_single_file.cpp /LD /FeImGui.dll /link + cl.exe /DIMGUI_API=__declspec(dllimport) /I. ImGui.lib /Feexample_null.exe examples/example_null/main.cpp # Win64 examples are more frequently compilted than the Win32 examples. # More of the Win32 examples requires 'workflow_run' to reduce waste. @@ -296,11 +294,10 @@ jobs: #define IM_ASSERT(x) #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" - #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF - g++ -I. -Ibackends -std=c++11 -Wall -Wformat -Wextra -Werror -Wno-zero-as-null-pointer-constant -Wno-double-promotion -Wno-variadic-macros -Wno-empty-body -o example_single_file example_single_file.cpp + g++ -I. -std=c++11 -Wall -Wformat -Wextra -Werror -Wno-zero-as-null-pointer-constant -Wno-double-promotion -Wno-variadic-macros -Wno-empty-body -o example_single_file example_single_file.cpp - name: Build example_null (freetype) run: | @@ -313,11 +310,10 @@ jobs: #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" - #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF - g++ -I. -Ibackends -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp + g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (with ImWchar32) run: | @@ -326,11 +322,10 @@ jobs: #define IMGUI_USE_WCHAR32 #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" - #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF - g++ -I. -Ibackends -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp + g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (with large ImDrawIdx + pointer ImTextureID) run: | @@ -340,11 +335,10 @@ jobs: #define ImDrawIdx unsigned int #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" - #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF - g++ -I. -Ibackends -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp + g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (with IMGUI_DISABLE_OBSOLETE_FUNCTIONS) run: | @@ -353,11 +347,10 @@ jobs: #define IMGUI_DISABLE_OBSOLETE_FUNCTIONS #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" - #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF - g++ -I. -Ibackends -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp + g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (with IMGUI_DISABLE_OBSOLETE_KEYIO) run: | @@ -366,11 +359,10 @@ jobs: #define IMGUI_DISABLE_OBSOLETE_KEYIO #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" - #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF - g++ -I. -Ibackends -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp + g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (with C++20) run: | @@ -379,11 +371,10 @@ jobs: #define IMGUI_DISABLE_OBSOLETE_KEYIO #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" - #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF - g++ -I. -Ibackends -std=c++20 -Wall -Wformat -o example_single_file example_single_file.cpp + g++ -I. -std=c++20 -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (with IMGUI_DISABLE_DEMO_WINDOWS and IMGUI_DISABLE_DEBUG_TOOLS) run: | @@ -393,11 +384,10 @@ jobs: #define IMGUI_DISABLE_DEBUG_TOOLS #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" - #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF - g++ -I. -Ibackends -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp + g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (with IMGUI_DISABLE_FILE_FUNCTIONS) run: | @@ -406,11 +396,10 @@ jobs: #define IMGUI_DISABLE_FILE_FUNCTIONS #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" - #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF - g++ -I. -Ibackends -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp + g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (with IMGUI_USE_BGRA_PACKED_COLOR) run: | @@ -419,11 +408,10 @@ jobs: #define IMGUI_USE_BGRA_PACKED_COLOR #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" - #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF - g++ -I. -Ibackends -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp + g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (with IM_VEC2_CLASS_EXTRA and IM_VEC4_CLASS_EXTRA) run: | @@ -440,11 +428,10 @@ jobs: operator MyVec4() const { return MyVec4(x, y, z, w); } #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" - #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF - g++ -I. -Ibackends -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp + g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (C++26, Clang) run: | @@ -453,11 +440,10 @@ jobs: #define IMGUI_IMPLEMENTATION #define IMGUI_DISABLE_DEMO_WINDOWS #include "misc/single_file/imgui_single_file.h" - #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF - clang++ -I. -Ibackends -std=c++26 -Wall -Wformat -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp + clang++ -I. -std=c++26 -Wall -Wformat -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp - name: Build example_null (without c++ runtime, Clang) run: | @@ -466,11 +452,10 @@ jobs: #define IMGUI_IMPLEMENTATION #define IMGUI_DISABLE_DEMO_WINDOWS #include "misc/single_file/imgui_single_file.h" - #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF - clang++ -I. -Ibackends -std=c++11 -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp + 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 - name: Build example_glfw_opengl2 run: make -C examples/example_glfw_opengl2 @@ -487,7 +472,7 @@ jobs: run: make -C examples/example_sdl2_opengl3 - name: Build with IMGUI_IMPL_VULKAN_NO_PROTOTYPES - run: g++ -c -I. -Ibackends -std=c++11 -DIMGUI_IMPL_VULKAN_NO_PROTOTYPES=1 backends/imgui_impl_vulkan.cpp + run: g++ -c -I. -std=c++11 -DIMGUI_IMPL_VULKAN_NO_PROTOTYPES=1 backends/imgui_impl_vulkan.cpp MacOS: runs-on: macos-latest @@ -507,11 +492,10 @@ jobs: #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" - #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF - clang++ -I. -Ibackends -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp + clang++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (single file build, c++20) run: | @@ -519,11 +503,10 @@ jobs: #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" - #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF - clang++ -I. -Ibackends -std=c++20 -Wall -Wformat -o example_single_file example_single_file.cpp + clang++ -I. -std=c++20 -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (without c++ runtime) run: | @@ -531,11 +514,10 @@ jobs: #define IMGUI_IMPLEMENTATION #include "misc/single_file/imgui_single_file.h" - #include "backends/imgui_impl_null.cpp" #include "examples/example_null/main.cpp" EOF - clang++ -I. -Ibackends -std=c++11 -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp + 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 - name: Build example_glfw_opengl2 run: make -C examples/example_glfw_opengl2 diff --git a/backends/imgui_impl_win32.cpp b/backends/imgui_impl_win32.cpp index 2973f6178..dc7e66f02 100644 --- a/backends/imgui_impl_win32.cpp +++ b/backends/imgui_impl_win32.cpp @@ -220,7 +220,7 @@ IMGUI_IMPL_API bool ImGui_ImplWin32_InitForOpenGL(void* hwnd) return ImGui_ImplWin32_InitEx(hwnd, true); } -IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown() +void ImGui_ImplWin32_Shutdown() { ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(); IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?"); @@ -392,7 +392,7 @@ static void ImGui_ImplWin32_UpdateGamepads(ImGuiIO& io) #endif } -IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame() +void ImGui_ImplWin32_NewFrame() { ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(); IM_ASSERT(bd != nullptr && "Context or backend not initialized? Did you call ImGui_ImplWin32_Init()?"); @@ -861,7 +861,7 @@ typedef HRESULT(WINAPI* PFN_GetDpiForMonitor)(HMONITOR, MONITOR_DPI_TYPE, UINT*, typedef DPI_AWARENESS_CONTEXT(WINAPI* PFN_SetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); // User32.lib + dll, Windows 10 v1607+ (Creators Update) // Helper function to enable DPI awareness without setting up a manifest -IMGUI_IMPL_API void ImGui_ImplWin32_EnableDpiAwareness() +void ImGui_ImplWin32_EnableDpiAwareness() { if (_IsWindows10OrGreater()) { @@ -890,7 +890,7 @@ IMGUI_IMPL_API void ImGui_ImplWin32_EnableDpiAwareness() #pragma comment(lib, "gdi32") // Link with gdi32.lib for GetDeviceCaps(). MinGW will require linking with '-lgdi32' #endif -IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor) +float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor) { UINT xdpi = 96, ydpi = 96; if (_IsWindows8Point1OrGreater()) @@ -916,7 +916,7 @@ IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor) return xdpi / 96.0f; } -IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd) +float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd) { HMONITOR monitor = ::MonitorFromWindow((HWND)hwnd, MONITOR_DEFAULTTONEAREST); return ImGui_ImplWin32_GetDpiScaleForMonitor(monitor); @@ -933,7 +933,7 @@ IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd) // [experimental] // Borrowed from GLFW's function updateFramebufferTransparency() in src/win32_window.c // (the Dwm* functions are Vista era functions but we are borrowing logic from GLFW) -IMGUI_IMPL_API void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd) +void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd) { if (!_IsWindowsVistaOrGreater()) return; diff --git a/examples/example_null/Makefile b/examples/example_null/Makefile index 91c8dd78c..4a67cecd8 100644 --- a/examples/example_null/Makefile +++ b/examples/example_null/Makefile @@ -14,11 +14,10 @@ EXE = example_null IMGUI_DIR = ../.. SOURCES = main.cpp SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp -SOURCES += $(IMGUI_DIR)/backends/imgui_impl_null.cpp OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) UNAME_S := $(shell uname -s) -CXXFLAGS += -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends +CXXFLAGS += -std=c++11 -I$(IMGUI_DIR) CXXFLAGS += -g -Wall -Wformat LIBS = diff --git a/examples/example_null/build_win32.bat b/examples/example_null/build_win32.bat index 3a07d8f8d..be81d8093 100644 --- a/examples/example_null/build_win32.bat +++ b/examples/example_null/build_win32.bat @@ -1,3 +1,3 @@ @REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. mkdir Debug -cl /nologo /Zi /MD /utf-8 /I ..\.. %* *.cpp ..\..\*.cpp ..\..\backends\imgui_impl_null.cpp /FeDebug/example_null.exe /FoDebug/ /link gdi32.lib shell32.lib imm32.lib +cl /nologo /Zi /MD /utf-8 /I ..\.. %* *.cpp ..\..\*.cpp /FeDebug/example_null.exe /FoDebug/ /link gdi32.lib shell32.lib imm32.lib diff --git a/examples/example_null/example_null.vcxproj b/examples/example_null/example_null.vcxproj index 7d0d59279..c8836c7e4 100644 --- a/examples/example_null/example_null.vcxproj +++ b/examples/example_null/example_null.vcxproj @@ -151,7 +151,6 @@ - diff --git a/examples/example_null/example_null.vcxproj.filters b/examples/example_null/example_null.vcxproj.filters index f5dd02f2d..9b485d5f4 100644 --- a/examples/example_null/example_null.vcxproj.filters +++ b/examples/example_null/example_null.vcxproj.filters @@ -18,9 +18,6 @@ imgui - - sources - @@ -54,4 +51,4 @@ imgui - + \ No newline at end of file diff --git a/examples/example_null/main.cpp b/examples/example_null/main.cpp index 5e94a6fb6..eba675670 100644 --- a/examples/example_null/main.cpp +++ b/examples/example_null/main.cpp @@ -3,7 +3,11 @@ // This is useful to test building, but you cannot interact with anything here! #include "imgui.h" #include -#include "imgui_impl_null.h" + +// For imgui_impl_null: use relative filename + embed implementation directly by including the .cpp file. +// This is to simplify casual building of this example from all sorts of test scripts. +#include "../../backends/imgui_impl_null.h" +#include "../../backends/imgui_impl_null.cpp" int main(int, char**) { From e1f9b8b3a76dff38968b5e0599c80a1b85dd0f6f Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 17 Nov 2025 16:49:34 +0100 Subject: [PATCH 06/16] CI: fixes warning building example_null w/ mingw 64-bit, as DLL --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 92d41dac1..5511d55fe 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -61,7 +61,7 @@ jobs: echo '#define IMGUI_IMPLEMENTATION' >> example_single_file.cpp echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp g++ -I. -Wall -Wformat -shared -o libimgui.dll -Wl,--out-implib,libimgui.a example_single_file.cpp -limm32 - g++ -I. -Wall -Wformat -DIMGUI_API='__declspec(dllimport)' -o example_null.exe examples/example_null/main.cpp -L. -limgui + g++ -I. -Wall -Wformat -DIMGUI_API=__declspec(dllimport) -DIMGUI_IMPL_API= -o example_null.exe examples/example_null/main.cpp -L. -limgui rm -f example_null.exe libimgui.* example_single_file.* - name: Build example_null (extra warnings, msvc 64-bit) From 04af1a39176e0789982038b2c33431336e21913e Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 17 Nov 2025 17:43:09 +0100 Subject: [PATCH 07/16] CI: fixes warning building example_null w/ mingw 64-bit, as DLL --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5511d55fe..cc6208516 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -61,7 +61,7 @@ jobs: echo '#define IMGUI_IMPLEMENTATION' >> example_single_file.cpp echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp g++ -I. -Wall -Wformat -shared -o libimgui.dll -Wl,--out-implib,libimgui.a example_single_file.cpp -limm32 - g++ -I. -Wall -Wformat -DIMGUI_API=__declspec(dllimport) -DIMGUI_IMPL_API= -o example_null.exe examples/example_null/main.cpp -L. -limgui + g++ -I. -Wall -Wformat -DIMGUI_API='__declspec(dllimport)' -DIMGUI_IMPL_API= -o example_null.exe examples/example_null/main.cpp -L. -limgui rm -f example_null.exe libimgui.* example_single_file.* - name: Build example_null (extra warnings, msvc 64-bit) From 52caa2f38a15ce6a83c253fa58a6d6ca8e753e9d Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 17 Nov 2025 17:50:37 +0100 Subject: [PATCH 08/16] CI: fixes warning building example_null w/ msvc as DLL --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cc6208516..ab8f507d0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -106,7 +106,7 @@ jobs: echo #include "misc/single_file/imgui_single_file.h" >> example_single_file.cpp cl.exe /D_USRDLL /D_WINDLL /I. example_single_file.cpp /LD /FeImGui.dll /link - cl.exe /DIMGUI_API=__declspec(dllimport) /I. ImGui.lib /Feexample_null.exe examples/example_null/main.cpp + cl.exe /DIMGUI_API=__declspec(dllimport) -DIMGUI_IMPL_API /I. ImGui.lib /Feexample_null.exe examples/example_null/main.cpp # Win64 examples are more frequently compilted than the Win32 examples. # More of the Win32 examples requires 'workflow_run' to reduce waste. From c3835de38a7c4c4c15c7c64fabdcfa7f63169721 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 17 Nov 2025 18:01:51 +0100 Subject: [PATCH 09/16] CI: fixes warning building example_null w/ msvc as DLL --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ab8f507d0..1c9e8dcdb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -106,7 +106,7 @@ jobs: echo #include "misc/single_file/imgui_single_file.h" >> example_single_file.cpp cl.exe /D_USRDLL /D_WINDLL /I. example_single_file.cpp /LD /FeImGui.dll /link - cl.exe /DIMGUI_API=__declspec(dllimport) -DIMGUI_IMPL_API /I. ImGui.lib /Feexample_null.exe examples/example_null/main.cpp + cl.exe /DIMGUI_API=__declspec(dllimport) -DIMGUI_IMPL_API= /I. ImGui.lib /Feexample_null.exe examples/example_null/main.cpp # Win64 examples are more frequently compilted than the Win32 examples. # More of the Win32 examples requires 'workflow_run' to reduce waste. From 9afc62d087bdbb5a951101c351f9d17e22dc6d50 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 18 Nov 2025 16:20:51 +0100 Subject: [PATCH 10/16] InputText: Fixed an assert when using ImGuiInputTextFlags_ReadOnly and making underlying contents shorter while text is selected. (#9069) --- docs/CHANGELOG.txt | 3 +++ imgui_widgets.cpp | 9 ++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 3ad4d4aa7..f7ab1336d 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -87,6 +87,9 @@ Other Changes: keys in order to allow e.g. external Shortcut override behavior. (#9004) - When using a callback to reduce/manipulate the value of BufTextLen, we do not require anymore that CursorPos be clamped by user code. (#9029) + - Fixed an assert when using ImGuiInputTextFlags_ReadOnly and making + underlying contents shorter while text is selected. (#9069, #3237) + (regression from 1.92.3) - InputTextMultiline: fixed a crash when using ImGuiInputTextFlags_WordWrap and resizing the parent window while keeping the multi-line field active (which is most typically achieved when resizing programmatically or via a docking layout diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 89b6d6e6f..0e49d1c19 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -4762,8 +4762,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ state->TextLen = new_len; memcpy(state->TextA.Data, buf, state->TextLen + 1); state->Stb->select_start = state->ReloadSelectionStart; - state->Stb->cursor = state->Stb->select_end = state->ReloadSelectionEnd; - state->CursorClamp(); + state->Stb->cursor = state->Stb->select_end = state->ReloadSelectionEnd; // will be clamped to bounds below } else if ((init_state && g.ActiveId != id) || init_changed_specs) { @@ -4803,9 +4802,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ // Recycle existing cursor/selection/undo stack but clamp position // Note a single mouse click will override the cursor/position immediately by calling stb_textedit_click handler. - if (recycle_state) - state->CursorClamp(); - else + if (!recycle_state) stb_textedit_initialize_state(state->Stb, !is_multiline); if (!is_multiline) @@ -4862,6 +4859,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ // Read-only mode always ever read from source buffer. Refresh TextLen when active. if (is_readonly && state != NULL) state->TextLen = (int)ImStrlen(buf); + if (state != NULL) + state->CursorClamp(); //if (is_readonly && state != NULL) // state->TextA.clear(); // Uncomment to facilitate debugging, but we otherwise prefer to keep/amortize th allocation. } From 6ae32c696a32af58cfe9185e464d65596c9ffafd Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 18 Nov 2025 16:34:35 +0100 Subject: [PATCH 11/16] Backends: fixed misc zealous Clang warnings. --- backends/imgui_impl_dx12.h | 2 +- backends/imgui_impl_glfw.cpp | 10 ++++++---- backends/imgui_impl_null.cpp | 7 ++++++- backends/imgui_impl_sdl3.cpp | 4 ++-- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/backends/imgui_impl_dx12.h b/backends/imgui_impl_dx12.h index 4ff510455..3bb66c1fb 100644 --- a/backends/imgui_impl_dx12.h +++ b/backends/imgui_impl_dx12.h @@ -44,7 +44,7 @@ struct ImGui_ImplDX12_InitInfo D3D12_GPU_DESCRIPTOR_HANDLE LegacySingleSrvGpuDescriptor; #endif - ImGui_ImplDX12_InitInfo() { memset((void*)this, 0, sizeof(*this)); } + ImGui_ImplDX12_InitInfo() { memset(this, 0, sizeof(*this)); } }; // Follow "Getting Started" link and check examples/ folder to learn about using backends! diff --git a/backends/imgui_impl_glfw.cpp b/backends/imgui_impl_glfw.cpp index 9ec9ccbf9..ac176a080 100644 --- a/backends/imgui_impl_glfw.cpp +++ b/backends/imgui_impl_glfw.cpp @@ -101,8 +101,10 @@ // Clang warnings with -Weverything #if defined(__clang__) #pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast -#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness +#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast +#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness +#pragma clang diagnostic ignored "-Wexit-time-destructors" // warning: declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals. +#pragma clang diagnostic ignored "-Wglobal-constructors" // warning: declaration requires a global destructor // similar to above, not sure what the exact difference is. #endif // GLFW @@ -957,8 +959,8 @@ static void ImGui_ImplGlfw_GetWindowSizeAndFramebufferScale(GLFWwindow* window, int display_w, display_h; glfwGetWindowSize(window, &w, &h); glfwGetFramebufferSize(window, &display_w, &display_h); - float fb_scale_x = (w > 0) ? (float)display_w / w : 1.0f; - float fb_scale_y = (h > 0) ? (float)display_h / h : 1.0f; + float fb_scale_x = (w > 0) ? (float)display_w / (float)w : 1.0f; + float fb_scale_y = (h > 0) ? (float)display_h / (float)h : 1.0f; #if GLFW_HAS_X11_OR_WAYLAND ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window); if (!bd->IsWayland) diff --git a/backends/imgui_impl_null.cpp b/backends/imgui_impl_null.cpp index 9503b1789..6bf3ddb22 100644 --- a/backends/imgui_impl_null.cpp +++ b/backends/imgui_impl_null.cpp @@ -17,6 +17,11 @@ #ifndef IMGUI_DISABLE #include "imgui_impl_null.h" +// Clang/GCC warnings with -Weverything +#if defined(__clang__) +#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse. +#endif + IMGUI_IMPL_API bool ImGui_ImplNull_Init() { ImGui_ImplNullPlatform_Init(); @@ -75,7 +80,7 @@ IMGUI_IMPL_API void ImGui_ImplNullRender_NewFrame() { } -void ImGui_ImplNullRender_UpdateTexture(ImTextureData* tex) +static void ImGui_ImplNullRender_UpdateTexture(ImTextureData* tex) { if (tex->Status == ImTextureStatus_WantCreate || tex->Status == ImTextureStatus_WantDestroy) tex->SetStatus(ImTextureStatus_OK); diff --git a/backends/imgui_impl_sdl3.cpp b/backends/imgui_impl_sdl3.cpp index 0a8647794..815929595 100644 --- a/backends/imgui_impl_sdl3.cpp +++ b/backends/imgui_impl_sdl3.cpp @@ -819,8 +819,8 @@ static void ImGui_ImplSDL3_GetWindowSizeAndFramebufferScale(SDL_Window* window, #else int display_w, display_h; SDL_GetWindowSizeInPixels(window, &display_w, &display_h); - float fb_scale_x = (w > 0) ? (float)display_w / w : 1.0f; - float fb_scale_y = (h > 0) ? (float)display_h / h : 1.0f; + float fb_scale_x = (w > 0) ? (float)display_w / (float)w : 1.0f; + float fb_scale_y = (h > 0) ? (float)display_h / (float)h : 1.0f; #endif if (out_size != nullptr) From 91b5256c57002b476ec40c6bf136136f7fe87eaa Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 18 Nov 2025 17:00:01 +0100 Subject: [PATCH 12/16] Clipper: fixed an issue when using up/down from an item outside of visible bound and using the clipper. (#9079) --- docs/CHANGELOG.txt | 3 +++ imgui.cpp | 10 +++++----- imgui.h | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index f7ab1336d..dea1b0a44 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -94,6 +94,9 @@ Other Changes: resizing the parent window while keeping the multi-line field active (which is most typically achieved when resizing programmatically or via a docking layout reacting to a platform window resize). (#3237, #9007) [@anton-kl, @ocornut] +- Nav: + - Clipper: fixed an issue when using up/down from an item outside of + visible bound and using the clipper. (#9079) - Fonts: - Calling ImFontAtlas::Clear() mid-frame without re-adding a font will lead to a more explicit crash. diff --git a/imgui.cpp b/imgui.cpp index fc52026ae..c0fa600b4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3346,10 +3346,12 @@ static bool ImGuiListClipper_StepInternal(ImGuiListClipper* clipper) { // Add range selected to be included for navigation const bool is_nav_request = (g.NavMoveScoringItems && g.NavWindow && g.NavWindow->RootWindowForNav == window->RootWindowForNav); + const int nav_off_min = (is_nav_request && g.NavMoveClipDir == ImGuiDir_Up) ? -1 : 0; + const int nav_off_max = (is_nav_request && g.NavMoveClipDir == ImGuiDir_Down) ? 1 : 0; if (is_nav_request) { - data->Ranges.push_back(ImGuiListClipperRange::FromPositions(g.NavScoringRect.Min.y, g.NavScoringRect.Max.y, 0, 0)); - data->Ranges.push_back(ImGuiListClipperRange::FromPositions(g.NavScoringNoClipRect.Min.y, g.NavScoringNoClipRect.Max.y, 0, 0)); + data->Ranges.push_back(ImGuiListClipperRange::FromPositions(g.NavScoringRect.Min.y, g.NavScoringRect.Max.y, nav_off_min, nav_off_max)); + data->Ranges.push_back(ImGuiListClipperRange::FromPositions(g.NavScoringNoClipRect.Min.y, g.NavScoringNoClipRect.Max.y, nav_off_min, nav_off_max)); } if (is_nav_request && (g.NavMoveFlags & ImGuiNavMoveFlags_IsTabbing) && g.NavTabbingDir == -1) data->Ranges.push_back(ImGuiListClipperRange::FromIndices(clipper->ItemsCount - 1, clipper->ItemsCount)); @@ -3378,9 +3380,7 @@ static bool ImGuiListClipper_StepInternal(ImGuiListClipper* clipper) } // Add main visible range - const int off_min = (is_nav_request && g.NavMoveClipDir == ImGuiDir_Up) ? -1 : 0; - const int off_max = (is_nav_request && g.NavMoveClipDir == ImGuiDir_Down) ? 1 : 0; - data->Ranges.push_back(ImGuiListClipperRange::FromPositions(min_y, max_y, off_min, off_max)); + data->Ranges.push_back(ImGuiListClipperRange::FromPositions(min_y, max_y, nav_off_min, nav_off_max)); } // Convert position ranges to item index ranges diff --git a/imgui.h b/imgui.h index e5e4dda91..d0bf6fa7b 100644 --- a/imgui.h +++ b/imgui.h @@ -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.5 WIP" -#define IMGUI_VERSION_NUM 19246 +#define IMGUI_VERSION_NUM 19247 #define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000 #define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198 From 405c80260776d3c966cdbb4c9d40588cd65f182e Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 18 Nov 2025 17:54:43 +0100 Subject: [PATCH 13/16] Nav: shallow tweaks. --- imgui.cpp | 15 ++++++++------- imgui_internal.h | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c0fa600b4..3332e62bf 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -13808,13 +13808,13 @@ void ImGui::NavUpdateCreateMoveRequest() // Update PageUp/PageDown/Home/End scroll // FIXME-NAV: Consider enabling those keys even without the master ImGuiConfigFlags_NavEnableKeyboard flag? - float scoring_rect_offset_y = 0.0f; + float scoring_page_offset_y = 0.0f; if (window && g.NavMoveDir == ImGuiDir_None && nav_keyboard_active) - scoring_rect_offset_y = NavUpdatePageUpPageDown(); - if (scoring_rect_offset_y != 0.0f) + scoring_page_offset_y = NavUpdatePageUpPageDown(); + if (scoring_page_offset_y != 0.0f) { g.NavScoringNoClipRect = window->InnerRect; - g.NavScoringNoClipRect.TranslateY(scoring_rect_offset_y); + g.NavScoringNoClipRect.TranslateY(scoring_page_offset_y); } // [DEBUG] Always send a request when holding Ctrl. Hold Ctrl + Arrow change the direction. @@ -13879,12 +13879,13 @@ void ImGui::NavUpdateCreateMoveRequest() { ImRect nav_rect_rel = !window->NavRectRel[g.NavLayer].IsInverted() ? window->NavRectRel[g.NavLayer] : ImRect(0, 0, 0, 0); scoring_rect = WindowRectRelToAbs(window, nav_rect_rel); - scoring_rect.TranslateY(scoring_rect_offset_y); + scoring_rect.TranslateY(scoring_page_offset_y); + //GetForegroundDrawList()->AddRectFilled(scoring_rect.Min - ImVec2(1, 1), scoring_rect.Max + ImVec2(1, 1), IM_COL32(255, 100, 0, 80)); // [DEBUG] Pre-bias if (g.NavMoveSubmitted) NavBiasScoringRect(scoring_rect, window->RootWindowForNav->NavPreferredScoringPosRel[g.NavLayer], g.NavMoveDir, g.NavMoveFlags); IM_ASSERT(!scoring_rect.IsInverted()); // Ensure we have a non-inverted bounding box here will allow us to remove extraneous ImFabs() calls in NavScoreItem(). - //GetForegroundDrawList()->AddRect(scoring_rect.Min, scoring_rect.Max, IM_COL32(255,200,0,255)); // [DEBUG] - //if (!g.NavScoringNoClipRect.IsInverted()) { GetForegroundDrawList()->AddRect(g.NavScoringNoClipRect.Min, g.NavScoringNoClipRect.Max, IM_COL32(255, 200, 0, 255)); } // [DEBUG] + //GetForegroundDrawList()->AddRectFilled(scoring_rect.Min - ImVec2(1, 1), scoring_rect.Max + ImVec2(1, 1), IM_COL32(255, 100, 0, 80)); // [DEBUG] Post-bias + //if (!g.NavScoringNoClipRect.IsInverted()) { GetForegroundDrawList()->AddRectFilled(g.NavScoringNoClipRect.Min, g.NavScoringNoClipRect.Max, IM_COL32(100, 255, 0, 80)); } // [DEBUG] } g.NavScoringRect = scoring_rect; //g.NavScoringNoClipRect.Add(scoring_rect); diff --git a/imgui_internal.h b/imgui_internal.h index f16fa73df..88af027d7 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1722,7 +1722,7 @@ enum ImGuiNavMoveFlags_ ImGuiNavMoveFlags_WrapMask_ = ImGuiNavMoveFlags_LoopX | ImGuiNavMoveFlags_LoopY | ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_WrapY, ImGuiNavMoveFlags_AllowCurrentNavId = 1 << 4, // Allow scoring and considering the current NavId as a move target candidate. This is used when the move source is offset (e.g. pressing PageDown actually needs to send a Up move request, if we are pressing PageDown from the bottom-most item we need to stay in place) ImGuiNavMoveFlags_AlsoScoreVisibleSet = 1 << 5, // Store alternate result in NavMoveResultLocalVisible that only comprise elements that are already fully visible (used by PageUp/PageDown) - ImGuiNavMoveFlags_ScrollToEdgeY = 1 << 6, // Force scrolling to min/max (used by Home/End) // FIXME-NAV: Aim to remove or reword, probably unnecessary + ImGuiNavMoveFlags_ScrollToEdgeY = 1 << 6, // Force scrolling to min/max (used by Home/End) // FIXME-NAV: Aim to remove or reword as ImGuiScrollFlags ImGuiNavMoveFlags_Forwarded = 1 << 7, ImGuiNavMoveFlags_DebugNoResult = 1 << 8, // Dummy scoring for debug purpose, don't apply result ImGuiNavMoveFlags_FocusApi = 1 << 9, // Requests from focus API can land/focus/activate items even if they are marked with _NoTabStop (see NavProcessItemForTabbingRequest() for details) From 81e01ddebe166f1dd9942ad8132f9d5846d57237 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 18 Nov 2025 18:57:32 +0100 Subject: [PATCH 14/16] Nav: reworked PageUp/PageDown to pick same-page top/bottom page based on inner rectangle rather than clipping rectangle. --- docs/CHANGELOG.txt | 4 ++++ imgui.cpp | 12 ++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index dea1b0a44..f5d620027 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -95,6 +95,10 @@ Other Changes: most typically achieved when resizing programmatically or via a docking layout reacting to a platform window resize). (#3237, #9007) [@anton-kl, @ocornut] - Nav: + - Reworked PageUp/PageDown to pick same-page top/bottom page based + on inner rectangle rather than clipping rectangle, ensuring consistent + (but occasionally less practical) navigation result when a window is + partially out of screen. (#787) - Clipper: fixed an issue when using up/down from an item outside of visible bound and using the clipper. (#9079) - Fonts: diff --git a/imgui.cpp b/imgui.cpp index 3332e62bf..f9b65c484 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -13207,10 +13207,14 @@ static void ImGui::NavProcessItem() // Features like PageUp/PageDown need to maintain a separate score for the visible set of items. const float VISIBLE_RATIO = 0.70f; - if ((g.NavMoveFlags & ImGuiNavMoveFlags_AlsoScoreVisibleSet) && window->ClipRect.Overlaps(nav_bb)) - if (ImClamp(nav_bb.Max.y, window->ClipRect.Min.y, window->ClipRect.Max.y) - ImClamp(nav_bb.Min.y, window->ClipRect.Min.y, window->ClipRect.Max.y) >= (nav_bb.Max.y - nav_bb.Min.y) * VISIBLE_RATIO) - if (NavScoreItem(&g.NavMoveResultLocalVisible, nav_bb)) - NavApplyItemToResult(&g.NavMoveResultLocalVisible); + if (g.NavMoveFlags & ImGuiNavMoveFlags_AlsoScoreVisibleSet) + { + const ImRect& r = window->InnerRect; // window->ClipRect + if (r.Overlaps(nav_bb)) + if (ImClamp(nav_bb.Max.y, r.Min.y, r.Max.y) - ImClamp(nav_bb.Min.y, r.Min.y, r.Max.y) >= (nav_bb.Max.y - nav_bb.Min.y) * VISIBLE_RATIO) + if (NavScoreItem(&g.NavMoveResultLocalVisible, nav_bb)) + NavApplyItemToResult(&g.NavMoveResultLocalVisible); + } } } } From 37f91531058534fbcbf809e9c38a1f57c05f4756 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 18 Nov 2025 18:59:06 +0100 Subject: [PATCH 15/16] Nav: improved/clarified behavior when requesting PageUp/PageDown from a focused item which is outside of visible boundaries. (#9079) --- docs/CHANGELOG.txt | 3 +++ imgui.cpp | 9 ++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index f5d620027..1a92b7f40 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -99,6 +99,9 @@ Other Changes: on inner rectangle rather than clipping rectangle, ensuring consistent (but occasionally less practical) navigation result when a window is partially out of screen. (#787) + - Improved/clarified behavior when requesting PageUp/PageDown from a + focused item which is outside of visible boundaries: now ends up one + page away from focused item. (#9079) - Clipper: fixed an issue when using up/down from an item outside of visible bound and using the clipper. (#9079) - Fonts: diff --git a/imgui.cpp b/imgui.cpp index f9b65c484..170bca0fd 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -13815,11 +13815,6 @@ void ImGui::NavUpdateCreateMoveRequest() float scoring_page_offset_y = 0.0f; if (window && g.NavMoveDir == ImGuiDir_None && nav_keyboard_active) scoring_page_offset_y = NavUpdatePageUpPageDown(); - if (scoring_page_offset_y != 0.0f) - { - g.NavScoringNoClipRect = window->InnerRect; - g.NavScoringNoClipRect.TranslateY(scoring_page_offset_y); - } // [DEBUG] Always send a request when holding Ctrl. Hold Ctrl + Arrow change the direction. #if IMGUI_DEBUG_NAV_SCORING @@ -13883,7 +13878,11 @@ void ImGui::NavUpdateCreateMoveRequest() { ImRect nav_rect_rel = !window->NavRectRel[g.NavLayer].IsInverted() ? window->NavRectRel[g.NavLayer] : ImRect(0, 0, 0, 0); scoring_rect = WindowRectRelToAbs(window, nav_rect_rel); + if (scoring_page_offset_y != 0.0f) + g.NavScoringNoClipRect = scoring_rect; scoring_rect.TranslateY(scoring_page_offset_y); + if (scoring_page_offset_y != 0.0f) + g.NavScoringNoClipRect.Add(scoring_rect); //GetForegroundDrawList()->AddRectFilled(scoring_rect.Min - ImVec2(1, 1), scoring_rect.Max + ImVec2(1, 1), IM_COL32(255, 100, 0, 80)); // [DEBUG] Pre-bias if (g.NavMoveSubmitted) NavBiasScoringRect(scoring_rect, window->RootWindowForNav->NavPreferredScoringPosRel[g.NavLayer], g.NavMoveDir, g.NavMoveFlags); From 23bd697f053bd5cf24601ee3f29572c0a645bd8f Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 18 Nov 2025 19:17:20 +0100 Subject: [PATCH 16/16] Drag and Drop: Pressing Escape while carrying a payload automatically cancel the active drag and drop. (#9071) --- docs/CHANGELOG.txt | 2 ++ imgui.cpp | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 1a92b7f40..116e3760d 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -122,6 +122,8 @@ Other Changes: - Drag and Drop: - Added ImGuiDragDropFlags_AcceptDrawAsHovered to make accepting item render as hovered, which can allow using e.g. Button() as drop target. (#8632) + - Pressing Escape while carrying a payload automatically cancel the + active drag and drop. (#9071) - Style: added ImGuiCol_DragDropTargetBg, style.DragDropTargetRounding, style.DragDropTargetBorderSize and style.DragDropTargetPadding to configure the drop target highlight. (#9056) [@aaronkirkham] diff --git a/imgui.cpp b/imgui.cpp index 170bca0fd..c20e8dfa3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5534,6 +5534,11 @@ void ImGui::NewFrame() g.DragDropWithinSource = false; g.DragDropWithinTarget = false; g.DragDropHoldJustPressedId = 0; + if (g.DragDropActive && IsKeyPressed(ImGuiKey_Escape, ImGuiInputFlags_None, g.ActiveId)) // Also works when g.ActiveId==0 (aka leftover payload in progress, no active id) + { + ClearActiveID(); + ClearDragDrop(); + } g.TooltipPreviousWindow = NULL; // Close popups on focus lost (currently wip/opt-in)