diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4ff14341e..783615aec 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -558,7 +558,7 @@ jobs: run: xcodebuild -project examples/example_apple_opengl2/example_apple_opengl2.xcodeproj -target example_osx_opengl2 iOS: - runs-on: macos-latest + runs-on: macos-14 steps: - uses: actions/checkout@v4 diff --git a/backends/imgui_impl_glfw.cpp b/backends/imgui_impl_glfw.cpp index 5d4df1cf8..c0f90b96d 100644 --- a/backends/imgui_impl_glfw.cpp +++ b/backends/imgui_impl_glfw.cpp @@ -32,6 +32,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) // 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. +// 2025-09-15: Content Scales are always reported as 1.0 on Wayland. FramebufferScale are always reported as 1.0 on X11. (#8920, #8921) // 2025-09-10: [Docking] Improve multi-viewport behavior in tiling WMs on X11 via the ImGui_ImplGlfw_SetWindowFloating() function. Note: using GLFW backend on Linux/BSD etc. requires linking with -lX11. (#8884, #8474, #8289) // 2025-07-08: Made ImGui_ImplGlfw_GetContentScaleForWindow(), ImGui_ImplGlfw_GetContentScaleForMonitor() helpers return 1.0f on Emscripten and Android platforms, matching macOS logic. (#8742, #8733) // 2025-06-18: Added support for multiple Dear ImGui contexts. (#8676, #8239, #8069) @@ -115,30 +116,29 @@ // GLFW #include - #ifdef _WIN32 #undef APIENTRY -#ifndef GLFW_EXPOSE_NATIVE_WIN32 +#ifndef GLFW_EXPOSE_NATIVE_WIN32 // for glfwGetWin32Window() #define GLFW_EXPOSE_NATIVE_WIN32 #endif -#include // for glfwGetWin32Window() +#include #elif defined(__APPLE__) -#ifndef GLFW_EXPOSE_NATIVE_COCOA +#ifndef GLFW_EXPOSE_NATIVE_COCOA // for glfwGetCocoaWindow() #define GLFW_EXPOSE_NATIVE_COCOA #endif -#include // for glfwGetCocoaWindow() +#include #elif !defined(__EMSCRIPTEN__) -// Freedesktop (Linux, BSD, etc) -#ifndef GLFW_EXPOSE_NATIVE_X11 +#ifndef GLFW_EXPOSE_NATIVE_X11 // for glfwGetX11Window() on Freedesktop (Linux, BSD, etc.) #define GLFW_EXPOSE_NATIVE_X11 #include #endif #ifndef GLFW_EXPOSE_NATIVE_WAYLAND #define GLFW_EXPOSE_NATIVE_WAYLAND #endif -#include // for getting the X11/Wayland window +#include #undef Status // X11 headers are leaking this. #endif + #ifndef _WIN32 #include // for usleep() #endif @@ -183,6 +183,11 @@ #define GLFW_HAS_GETKEYNAME (GLFW_VERSION_COMBINED >= 3200) // 3.2+ glfwGetKeyName() #define GLFW_HAS_GETERROR (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetError() #define GLFW_HAS_GETPLATFORM (GLFW_VERSION_COMBINED >= 3400) // 3.4+ glfwGetPlatform() +#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) +#define GLFW_HAS_X11_OR_WAYLAND 1 +#else +#define GLFW_HAS_X11_OR_WAYLAND 0 +#endif // Map GLFWWindow* to ImGuiContext*. // - Would be simpler if we could use glfwSetWindowUserPointer()/glfwGetWindowUserPointer(), but this is a single and shared resource. @@ -194,14 +199,14 @@ static void ImGui_ImplGlfw_ContextMap_Add(GLFWwindow* window, ImGuiContext* ctx) static void ImGui_ImplGlfw_ContextMap_Remove(GLFWwindow* window) { for (ImGui_ImplGlfw_WindowToContext& entry : g_ContextMap) if (entry.Window == window) { g_ContextMap.erase_unsorted(&entry); return; } } static ImGuiContext* ImGui_ImplGlfw_ContextMap_Get(GLFWwindow* window) { for (ImGui_ImplGlfw_WindowToContext& entry : g_ContextMap) if (entry.Window == window) return entry.Context; return nullptr; } -// GLFW data enum GlfwClientApi { - GlfwClientApi_Unknown, GlfwClientApi_OpenGL, GlfwClientApi_Vulkan, + GlfwClientApi_Unknown, // Anything else fits here. }; +// GLFW data struct ImGui_ImplGlfw_Data { ImGuiContext* Context; @@ -214,6 +219,7 @@ struct ImGui_ImplGlfw_Data bool MouseIgnoreButtonUp; ImVec2 LastValidMousePos; GLFWwindow* KeyOwnerWindows[GLFW_KEY_LAST]; + bool IsWayland; bool InstalledCallbacks; bool CallbacksChainForAllWindows; char BackendPlatformName[32]; @@ -263,6 +269,23 @@ static void ImGui_ImplGlfw_InitMultiViewportSupport(); static void ImGui_ImplGlfw_ShutdownMultiViewportSupport(); // Functions +static bool ImGui_ImplGlfw_IsWayland() +{ +#if !GLFW_HAS_X11_OR_WAYLAND + return false; +#elif GLFW_HAS_GETPLATFORM + return glfwGetPlatform() == GLFW_PLATFORM_WAYLAND; +#else + const char* version = glfwGetVersionString(); + if (strstr(version, "Wayland") == NULL) // e.g. Ubuntu 22.04 ships with GLFW 3.3.6 compiled without Wayland + return false; +#ifdef GLFW_EXPOSE_NATIVE_X11 + if (glfwGetX11Display() != NULL) + return false; +#endif + return true; +#endif +} // Not static to allow third-party code to use that if they want to (but undocumented) ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int keycode, int scancode); @@ -680,6 +703,7 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw bd->Context = ImGui::GetCurrentContext(); bd->Window = window; bd->Time = 0.0; + bd->IsWayland = ImGui_ImplGlfw_IsWayland(); ImGui_ImplGlfw_ContextMap_Add(window, bd->Context); ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); @@ -1015,6 +1039,11 @@ static void ImGui_ImplGlfw_UpdateMonitors() // - Some accessibility applications are declaring virtual monitors with a DPI of 0.0f, see #7902. We preserve this value for caller to handle. float ImGui_ImplGlfw_GetContentScaleForWindow(GLFWwindow* window) { +#if GLFW_HAS_X11_OR_WAYLAND + if (ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window)) + if (bd->IsWayland) + return 1.0f; +#endif #if GLFW_HAS_PER_MONITOR_DPI && !(defined(__APPLE__) || defined(__EMSCRIPTEN__) || defined(__ANDROID__)) float x_scale, y_scale; glfwGetWindowContentScale(window, &x_scale, &y_scale); @@ -1027,6 +1056,10 @@ float ImGui_ImplGlfw_GetContentScaleForWindow(GLFWwindow* window) float ImGui_ImplGlfw_GetContentScaleForMonitor(GLFWmonitor* monitor) { +#if GLFW_HAS_X11_OR_WAYLAND + if (ImGui_ImplGlfw_IsWayland()) // We can't access our bd->IsWayland cache for a monitor. + return 1.0f; +#endif #if GLFW_HAS_PER_MONITOR_DPI && !(defined(__APPLE__) || defined(__EMSCRIPTEN__) || defined(__ANDROID__)) float x_scale, y_scale; glfwGetMonitorContentScale(monitor, &x_scale, &y_scale); @@ -1043,10 +1076,17 @@ 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; +#if GLFW_HAS_X11_OR_WAYLAND + ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window); + if (!bd->IsWayland) + fb_scale_x = fb_scale_y = 1.0f; +#endif if (out_size != nullptr) *out_size = ImVec2((float)w, (float)h); if (out_framebuffer_scale != nullptr) - *out_framebuffer_scale = (w > 0 && h > 0) ? ImVec2((float)display_w / (float)w, (float)display_h / (float)h) : ImVec2(1.0f, 1.0f); + *out_framebuffer_scale = ImVec2(fb_scale_x, fb_scale_y); } void ImGui_ImplGlfw_NewFrame() diff --git a/backends/imgui_impl_sdl2.cpp b/backends/imgui_impl_sdl2.cpp index 5b61cf84f..26a8ad706 100644 --- a/backends/imgui_impl_sdl2.cpp +++ b/backends/imgui_impl_sdl2.cpp @@ -26,6 +26,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) // 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. +// 2025-09-15: Content Scales are always reported as 1.0 on Wayland. (#8921) // 2025-07-08: Made ImGui_ImplSDL2_GetContentScaleForWindow(), ImGui_ImplSDL2_GetContentScaleForDisplay() helpers return 1.0f on Emscripten and Android platforms, matching macOS logic. (#8742, #8733) // 2025-06-11: Added ImGui_ImplSDL2_GetContentScaleForWindow(SDL_Window* window) and ImGui_ImplSDL2_GetContentScaleForDisplay(int display_index) helper to facilitate making DPI-aware apps. // 2025-05-15: [Docking] Add Platform_GetWindowFramebufferScale() handler, to allow varying Retina display density on multiple monitors. @@ -825,6 +826,9 @@ float ImGui_ImplSDL2_GetContentScaleForWindow(SDL_Window* window) float ImGui_ImplSDL2_GetContentScaleForDisplay(int display_index) { + const char* sdl_driver = SDL_GetCurrentVideoDriver(); + if (sdl_driver && strcmp(sdl_driver, "wayland") == 0) + return 1.0f; #if SDL_HAS_PER_MONITOR_DPI #if !defined(__APPLE__) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) float dpi = 0.0f; diff --git a/backends/imgui_impl_sdl3.cpp b/backends/imgui_impl_sdl3.cpp index 94942aa3c..52370558a 100644 --- a/backends/imgui_impl_sdl3.cpp +++ b/backends/imgui_impl_sdl3.cpp @@ -24,6 +24,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) // 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. +// 2025-09-15: Use SDL_GetWindowDisplayScale() on Mac to output DisplayFrameBufferScale. The function is more reliable during resolution changes e.g. going fullscreen. (#8703, #4414) // 2025-06-27: IME: avoid calling SDL_StartTextInput() again if already active. (#8727) // 2025-05-15: [Docking] Add Platform_GetWindowFramebufferScale() handler, to allow varying Retina display density on multiple monitors. // 2025-05-06: [Docking] macOS: fixed secondary viewports not appearing on other monitors before of parenting. @@ -913,15 +914,24 @@ static void ImGui_ImplSDL3_UpdateMonitors() static void ImGui_ImplSDL3_GetWindowSizeAndFramebufferScale(SDL_Window* window, ImVec2* out_size, ImVec2* out_framebuffer_scale) { int w, h; - int display_w, display_h; SDL_GetWindowSize(window, &w, &h); if (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED) w = h = 0; + +#if defined(__APPLE__) + float fb_scale_x = SDL_GetWindowDisplayScale(window); // Seems more reliable during resolution change (#8703) + float fb_scale_y = fb_scale_x; +#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; +#endif + if (out_size != nullptr) *out_size = ImVec2((float)w, (float)h); if (out_framebuffer_scale != nullptr) - *out_framebuffer_scale = (w > 0 && h > 0) ? ImVec2((float)display_w / w, (float)display_h / h) : ImVec2(1.0f, 1.0f); + *out_framebuffer_scale = ImVec2(fb_scale_x, fb_scale_y); } void ImGui_ImplSDL3_NewFrame() diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index ede101942..2170ab6dd 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -36,25 +36,27 @@ HOW TO UPDATE? - Please report any issue! ----------------------------------------------------------------------- - VERSION 1.92.3 WIP (In Progress) + VERSION 1.92.3 (Released 2025-09-17) ----------------------------------------------------------------------- -Breaking Changes: +Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.92.3 Other Changes: -- Scrollbar, Style: added configurable style.ScrollbarPadding value and corresponding - ImGuiStyleVar_ScrollbarPadding enum, instead of hardcoded computed default. (#8895) -- Fonts: fixed an assertion failure when a rectangle entry has been reused - 1024 times (e.g. due to constant change of font types). (#8906) [@cfillion] - Fonts: fixed merging a font and specifying a font target in DstFont that's not the last added font (regression in 1.92). (#8912) +- Fonts: fixed an assertion failure when a rectangle entry has been reused + 1024 times (e.g. due to constant change of font size). (#8906) [@cfillion] - Clipper, Tables: added ImGuiListClipperFlags_NoSetTableRowCounters as a way to disable the assumption that 1 clipper item == 1 table row, which breaks when e.g. using clipper with ItemsHeight=1 in order to clip in pixel units. (#8886) +- Scrollbar, Style: added configurable style.ScrollbarPadding value and corresponding + ImGuiStyleVar_ScrollbarPadding enum, instead of an hard-coded computed default. (#8895) - Nav: fixed Ctrl+Tab window appearing as empty when the sole active and focused window has the ImGuiWindowFlags_NoNavFocus flag. (#8914) -- Bullet: fixed tesselation amount which looked out of place in very large sizes. +- Nav: fixed a crash that could occur when opening a popup following the processing + of a global shortcut while no windows were focused. +- Bullet: fixed tessellation which looked out of place in very large sizes. - InputText: added ImGuiInputTextFlags_WordWrap flag to word-wrap multi-line buffers. (#3237, #952, #1062, #7363). Current caveats: - This is marked as beta because not being tested enough. @@ -62,7 +64,7 @@ Other Changes: - Wrapping style is not ideal. Wrapping of long words/sections (e.g. words larger than total available width) may be particularly unpleasing. - Wrapping width needs to always account for the possibility of a vertical scrollbar. - - It is currently much slower than regular text fields. + - It is currently much slower than regular text fields: - Ballpark estimate of cost on my 2019 desktop PC: For a 100 KB text buffer: +~0.3 ms/+~1.0 ms (Optimized vs Debug builds). - The CPU cost is very roughly proportional to text length, so a 10 KB buffer @@ -101,12 +103,25 @@ Other Changes: is now skipped. (#8904, #4631) - Debug Tools: ID Stack Tool: added option to hex-encode non-ASCII characters in output path. (#8904, #4631) +- Debug Tools: ID Stack Tool: fixed a crash when using PushOverrideID(0) during + a query. (#8937, #4631) - Debug Tools: Fixed assertion failure when opening a combo box while using io.ConfigDebugBeginReturnValueOnce/ConfigDebugBeginReturnValueLoop. (#8931) [@harrymander] - Demo: tweaked ShowFontSelector() and ShowStyleSelector() to update selection while navigating and to not close popup automatically. - CI: Updates Windows CI to use a more recent VulkanSDK. (#8925, #8778) [@yaz0r] - Examples: Android: Android+OpenGL3: update Gradle project (#8888, #8878) [@scribam] +- Examples: GLFW+OpenGL2, GLFW+Vulkan, GLFW+Metal, Win32+Vulkan: Fixed not applying + content scale consistently with other examples. (#8921, #8756) +- Backends: GLFW: distinguish X11 vs Wayland to fix various scaling issues. + (#8920, #8921) [@TheBrokenRail, @pthom, @ocornut] + - window/monitor content scales are always reported as 1.0 on Wayland. + - framebuffer scales are always reported as 1.0 on X11. +- Backends: SDL2: window/monitor content scales are always reported as 1.0 on Wayland. + (#8920, #8921) [@TheBrokenRail, @pthom, @ocornut] +- Backends: SDL3: use SDL_GetWindowDisplayScale() on Mac to obtain DisplayFrameBufferScale, + fixing incorrect values during resolution changes e.g. going fullscreen. + (#8703, #4414) [@jclounge] - Backends: SDL_GPU: Added ImGui_ImplSDLGPU3_InitInfo::SwapchainComposition and PresentMode to configure how secondary viewports are created. Currently only used multi-viewport mode. (#8892) [@PTSVU] @@ -781,8 +796,8 @@ Docking+Viewports Branch: - Viewports: fixed handling of simultaneous move + resize (e.g. toggling maximized) when ImGuiConfigFlags_DpiEnableScaleViewports is enabled. - Backends: Win32: Viewports: fixed an issue when closing a window from - the OS close button (with io.ConfigViewportsNoDecoration=false) while - user code is discarding the 'bool *p_open=false output' from Begin(). + the OS close button (with io.ConfigViewportsNoDecoration=false) while + user code is discarding the 'bool *p_open=false output' from Begin(). Because we allowed the Win32 window to close early, Windows destroyed it and our imgui window became not visible even though user code was still submitting it. (#8670) @@ -933,7 +948,7 @@ Other changes: with asserts enabled. (#8452) - Backends: SDL2, SDL3: Using SDL_OpenURL() in platform_io.Platform_OpenInShellFn handler. (#7660) [@achabense] -- Backends: SDL2, SDL3: Use display bounds when SDL_GetDisplayUsableBounds() +- Backends: SDL2, SDL3: Use display bounds when SDL_GetDisplayUsableBounds() fails or return a zero size. (#8415, #3457) - Backends: SDL2, SDL3, Win32, Allegro5: Added support for ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress cursors. @@ -961,9 +976,9 @@ Docking+Viewports Branch: - Docking: Removed legacy assert preventing to call DockBuilderSplitNode() on an existing split node. This makes using DockBuilder a little more flexible and bearable! (#8472) [@MegaMech] -- Viewports: fixed an issue where in certain cases, a window repositioning leading - to a monitor change could have the window incorrectly get clamped within the boundaries - of its previous monitor. Would happen e.g. when loading .ini data during runtime. (#8484) +- Viewports: fixed an issue where in certain cases, a window repositioning leading + to a monitor change could have the window incorrectly get clamped within the boundaries + of its previous monitor. Would happen e.g. when loading .ini data during runtime. (#8484) - Viewports: fixed an assert when a window load settings with a position outside monitor bounds, when there are multiple monitors. (#8393, #8385) [@gaborodriguez] - Viewports + Backends: Win32: Fixed setting title bar text when application diff --git a/examples/example_allegro5/main.cpp b/examples/example_allegro5/main.cpp index 5dd35bb4a..8476599d3 100644 --- a/examples/example_allegro5/main.cpp +++ b/examples/example_allegro5/main.cpp @@ -28,7 +28,7 @@ int main(int, char**) al_install_mouse(); al_init_primitives_addon(); al_set_new_display_flags(ALLEGRO_RESIZABLE); - ALLEGRO_DISPLAY* display = al_create_display(1280, 720); + ALLEGRO_DISPLAY* display = al_create_display(1280, 800); al_set_window_title(display, "Dear ImGui Allegro 5 example"); ALLEGRO_EVENT_QUEUE* queue = al_create_event_queue(); al_register_event_source(queue, al_get_display_event_source(display)); diff --git a/examples/example_apple_metal/main.mm b/examples/example_apple_metal/main.mm index 462d79f97..68bd2bba6 100644 --- a/examples/example_apple_metal/main.mm +++ b/examples/example_apple_metal/main.mm @@ -104,7 +104,7 @@ -(void)loadView { - self.view = [[MTKView alloc] initWithFrame:CGRectMake(0, 0, 1200, 720)]; + self.view = [[MTKView alloc] initWithFrame:CGRectMake(0, 0, 1200, 800)]; } -(void)viewDidLoad diff --git a/examples/example_apple_opengl2/main.mm b/examples/example_apple_opengl2/main.mm index 0de88f5bf..25121b053 100644 --- a/examples/example_apple_opengl2/main.mm +++ b/examples/example_apple_opengl2/main.mm @@ -190,7 +190,7 @@ if (_window != nil) return (_window); - NSRect viewRect = NSMakeRect(100.0, 100.0, 100.0 + 1280.0, 100 + 720.0); + NSRect viewRect = NSMakeRect(100.0, 100.0, 100.0 + 1280.0, 100 + 800.0); _window = [[NSWindow alloc] initWithContentRect:viewRect styleMask:NSWindowStyleMaskTitled|NSWindowStyleMaskMiniaturizable|NSWindowStyleMaskResizable|NSWindowStyleMaskClosable backing:NSBackingStoreBuffered defer:YES]; [_window setTitle:@"Dear ImGui OSX+OpenGL2 Example"]; diff --git a/examples/example_glfw_metal/main.mm b/examples/example_glfw_metal/main.mm index 9f58a55c5..c7fd3531e 100644 --- a/examples/example_glfw_metal/main.mm +++ b/examples/example_glfw_metal/main.mm @@ -27,19 +27,37 @@ static void glfw_error_callback(int error, const char* description) int main(int, char**) { + glfwSetErrorCallback(glfw_error_callback); + if (!glfwInit()) + return 1; + + // Create window with graphics context + float main_scale = ImGui_ImplGlfw_GetContentScaleForMonitor(glfwGetPrimaryMonitor()); // Valid on GLFW 3.3+ only + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + GLFWwindow* window = glfwCreateWindow((int)(1280 * main_scale), (int)(800 * main_scale), "Dear ImGui GLFW+Metal example", nullptr, nullptr); + if (window == nullptr) + return 1; + // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; - io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls - io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls - io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking - io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking + io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows - // Setup style + // Setup Dear ImGui style ImGui::StyleColorsDark(); //ImGui::StyleColorsLight(); + // Setup scaling + ImGuiStyle& style = ImGui::GetStyle(); + style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again) + style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose) + io.ConfigDpiScaleFonts = true; // [Experimental] Automatically overwrite style.FontScaleDpi in Begin() when Monitor DPI changes. This will scale fonts but _NOT_ scale sizes/padding for now. + io.ConfigDpiScaleViewports = true; // [Experimental] Scale Dear ImGui and Platform Windows when Monitor DPI changes. + // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones. ImGuiStyle& style = ImGui::GetStyle(); if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) @@ -48,6 +66,13 @@ int main(int, char**) style.Colors[ImGuiCol_WindowBg].w = 1.0f; } + id device = MTLCreateSystemDefaultDevice(); + id commandQueue = [device newCommandQueue]; + + // Setup Platform/Renderer backends + ImGui_ImplGlfw_InitForOpenGL(window, true); + ImGui_ImplMetal_Init(device); + // Load Fonts // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. @@ -64,24 +89,6 @@ int main(int, char**) //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf"); //IM_ASSERT(font != nullptr); - // Setup window - glfwSetErrorCallback(glfw_error_callback); - if (!glfwInit()) - return 1; - - // Create window with graphics context - glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); - GLFWwindow* window = glfwCreateWindow(1280, 720, "Dear ImGui GLFW+Metal example", nullptr, nullptr); - if (window == nullptr) - return 1; - - id device = MTLCreateSystemDefaultDevice(); - id commandQueue = [device newCommandQueue]; - - // Setup Platform/Renderer backends - ImGui_ImplGlfw_InitForOther(window, true); - ImGui_ImplMetal_Init(device); - NSWindow *nswin = glfwGetCocoaWindow(window); CAMetalLayer *layer = [CAMetalLayer layer]; layer.device = device; diff --git a/examples/example_glfw_opengl2/main.cpp b/examples/example_glfw_opengl2/main.cpp index 914db49de..c4b31259f 100644 --- a/examples/example_glfw_opengl2/main.cpp +++ b/examples/example_glfw_opengl2/main.cpp @@ -40,7 +40,8 @@ int main(int, char**) return 1; // Create window with graphics context - GLFWwindow* window = glfwCreateWindow(1280, 720, "Dear ImGui GLFW+OpenGL2 example", nullptr, nullptr); + float main_scale = ImGui_ImplGlfw_GetContentScaleForMonitor(glfwGetPrimaryMonitor()); // Valid on GLFW 3.3+ only + GLFWwindow* window = glfwCreateWindow((int)(1280 * main_scale), (int)(800 * main_scale), "Dear ImGui GLFW+OpenGL2 example", nullptr, nullptr); if (window == nullptr) return 1; glfwMakeContextCurrent(window); @@ -61,6 +62,13 @@ int main(int, char**) ImGui::StyleColorsDark(); //ImGui::StyleColorsLight(); + // Setup scaling + ImGuiStyle& style = ImGui::GetStyle(); + style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again) + style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose) + io.ConfigDpiScaleFonts = true; // [Experimental] Automatically overwrite style.FontScaleDpi in Begin() when Monitor DPI changes. This will scale fonts but _NOT_ scale sizes/padding for now. + io.ConfigDpiScaleViewports = true; // [Experimental] Scale Dear ImGui and Platform Windows when Monitor DPI changes. + // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones. ImGuiStyle& style = ImGui::GetStyle(); if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) diff --git a/examples/example_glfw_vulkan/main.cpp b/examples/example_glfw_vulkan/main.cpp index 2936b620d..8f3618703 100644 --- a/examples/example_glfw_vulkan/main.cpp +++ b/examples/example_glfw_vulkan/main.cpp @@ -357,7 +357,8 @@ int main(int, char**) // Create window with Vulkan context glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); - GLFWwindow* window = glfwCreateWindow(1280, 720, "Dear ImGui GLFW+Vulkan example", nullptr, nullptr); + float main_scale = ImGui_ImplGlfw_GetContentScaleForMonitor(glfwGetPrimaryMonitor()); // Valid on GLFW 3.3+ only + GLFWwindow* window = glfwCreateWindow((int)(1280 * main_scale), (int)(800 * main_scale), "Dear ImGui GLFW+Vulkan example", nullptr, nullptr); if (!glfwVulkanSupported()) { printf("GLFW: Vulkan Not Supported\n"); @@ -397,6 +398,13 @@ int main(int, char**) ImGui::StyleColorsDark(); //ImGui::StyleColorsLight(); + // Setup scaling + ImGuiStyle& style = ImGui::GetStyle(); + style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again) + style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose) + io.ConfigDpiScaleFonts = true; // [Experimental] Automatically overwrite style.FontScaleDpi in Begin() when Monitor DPI changes. This will scale fonts but _NOT_ scale sizes/padding for now. + io.ConfigDpiScaleViewports = true; // [Experimental] Scale Dear ImGui and Platform Windows when Monitor DPI changes. + // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones. ImGuiStyle& style = ImGui::GetStyle(); if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) diff --git a/examples/example_glfw_wgpu/main.cpp b/examples/example_glfw_wgpu/main.cpp index 66325ccd8..5eec5009d 100644 --- a/examples/example_glfw_wgpu/main.cpp +++ b/examples/example_glfw_wgpu/main.cpp @@ -37,7 +37,7 @@ static WGPUSurface wgpu_surface = nullptr; static WGPUTextureFormat wgpu_preferred_fmt = WGPUTextureFormat_RGBA8Unorm; static WGPUSwapChain wgpu_swap_chain = nullptr; static int wgpu_swap_chain_width = 1280; -static int wgpu_swap_chain_height = 720; +static int wgpu_swap_chain_height = 800; // Forward declarations static bool InitWGPU(GLFWwindow* window); diff --git a/examples/example_glut_opengl2/main.cpp b/examples/example_glut_opengl2/main.cpp index 569e34666..ad7f24830 100644 --- a/examples/example_glut_opengl2/main.cpp +++ b/examples/example_glut_opengl2/main.cpp @@ -48,7 +48,7 @@ int main(int argc, char** argv) glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS); #endif glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_MULTISAMPLE); - glutInitWindowSize(1280, 720); + glutInitWindowSize(1280, 800); glutCreateWindow("Dear ImGui GLUT+OpenGL2 Example"); // Setup GLUT display function diff --git a/examples/example_sdl2_directx11/main.cpp b/examples/example_sdl2_directx11/main.cpp index 6a4b971f5..be6a3d794 100644 --- a/examples/example_sdl2_directx11/main.cpp +++ b/examples/example_sdl2_directx11/main.cpp @@ -50,7 +50,7 @@ int main(int, char**) // Setup window float main_scale = ImGui_ImplSDL2_GetContentScaleForDisplay(0); SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); - SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+DirectX11 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (int)(1280 * main_scale), (int)(720 * main_scale), window_flags); + SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+DirectX11 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (int)(1280 * main_scale), (int)(800 * main_scale), window_flags); if (window == nullptr) { printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError()); diff --git a/examples/example_sdl2_metal/main.mm b/examples/example_sdl2_metal/main.mm index 9adfac95e..2c5cc76f7 100644 --- a/examples/example_sdl2_metal/main.mm +++ b/examples/example_sdl2_metal/main.mm @@ -70,7 +70,7 @@ int main(int, char**) // Enable native IME. SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1"); - SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL+Metal example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); + SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL+Metal example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 800, SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); if (window == nullptr) { printf("Error creating window: %s\n", SDL_GetError()); diff --git a/examples/example_sdl2_opengl2/main.cpp b/examples/example_sdl2_opengl2/main.cpp index 70a813889..e453a8112 100644 --- a/examples/example_sdl2_opengl2/main.cpp +++ b/examples/example_sdl2_opengl2/main.cpp @@ -47,7 +47,7 @@ int main(int, char**) SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); float main_scale = ImGui_ImplSDL2_GetContentScaleForDisplay(0); SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); - SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (int)(1280 * main_scale), (int)(720 * main_scale), window_flags); + SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (int)(1280 * main_scale), (int)(800 * main_scale), window_flags); if (window == nullptr) { printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError()); diff --git a/examples/example_sdl2_opengl3/main.cpp b/examples/example_sdl2_opengl3/main.cpp index 89f9751ff..23aa9ef26 100644 --- a/examples/example_sdl2_opengl3/main.cpp +++ b/examples/example_sdl2_opengl3/main.cpp @@ -81,7 +81,7 @@ int main(int, char**) SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); float main_scale = ImGui_ImplSDL2_GetContentScaleForDisplay(0); SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); - SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL3 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (int)(1280 * main_scale), (int)(720 * main_scale), window_flags); + SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL3 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (int)(1280 * main_scale), (int)(800 * main_scale), window_flags); if (window == nullptr) { printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError()); diff --git a/examples/example_sdl2_sdlrenderer2/main.cpp b/examples/example_sdl2_sdlrenderer2/main.cpp index 62b0a6f44..b9a7fb197 100644 --- a/examples/example_sdl2_sdlrenderer2/main.cpp +++ b/examples/example_sdl2_sdlrenderer2/main.cpp @@ -44,7 +44,7 @@ int main(int, char**) // Create window with SDL_Renderer graphics context float main_scale = ImGui_ImplSDL2_GetContentScaleForDisplay(0); SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); - SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+SDL_Renderer example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (int)(1280 * main_scale), (int)(720 * main_scale), window_flags); + SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+SDL_Renderer example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (int)(1280 * main_scale), (int)(800 * main_scale), window_flags); if (window == nullptr) { printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError()); diff --git a/examples/example_sdl2_vulkan/main.cpp b/examples/example_sdl2_vulkan/main.cpp index b1b6cca96..bd456e689 100644 --- a/examples/example_sdl2_vulkan/main.cpp +++ b/examples/example_sdl2_vulkan/main.cpp @@ -360,7 +360,7 @@ int main(int, char**) // Create window with Vulkan graphics context float main_scale = ImGui_ImplSDL2_GetContentScaleForDisplay(0); SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); - SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+Vulkan example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (int)(1280 * main_scale), (int)(720 * main_scale), window_flags); + SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+Vulkan example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (int)(1280 * main_scale), (int)(800 * main_scale), window_flags); if (window == nullptr) { printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError()); diff --git a/examples/example_sdl3_metal/main.mm b/examples/example_sdl3_metal/main.mm index 98c4a9490..022e0f432 100644 --- a/examples/example_sdl3_metal/main.mm +++ b/examples/example_sdl3_metal/main.mm @@ -30,7 +30,7 @@ int main(int, char**) // Create SDL window graphics context float main_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay()); SDL_WindowFlags window_flags = SDL_WINDOW_METAL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY; - SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+Metal example", (int)(1280 * main_scale), (int)(720 * main_scale), window_flags); + SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+Metal example", (int)(1280 * main_scale), (int)(800 * main_scale), window_flags); if (window == nullptr) { printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError()); diff --git a/examples/example_sdl3_opengl3/main.cpp b/examples/example_sdl3_opengl3/main.cpp index 62dff4a93..c5435612c 100644 --- a/examples/example_sdl3_opengl3/main.cpp +++ b/examples/example_sdl3_opengl3/main.cpp @@ -70,7 +70,7 @@ int main(int, char**) SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); float main_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay()); SDL_WindowFlags window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY; - SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+OpenGL3 example", (int)(1280 * main_scale), (int)(720 * main_scale), window_flags); + SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+OpenGL3 example", (int)(1280 * main_scale), (int)(800 * main_scale), window_flags); if (window == nullptr) { printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError()); diff --git a/examples/example_sdl3_sdlgpu3/main.cpp b/examples/example_sdl3_sdlgpu3/main.cpp index 1e409fa1f..f254fe729 100644 --- a/examples/example_sdl3_sdlgpu3/main.cpp +++ b/examples/example_sdl3_sdlgpu3/main.cpp @@ -37,7 +37,7 @@ int main(int, char**) // Create SDL window graphics context float main_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay()); SDL_WindowFlags window_flags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY; - SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+SDL_GPU example", (int)(1280 * main_scale), (int)(720 * main_scale), window_flags); + SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+SDL_GPU example", (int)(1280 * main_scale), (int)(800 * main_scale), window_flags); if (window == nullptr) { printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError()); diff --git a/examples/example_sdl3_sdlrenderer3/main.cpp b/examples/example_sdl3_sdlrenderer3/main.cpp index 77ae4362c..6b59ccd79 100644 --- a/examples/example_sdl3_sdlrenderer3/main.cpp +++ b/examples/example_sdl3_sdlrenderer3/main.cpp @@ -34,7 +34,7 @@ int main(int, char**) // Create window with SDL_Renderer graphics context float main_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay()); SDL_WindowFlags window_flags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY; - SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+SDL_Renderer example", (int)(1280 * main_scale), (int)(720 * main_scale), window_flags); + SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+SDL_Renderer example", (int)(1280 * main_scale), (int)(800 * main_scale), window_flags); if (window == nullptr) { printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError()); diff --git a/examples/example_sdl3_vulkan/main.cpp b/examples/example_sdl3_vulkan/main.cpp index a6733f5da..0ca690db6 100644 --- a/examples/example_sdl3_vulkan/main.cpp +++ b/examples/example_sdl3_vulkan/main.cpp @@ -355,7 +355,7 @@ int main(int, char**) // Create window with Vulkan graphics context float main_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay()); SDL_WindowFlags window_flags = SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY; - SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+Vulkan example", (int)(1280 * main_scale), (int)(720 * main_scale), window_flags); + SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+Vulkan example", (int)(1280 * main_scale), (int)(800 * main_scale), window_flags); if (window == nullptr) { printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError()); diff --git a/examples/example_win32_opengl3/main.cpp b/examples/example_win32_opengl3/main.cpp index ab71848a3..66d4d9dae 100644 --- a/examples/example_win32_opengl3/main.cpp +++ b/examples/example_win32_opengl3/main.cpp @@ -72,11 +72,14 @@ static void Hook_Renderer_SwapBuffers(ImGuiViewport* viewport, void*) // Main code int main(int, char**) { + // Make process DPI aware and obtain main monitor scale + //ImGui_ImplWin32_EnableDpiAwareness(); // FIXME: This somehow doesn't work in the Win32+OpenGL example. Why? + float main_scale = ImGui_ImplWin32_GetDpiScaleForMonitor(::MonitorFromPoint(POINT{ 0, 0 }, MONITOR_DEFAULTTOPRIMARY)); + // Create application window - //ImGui_ImplWin32_EnableDpiAwareness(); WNDCLASSEXW wc = { sizeof(wc), CS_OWNDC, WndProc, 0L, 0L, GetModuleHandle(nullptr), nullptr, nullptr, nullptr, nullptr, L"ImGui Example", nullptr }; ::RegisterClassExW(&wc); - HWND hwnd = ::CreateWindowW(wc.lpszClassName, L"Dear ImGui Win32+OpenGL3 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, nullptr, nullptr, wc.hInstance, nullptr); + HWND hwnd = ::CreateWindowW(wc.lpszClassName, L"Dear ImGui Win32+OpenGL3 Example", WS_OVERLAPPEDWINDOW, 100, 100, (int)(1280 * main_scale), (int)(800 * main_scale), nullptr, nullptr, wc.hInstance, nullptr); // Initialize OpenGL if (!CreateDeviceWGL(hwnd, &g_MainWindow)) @@ -105,6 +108,13 @@ int main(int, char**) ImGui::StyleColorsDark(); //ImGui::StyleColorsClassic(); + // Setup scaling + ImGuiStyle& style = ImGui::GetStyle(); + style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again) + style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose) + io.ConfigDpiScaleFonts = true; // [Experimental] Automatically overwrite style.FontScaleDpi in Begin() when Monitor DPI changes. This will scale fonts but _NOT_ scale sizes/padding for now. + io.ConfigDpiScaleViewports = true; // [Experimental] Scale Dear ImGui and Platform Windows when Monitor DPI changes. + // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones. ImGuiStyle& style = ImGui::GetStyle(); if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) diff --git a/examples/example_win32_vulkan/main.cpp b/examples/example_win32_vulkan/main.cpp index 63f2d1449..9e9efb2c3 100644 --- a/examples/example_win32_vulkan/main.cpp +++ b/examples/example_win32_vulkan/main.cpp @@ -352,11 +352,14 @@ static int ImGui_ImplWin32_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_ins // Main code int main(int, char**) { + // Make process DPI aware and obtain main monitor scale + ImGui_ImplWin32_EnableDpiAwareness(); + float main_scale = ImGui_ImplWin32_GetDpiScaleForMonitor(::MonitorFromPoint(POINT{ 0, 0 }, MONITOR_DEFAULTTOPRIMARY)); + // Create application window - //ImGui_ImplWin32_EnableDpiAwareness(); WNDCLASSEXW wc = { sizeof(wc), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(nullptr), nullptr, nullptr, nullptr, nullptr, L"ImGui Example", nullptr }; ::RegisterClassExW(&wc); - HWND hwnd = ::CreateWindowW(wc.lpszClassName, L"Dear ImGui Win32+Vulkan Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, nullptr, nullptr, wc.hInstance, nullptr); + HWND hwnd = ::CreateWindowW(wc.lpszClassName, L"Dear ImGui Win32+Vulkan Example", WS_OVERLAPPEDWINDOW, 100, 100, (int)(1280 * main_scale), (int)(800 * main_scale), nullptr, nullptr, wc.hInstance, nullptr); ImVector extensions; extensions.push_back("VK_KHR_surface"); @@ -379,7 +382,7 @@ int main(int, char**) // Show the window // FIXME: Retrieve client size from window itself. ImGui_ImplVulkanH_Window* wd = &g_MainWindowData; - SetupVulkanWindow(wd, surface, 1280, 800); + SetupVulkanWindow(wd, surface, (int)(1280 * main_scale), (int)(800 * main_scale)); ::ShowWindow(hwnd, SW_SHOWDEFAULT); ::UpdateWindow(hwnd); @@ -398,6 +401,13 @@ int main(int, char**) ImGui::StyleColorsDark(); //ImGui::StyleColorsLight(); + // Setup scaling + ImGuiStyle& style = ImGui::GetStyle(); + style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again) + style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose) + io.ConfigDpiScaleFonts = true; // [Experimental] Automatically overwrite style.FontScaleDpi in Begin() when Monitor DPI changes. This will scale fonts but _NOT_ scale sizes/padding for now. + io.ConfigDpiScaleViewports = true; // [Experimental] Scale Dear ImGui and Platform Windows when Monitor DPI changes. + // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones. ImGuiStyle& style = ImGui::GetStyle(); if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) diff --git a/imgui.cpp b/imgui.cpp index 50b1f57ab..d4dbacf1d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.92.3 WIP +// dear imgui, v1.92.3 // (main code and documentation) // Help: @@ -4147,7 +4147,7 @@ ImGuiContext::ImGuiContext(ImFontAtlas* shared_font_atlas) WheelingWindowReleaseTimer = 0.0f; DebugDrawIdConflictsId = 0; - DebugHookIdInfo = 0; + DebugHookIdInfoId = 0; HoveredId = HoveredIdPreviousFrame = 0; HoveredIdPreviousFrameItemCount = 0; HoveredIdAllowOverlap = false; @@ -9597,7 +9597,7 @@ ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end) ImGuiID id = ImHashStr(str, str_end ? (str_end - str) : 0, seed); #ifndef IMGUI_DISABLE_DEBUG_TOOLS ImGuiContext& g = *Ctx; - if (g.DebugHookIdInfo == id) + if (g.DebugHookIdInfoId == id) ImGui::DebugHookIdInfo(id, ImGuiDataType_String, str, str_end); #endif return id; @@ -9609,7 +9609,7 @@ ImGuiID ImGuiWindow::GetID(const void* ptr) ImGuiID id = ImHashData(&ptr, sizeof(void*), seed); #ifndef IMGUI_DISABLE_DEBUG_TOOLS ImGuiContext& g = *Ctx; - if (g.DebugHookIdInfo == id) + if (g.DebugHookIdInfoId == id) ImGui::DebugHookIdInfo(id, ImGuiDataType_Pointer, ptr, NULL); #endif return id; @@ -9621,7 +9621,7 @@ ImGuiID ImGuiWindow::GetID(int n) ImGuiID id = ImHashData(&n, sizeof(n), seed); #ifndef IMGUI_DISABLE_DEBUG_TOOLS ImGuiContext& g = *Ctx; - if (g.DebugHookIdInfo == id) + if (g.DebugHookIdInfoId == id) ImGui::DebugHookIdInfo(id, ImGuiDataType_S32, (void*)(intptr_t)n, NULL); #endif return id; @@ -9684,7 +9684,7 @@ void ImGui::PushOverrideID(ImGuiID id) ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; #ifndef IMGUI_DISABLE_DEBUG_TOOLS - if (g.DebugHookIdInfo == id) + if (g.DebugHookIdInfoId == id) DebugHookIdInfo(id, ImGuiDataType_ID, NULL, NULL); #endif window->IDStack.push_back(id); @@ -9698,7 +9698,7 @@ ImGuiID ImGui::GetIDWithSeed(const char* str, const char* str_end, ImGuiID seed) ImGuiID id = ImHashStr(str, str_end ? (str_end - str) : 0, seed); #ifndef IMGUI_DISABLE_DEBUG_TOOLS ImGuiContext& g = *GImGui; - if (g.DebugHookIdInfo == id) + if (g.DebugHookIdInfoId == id) DebugHookIdInfo(id, ImGuiDataType_String, str, str_end); #endif return id; @@ -9709,7 +9709,7 @@ ImGuiID ImGui::GetIDWithSeed(int n, ImGuiID seed) ImGuiID id = ImHashData(&n, sizeof(n), seed); #ifndef IMGUI_DISABLE_DEBUG_TOOLS ImGuiContext& g = *GImGui; - if (g.DebugHookIdInfo == id) + if (g.DebugHookIdInfoId == id) DebugHookIdInfo(id, ImGuiDataType_S32, (void*)(intptr_t)n, NULL); #endif return id; @@ -14121,6 +14121,9 @@ static ImVec2 ImGui::NavCalcPreferredRefPos() const bool activated_shortcut = g.ActiveId != 0 && g.ActiveIdFromShortcut && g.ActiveId == g.LastItemData.ID; + if (source != ImGuiInputSource_Mouse && !activated_shortcut && window == NULL) + source = ImGuiInputSource_Mouse; + // Testing for !activated_shortcut here could in theory be removed if we decided that activating a remote shortcut altered one of the g.NavDisableXXX flag. if (source == ImGuiInputSource_Mouse) { @@ -14140,7 +14143,7 @@ static ImVec2 ImGui::NavCalcPreferredRefPos() ref_rect = WindowRectRelToAbs(window, window->NavRectRel[g.NavLayer]); // Take account of upcoming scrolling (maybe set mouse pos should be done in EndFrame?) - if (window->LastFrameActive != g.FrameCount && (window->ScrollTarget.x != FLT_MAX || window->ScrollTarget.y != FLT_MAX)) + if (window != NULL && window->LastFrameActive != g.FrameCount && (window->ScrollTarget.x != FLT_MAX || window->ScrollTarget.y != FLT_MAX)) { ImVec2 next_scroll = CalcNextScrollFromScrollTargetAndClamp(window); ref_rect.Translate(window->Scroll - next_scroll); @@ -23539,21 +23542,22 @@ void ImGui::UpdateDebugToolStackQueries() ImGuiIDStackTool* tool = &g.DebugIDStackTool; // Clear hook when id stack tool is not visible - g.DebugHookIdInfo = 0; + g.DebugHookIdInfoId = 0; + tool->QueryHookActive = false; if (g.FrameCount != tool->LastActiveFrame + 1) return; // Update queries. The steps are: -1: query Stack, >= 0: query each stack item // We can only perform 1 ID Info query every frame. This is designed so the GetID() tests are cheap and constant-time - const ImGuiID query_id = g.HoveredIdPreviousFrame ? g.HoveredIdPreviousFrame : g.ActiveId; - if (tool->QueryId != query_id) + const ImGuiID query_main_id = g.HoveredIdPreviousFrame ? g.HoveredIdPreviousFrame : g.ActiveId; + if (tool->QueryMainId != query_main_id) { - tool->QueryId = query_id; + tool->QueryMainId = query_main_id; tool->StackLevel = -1; tool->Results.resize(0); tool->ResultPathsBuf.resize(0); } - if (query_id == 0) + if (query_main_id == 0) return; // Advance to next stack level when we got our result, or after 2 frames (in case we never get a result) @@ -23565,11 +23569,15 @@ void ImGui::UpdateDebugToolStackQueries() // Update hook stack_level = tool->StackLevel; if (stack_level == -1) - g.DebugHookIdInfo = query_id; - if (stack_level >= 0 && stack_level < tool->Results.Size) { - g.DebugHookIdInfo = tool->Results[stack_level].ID; + g.DebugHookIdInfoId = query_main_id; + tool->QueryHookActive = true; + } + else if (stack_level >= 0 && stack_level < tool->Results.Size) + { + g.DebugHookIdInfoId = tool->Results[stack_level].ID; tool->Results[stack_level].QueryFrameCount++; + tool->QueryHookActive = true; } } @@ -23579,11 +23587,17 @@ void ImGui::DebugHookIdInfo(ImGuiID id, ImGuiDataType data_type, const void* dat ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; ImGuiIDStackTool* tool = &g.DebugIDStackTool; + if (tool->QueryHookActive == false) + { + IM_ASSERT(id == 0); + return; + } // Step 0: stack query // This assumes that the ID was computed with the current ID stack, which tends to be the case for our widget. if (tool->StackLevel == -1) { + IM_ASSERT(tool->Results.Size == 0); tool->StackLevel++; tool->Results.resize(window->IDStack.Size + 1, ImGuiStackLevelInfo()); for (int n = 0; n < window->IDStack.Size + 1; n++) @@ -23679,7 +23693,7 @@ void ImGui::ShowIDStackToolWindow(bool* p_open) p = p_next; } } - Text("0x%08X", tool->QueryId); + Text("0x%08X", tool->QueryMainId); SameLine(); MetricsHelpMarker("Hover an item with the mouse to display elements of the ID Stack leading to the item's final ID.\nEach level of the stack correspond to a PushID() call.\nAll levels of the stack are hashed together to make the final ID of a widget (ID displayed at the bottom level of the stack).\nRead FAQ entry about the ID stack for details."); @@ -23700,7 +23714,7 @@ void ImGui::ShowIDStackToolWindow(bool* p_open) Text("- Path \"%s\"", tool->ResultTempBuf.c_str()); #ifdef IMGUI_ENABLE_TEST_ENGINE - Text("- Label \"%s\"", tool->QueryId ? ImGuiTestEngine_FindItemDebugLabel(&g, tool->QueryId) : ""); + Text("- Label \"%s\"", tool->QueryMainId ? ImGuiTestEngine_FindItemDebugLabel(&g, tool->QueryMainId) : ""); #endif Separator(); diff --git a/imgui.h b/imgui.h index d21488a33..ac8cddd6d 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.92.3 WIP +// dear imgui, v1.92.3 // (headers) // Help: @@ -28,8 +28,8 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') -#define IMGUI_VERSION "1.92.3 WIP" -#define IMGUI_VERSION_NUM 19228 +#define IMGUI_VERSION "1.92.3" +#define IMGUI_VERSION_NUM 19230 #define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000 #define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198 #define IMGUI_HAS_VIEWPORT // In 'docking' WIP branch. diff --git a/imgui_demo.cpp b/imgui_demo.cpp index e746ba6b9..d124b774d 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.92.3 WIP +// dear imgui, v1.92.3 // (demo code) // Help: diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 5f37481d1..98cca3c99 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.92.3 WIP +// dear imgui, v1.92.3 // (drawing and font code) /* diff --git a/imgui_internal.h b/imgui_internal.h index 41f66afd1..aa2b23974 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.92.3 WIP +// dear imgui, v1.92.3 // (internal structures/api) // You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility. @@ -2319,15 +2319,16 @@ struct ImGuiIDStackTool { int LastActiveFrame; int StackLevel; // -1: query stack and resize Results, >= 0: individual stack level - ImGuiID QueryId; // ID to query details for + ImGuiID QueryMainId; // ID to query details for ImVector Results; + bool QueryHookActive; // Used to disambiguate the case where DebugHookIdInfoId == 0 which is valid. bool OptHexEncodeNonAsciiChars; bool OptCopyToClipboardOnCtrlC; float CopyToClipboardLastTime; ImGuiTextBuffer ResultPathsBuf; ImGuiTextBuffer ResultTempBuf; - ImGuiIDStackTool() { memset(this, 0, sizeof(*this)); OptHexEncodeNonAsciiChars = true; CopyToClipboardLastTime = -FLT_MAX; } + ImGuiIDStackTool() { memset(this, 0, sizeof(*this)); LastActiveFrame = -1; OptHexEncodeNonAsciiChars = true; CopyToClipboardLastTime = -FLT_MAX; } }; //----------------------------------------------------------------------------- @@ -2412,7 +2413,7 @@ struct ImGuiContext // Item/widgets state and tracking information ImGuiID DebugDrawIdConflictsId; // Set when we detect multiple items with the same identifier - ImGuiID DebugHookIdInfo; // Will call core hooks: DebugHookIdInfo() from GetID functions, used by ID Stack Tool [next HoveredId/ActiveId to not pull in an extra cache-line] + ImGuiID DebugHookIdInfoId; // Will call core hooks: DebugHookIdInfo() from GetID functions, used by ID Stack Tool [next HoveredId/ActiveId to not pull in an extra cache-line] ImGuiID HoveredId; // Hovered widget, filled during the frame ImGuiID HoveredIdPreviousFrame; int HoveredIdPreviousFrameItemCount; // Count numbers of items using the same ID as last frame's hovered id diff --git a/imgui_tables.cpp b/imgui_tables.cpp index 5b4e3e07d..f5c4c25aa 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.92.3 WIP +// dear imgui, v1.92.3 // (tables and columns code) /* diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index f4c12fcb8..629dd0eba 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.92.3 WIP +// dear imgui, v1.92.3 // (widgets code) /* @@ -5186,7 +5186,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ apply_new_text = ""; apply_new_text_length = 0; value_changed = true; - IMSTB_TEXTEDIT_CHARTYPE empty_string; + char empty_string = 0; stb_textedit_replace(state, state->Stb, &empty_string, 0); } else if (strcmp(state->TextA.Data, state->TextToRevertTo.Data) != 0)