Viewports: added per-viewport FramebufferScale, Platform_GetWindowFramebufferScale() + Backends: GLFW, SDL2, SDL3, Apple: added support. (#1065, #1542, #1676, #1786, #2826, #3757, #5081, #5580, #5592, #6465, #7273, #7779 etc.)

)

Metal backend is not in charge of writing to DpiScale/FramebufferScale (tho it was a neat workaround).
This commit is contained in:
ocornut
2025-05-15 14:31:26 +02:00
parent 63554bcee5
commit c90ea1315a
9 changed files with 119 additions and 46 deletions

View File

@@ -31,7 +31,8 @@
// 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-04-26: Disable multi-viewports under Wayland. (#8587)
// 2025-05-15: [Docking] Add Platform_GetWindowFramebufferScale() handler, to allow varying Retina display density on multiple monitors.
// 2025-04-26: [Docking] Disable multi-viewports under Wayland. (#8587)
// 2025-03-10: Map GLFW_KEY_WORLD_1 and GLFW_KEY_WORLD_2 into ImGuiKey_Oem102.
// 2025-03-03: Fixed clipboard handler assertion when using GLFW <= 3.2.1 compiled with asserts enabled.
// 2025-02-21: [Docking] Update monitors and work areas information every frame, as the later may change regardless of monitor changes. (#8415)
@@ -970,20 +971,26 @@ static void ImGui_ImplGlfw_UpdateMonitors()
}
}
static void ImGui_ImplGlfw_GetWindowSizeAndFramebufferScale(GLFWwindow* window, ImVec2* out_size, ImVec2* out_framebuffer_scale)
{
int w, h;
int display_w, display_h;
glfwGetWindowSize(window, &w, &h);
glfwGetFramebufferSize(window, &display_w, &display_h);
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);
}
void ImGui_ImplGlfw_NewFrame()
{
ImGuiIO& io = ImGui::GetIO();
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplGlfw_InitForXXX()?");
// Setup display size (every frame to accommodate for window resizing)
int w, h;
int display_w, display_h;
glfwGetWindowSize(bd->Window, &w, &h);
glfwGetFramebufferSize(bd->Window, &display_w, &display_h);
io.DisplaySize = ImVec2((float)w, (float)h);
if (w > 0 && h > 0)
io.DisplayFramebufferScale = ImVec2((float)display_w / (float)w, (float)display_h / (float)h);
// Setup main viewport size (every frame to accommodate for window resizing)
ImGui_ImplGlfw_GetWindowSizeAndFramebufferScale(bd->Window, &io.DisplaySize, &io.DisplayFramebufferScale);
ImGui_ImplGlfw_UpdateMonitors();
// Setup time step
@@ -1283,6 +1290,14 @@ static void ImGui_ImplGlfw_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
glfwSetWindowSize(vd->Window, (int)size.x, (int)size.y);
}
static ImVec2 ImGui_ImplGlfw_GetWindowFramebufferScale(ImGuiViewport* viewport)
{
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
ImVec2 framebuffer_scale;
ImGui_ImplGlfw_GetWindowSizeAndFramebufferScale(vd->Window, nullptr, &framebuffer_scale);
return framebuffer_scale;
}
static void ImGui_ImplGlfw_SetWindowTitle(ImGuiViewport* viewport, const char* title)
{
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
@@ -1381,6 +1396,7 @@ static void ImGui_ImplGlfw_InitMultiViewportSupport()
platform_io.Platform_GetWindowPos = ImGui_ImplGlfw_GetWindowPos;
platform_io.Platform_SetWindowSize = ImGui_ImplGlfw_SetWindowSize;
platform_io.Platform_GetWindowSize = ImGui_ImplGlfw_GetWindowSize;
platform_io.Platform_GetWindowFramebufferScale = ImGui_ImplGlfw_GetWindowFramebufferScale;
platform_io.Platform_SetWindowFocus = ImGui_ImplGlfw_SetWindowFocus;
platform_io.Platform_GetWindowFocus = ImGui_ImplGlfw_GetWindowFocus;
platform_io.Platform_GetWindowMinimized = ImGui_ImplGlfw_GetWindowMinimized;