Backends: Metal, Metal4: fixed resizing windows losing framebuffer scale. (#6828, #8856)

Untested for Metal4
This commit is contained in:
ocornut
2026-08-06 22:12:39 +02:00
parent cf27a555ad
commit de4a2990a2
3 changed files with 29 additions and 14 deletions

View File

@@ -18,6 +18,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2026-XX-XX: Metal: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2026-08-06: Metal: fixed resizing windows losing framebuffer scale. (#6828, #8856)
// 2026-04-28: Added support for standard draw callbacks (in platform_io): DrawCallback_SetSamplerLinear and DrawCallback_SetSamplerNearest. (#9378, #9381)
// 2026-04-23: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState (others are not yet supported). (#9378)
// 2026-04-14: Metal: use a dedicated bufferCacheLock to avoid crashing when bufferCache is replaced by a new object while being used for @synchronize(). (#9367)
@@ -541,7 +542,15 @@ inline static CGSize MakeScaledSize(CGSize size, CGFloat scale)
static void ImGui_ImplMetal_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
{
ImGuiViewportDataMetal* data = (ImGuiViewportDataMetal*)viewport->RendererUserData;
data->MetalLayer.drawableSize = MakeScaledSize(CGSizeMake(size.x, size.y), viewport->DpiScale);
#if 0 && TARGET_OS_OSX
void* handle = viewport->PlatformHandleRaw ? viewport->PlatformHandleRaw : viewport->PlatformHandle;
NSWindow* window = (__bridge NSWindow*)handle;
CGFloat scale = window.backingScaleFactor;
data->MetalLayer.contentsScale = scale;
data->MetalLayer.drawableSize = MakeScaledSize(CGSizeMake(size.x, size.y), scale);
#else
data->MetalLayer.drawableSize = MakeScaledSize(CGSizeMake(size.x, size.y), data->MetalLayer.contentsScale);
#endif
}
static void ImGui_ImplMetal_RenderWindow(ImGuiViewport* viewport, void*)
@@ -561,12 +570,12 @@ static void ImGui_ImplMetal_RenderWindow(ImGuiViewport* viewport, void*)
}
data->FirstFrame = false;
float fb_scale = (float)window.backingScaleFactor;
if (data->MetalLayer.contentsScale != fb_scale)
{
data->MetalLayer.contentsScale = fb_scale;
data->MetalLayer.drawableSize = MakeScaledSize(window.frame.size, fb_scale);
}
// The layer is installed on the window's contentView; window.frame additionally includes the title bar.
CGFloat fb_scale = window.backingScaleFactor;
data->MetalLayer.contentsScale = fb_scale;
CGSize want_size = MakeScaledSize(window.contentView.bounds.size, fb_scale);
if (!CGSizeEqualToSize(data->MetalLayer.drawableSize, want_size))
data->MetalLayer.drawableSize = want_size;
#endif
id <CAMetalDrawable> drawable = [data->MetalLayer nextDrawable];

View File

@@ -21,6 +21,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2026-08-06: Metal 4: fixed resizing windows losing framebuffer scale. (#6828, #8856)
// 2026-07-07: Metal 4: Added metal-cpp support. (#9461)
// 2026-07-02: Metal 4: Added new Metal 4 backend implementation. (#9458)
@@ -847,7 +848,7 @@ inline static CGSize MakeScaledSize(CGSize size, CGFloat scale)
static void ImGui_ImplMetal_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
{
ImGuiViewportDataMetal* data = (ImGuiViewportDataMetal*)viewport->RendererUserData;
data->MetalLayer.drawableSize = MakeScaledSize(CGSizeMake(size.x, size.y), viewport->DpiScale);
data->MetalLayer.drawableSize = MakeScaledSize(CGSizeMake(size.x, size.y), data->MetalLayer.contentsScale);
}
static void ImGui_ImplMetal_RenderWindow(ImGuiViewport* viewport, void*)
@@ -867,12 +868,12 @@ static void ImGui_ImplMetal_RenderWindow(ImGuiViewport* viewport, void*)
}
data->FirstFrame = false;
float fb_scale = (float)window.backingScaleFactor;
if (data->MetalLayer.contentsScale != fb_scale)
{
data->MetalLayer.contentsScale = fb_scale;
data->MetalLayer.drawableSize = MakeScaledSize(window.frame.size, fb_scale);
}
// The layer is installed on the window's contentView; window.frame additionally includes the title bar.
CGFloat fb_scale = window.backingScaleFactor;
data->MetalLayer.contentsScale = fb_scale;
CGSize want_size = MakeScaledSize(window.contentView.bounds.size, fb_scale);
if (!CGSizeEqualToSize(data->MetalLayer.drawableSize, want_size))
data->MetalLayer.drawableSize = want_size;
#endif
id <CAMetalDrawable> drawable = [data->MetalLayer nextDrawable];

View File

@@ -68,6 +68,11 @@ Other Changes:
- SDL2+Metal: create Metal context without using a SDL_Renderer.
- QNX+OpenGL3, QNX+Vulkan: added QNX Screen examples. (#9492) [@mgorchak-blackberry]
Docking+Viewports Branch:
- Backends:
- Metal: fixed resizing windows losing framebuffer scale. (#6828, #8856) [@laikoken]
-----------------------------------------------------------------------
VERSION 1.92.9b (Released 2026-07-31)