diff --git a/examples/imgui_impl_win32.cpp b/examples/imgui_impl_win32.cpp index 63c27046..cf88c823 100644 --- a/examples/imgui_impl_win32.cpp +++ b/examples/imgui_impl_win32.cpp @@ -366,7 +366,7 @@ void ImGui_ImplWin32_EnableDpiAwareness() float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor) { UINT xdpi = 96, ydpi = 96; - if (IsWindows8Point1OrGreater()) + if (::IsWindows8Point1OrGreater()) { static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process if (PFN_GetDpiForMonitor GetDpiForMonitorFn = (PFN_GetDpiForMonitor)::GetProcAddress(shcore_dll, "GetDpiForMonitor")) @@ -389,13 +389,6 @@ float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd) return ImGui_ImplWin32_GetDpiScaleForMonitor(monitor); } -float ImGui_ImplWin32_GetDpiScaleForRect(int x1, int y1, int x2, int y2) -{ - RECT viewport_rect = { (LONG)x1, (LONG)y1, (LONG)x2, (LONG)y2 }; - HMONITOR monitor = ::MonitorFromRect(&viewport_rect, MONITOR_DEFAULTTONEAREST); - return ImGui_ImplWin32_GetDpiScaleForMonitor(monitor); -} - //-------------------------------------------------------------------------------------------------------- // IME (Input Method Editor) basic support for e.g. Asian language users //-------------------------------------------------------------------------------------------------------- @@ -589,13 +582,8 @@ static void ImGui_ImplWin32_SetWindowAlpha(ImGuiViewport* viewport, float alpha) static float ImGui_ImplWin32_GetWindowDpiScale(ImGuiViewport* viewport) { ImGuiViewportDataWin32* data = (ImGuiViewportDataWin32*)viewport->PlatformUserData; - if (data && data->Hwnd) - return ImGui_ImplWin32_GetDpiScaleForHwnd(data->Hwnd); - - // The first frame a viewport is created we don't have a window yet - return ImGui_ImplWin32_GetDpiScaleForRect( - (int)(viewport->Pos.x), (int)(viewport->Pos.y), - (int)(viewport->Pos.x + viewport->Size.x), (int)(viewport->Pos.y + viewport->Size.y)); + IM_ASSERT(data->Hwnd != 0); + return ImGui_ImplWin32_GetDpiScaleForHwnd(data->Hwnd); } // FIXME-DPI: Testing DPI related ideas @@ -706,7 +694,7 @@ static void ImGui_ImplWin32_InitPlatformInterface() platform_io.Platform_GetWindowMinimized = ImGui_ImplWin32_GetWindowMinimized; platform_io.Platform_SetWindowTitle = ImGui_ImplWin32_SetWindowTitle; platform_io.Platform_SetWindowAlpha = ImGui_ImplWin32_SetWindowAlpha; - platform_io.Platform_GetWindowDpiScale = ImGui_ImplWin32_GetWindowDpiScale; + platform_io.Platform_GetWindowDpiScale = ImGui_ImplWin32_GetWindowDpiScale; // FIXME-DPI platform_io.Platform_OnChangedViewport = ImGui_ImplWin32_OnChangedViewport; // FIXME-DPI #if HAS_WIN32_IME platform_io.Platform_SetImeInputPos = ImGui_ImplWin32_SetImeInputPos; diff --git a/examples/imgui_impl_win32.h b/examples/imgui_impl_win32.h index 5f163152..b7c9d819 100644 --- a/examples/imgui_impl_win32.h +++ b/examples/imgui_impl_win32.h @@ -16,10 +16,9 @@ IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown(); IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame(); // DPI-related helpers (which run and compile without requiring 8.1 or 10, neither Windows version, neither associated SDK) -IMGUI_API void ImGui_ImplWin32_EnableDpiAwareness(); -IMGUI_API float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd); // HWND hwnd -IMGUI_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor); // HMONITOR monitor -IMGUI_API float ImGui_ImplWin32_GetDpiScaleForRect(int x1, int y1, int x2, int y2); +IMGUI_IMPL_API void ImGui_ImplWin32_EnableDpiAwareness(); +IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd); // HWND hwnd +IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor); // HMONITOR monitor // Handler for Win32 messages, update mouse/keyboard data. // You may or not need this for your implementation, but it can serve as reference for handling inputs. diff --git a/imgui.cpp b/imgui.cpp index a7db3b7d..d499d1d8 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7376,8 +7376,10 @@ static void ImGui::UpdateViewports() // Update DPI scale float new_dpi_scale; - if (g.PlatformIO.Platform_GetWindowDpiScale) + if (g.PlatformIO.Platform_GetWindowDpiScale && platform_funcs_available) new_dpi_scale = g.PlatformIO.Platform_GetWindowDpiScale(viewport); + else if (viewport->PlatformMonitor != -1) + new_dpi_scale = g.PlatformIO.Monitors[viewport->PlatformMonitor].DpiScale; else new_dpi_scale = (viewport->DpiScale != 0.0f) ? viewport->DpiScale : 1.0f; if (viewport->DpiScale != 0.0f && new_dpi_scale != viewport->DpiScale) @@ -7490,10 +7492,10 @@ ImGuiViewportP* ImGui::AddUpdateViewport(ImGuiWindow* window, ImGuiID id, const g.DrawListSharedData.ClipRectFullscreen.z = ImMax(g.DrawListSharedData.ClipRectFullscreen.z, viewport->Pos.x + viewport->Size.x); g.DrawListSharedData.ClipRectFullscreen.w = ImMax(g.DrawListSharedData.ClipRectFullscreen.w, viewport->Pos.y + viewport->Size.y); - // Request an initial DpiScale before the OS platform window creation + // Store initial DpiScale before the OS platform window creation, based on expected monitor data. // This is so we can select an appropriate font size on the first frame of our window lifetime - if (g.PlatformIO.Platform_GetWindowDpiScale) - viewport->DpiScale = g.PlatformIO.Platform_GetWindowDpiScale(viewport); + if (viewport->PlatformMonitor != -1) + viewport->DpiScale = g.PlatformIO.Monitors[viewport->PlatformMonitor].DpiScale; } viewport->Window = window; diff --git a/imgui.h b/imgui.h index fc687fbc..f70b465b 100644 --- a/imgui.h +++ b/imgui.h @@ -2124,13 +2124,13 @@ struct ImFont // - if you are new to dear imgui and trying to integrate it into your engine, you should probably ignore this for now. //----------------------------------------------------------------------------- -// (Optional) Represent the bounds of each connected monitor/display -// Dear ImGui only uses this to clamp the position of popups and tooltips so they don't straddle multiple monitors. +// (Optional) Represent the bounds of each connected monitor/display and their DPI +// This is used for: multiple DPI support + clamping the position of popups and tooltips so they don't straddle multiple monitors. struct ImGuiPlatformMonitor { ImVec2 MainPos, MainSize; // Coordinates of the area displayed on this monitor (Min = upper left, Max = bottom right) ImVec2 WorkPos, WorkSize; // (Optional) Coordinates without task bars / side bars / menu bars. imgui uses this to avoid positioning popups/tooltips inside this region. - float DpiScale; + float DpiScale; // 1.0f = 96 DPI ImGuiPlatformMonitor() { MainPos = MainSize = WorkPos = WorkSize = ImVec2(0,0); DpiScale = 1.0f; } }; @@ -2165,7 +2165,7 @@ struct ImGuiPlatformIO void (*Platform_SetWindowAlpha)(ImGuiViewport* vp, float alpha); // (Optional) Setup window transparency void (*Platform_RenderWindow)(ImGuiViewport* vp, void* render_arg); // (Optional) Setup for render (platform side) void (*Platform_SwapBuffers)(ImGuiViewport* vp, void* render_arg); // (Optional) Call Present/SwapBuffers (platform side) - float (*Platform_GetWindowDpiScale)(ImGuiViewport* vp); // (Optional) [BETA] (FIXME-DPI) DPI handling: Return DPI scale for this viewport. 1.0f = 96 DPI. IMPORTANT: this will be called _before_ the window is created, in which case the implementation is expected to use the viewport->Pos/Size fields to estimate DPI value. + float (*Platform_GetWindowDpiScale)(ImGuiViewport* vp); // (Optional) [BETA] (FIXME-DPI) DPI handling: Return DPI scale for this viewport. 1.0f = 96 DPI. void (*Platform_OnChangedViewport)(ImGuiViewport* vp); // (Optional) [BETA] (FIXME-DPI) DPI handling: Called during Begin() every time the viewport we are outputting into changes, so back-end has a chance to swap fonts to adjust style. void (*Platform_SetImeInputPos)(ImGuiViewport* vp, ImVec2 pos); // (Optional) Set IME (Input Method Editor, e.g. for Asian languages) input position, so text preview appears over the imgui input box. int (*Platform_CreateVkSurface)(ImGuiViewport* vp, ImU64 vk_inst, const void* vk_allocators, ImU64* out_vk_surface); // (Optional) For Renderer to call into Platform code