From a4ca2963a20235d9275c84aa4a5111a75c1614bf Mon Sep 17 00:00:00 2001 From: Qwerasd Date: Fri, 2 Feb 2024 03:00:43 -0500 Subject: [PATCH 1/2] fix(macOS): Prevent squash/stretch during resize --- macos/Sources/Ghostty/SurfaceView.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/macos/Sources/Ghostty/SurfaceView.swift b/macos/Sources/Ghostty/SurfaceView.swift index be7cd9e6e..311861d2e 100644 --- a/macos/Sources/Ghostty/SurfaceView.swift +++ b/macos/Sources/Ghostty/SurfaceView.swift @@ -118,6 +118,9 @@ extension Ghostty { } } .onAppear() { + // Prevent macOS from stretching rendered frames when the view is resized. + surfaceView.layerContentsPlacement = .topLeft + // Welcome to the SwiftUI bug house of horrors. On macOS 12 (at least // 12.5.1, didn't test other versions), the order in which the view // is added to the window hierarchy is such that $surfaceFocus is From 7b3deb13d803d8019cadffb5f8335be464d2e02a Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 2 Feb 2024 08:39:08 -0800 Subject: [PATCH 2/2] renderer/metal: apply layerContentsPlacement on macOS to fix stretching Fixes #42 --- macos/Sources/Ghostty/SurfaceView.swift | 3 --- pkg/macos/animation.zig | 6 ++++++ pkg/macos/animation/c.zig | 3 +++ pkg/macos/animation/layer.zig | 2 ++ pkg/macos/build.zig | 2 ++ pkg/macos/main.zig | 1 + src/renderer/Metal.zig | 4 ++++ 7 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 pkg/macos/animation.zig create mode 100644 pkg/macos/animation/c.zig create mode 100644 pkg/macos/animation/layer.zig diff --git a/macos/Sources/Ghostty/SurfaceView.swift b/macos/Sources/Ghostty/SurfaceView.swift index 311861d2e..be7cd9e6e 100644 --- a/macos/Sources/Ghostty/SurfaceView.swift +++ b/macos/Sources/Ghostty/SurfaceView.swift @@ -118,9 +118,6 @@ extension Ghostty { } } .onAppear() { - // Prevent macOS from stretching rendered frames when the view is resized. - surfaceView.layerContentsPlacement = .topLeft - // Welcome to the SwiftUI bug house of horrors. On macOS 12 (at least // 12.5.1, didn't test other versions), the order in which the view // is added to the window hierarchy is such that $surfaceFocus is diff --git a/pkg/macos/animation.zig b/pkg/macos/animation.zig new file mode 100644 index 000000000..af7405cd1 --- /dev/null +++ b/pkg/macos/animation.zig @@ -0,0 +1,6 @@ +pub const c = @import("animation/c.zig"); +pub usingnamespace @import("animation/layer.zig"); + +test { + @import("std").testing.refAllDecls(@This()); +} diff --git a/pkg/macos/animation/c.zig b/pkg/macos/animation/c.zig new file mode 100644 index 000000000..7cdcaf9bd --- /dev/null +++ b/pkg/macos/animation/c.zig @@ -0,0 +1,3 @@ +pub usingnamespace @cImport({ + @cInclude("QuartzCore/CALayer.h"); +}); diff --git a/pkg/macos/animation/layer.zig b/pkg/macos/animation/layer.zig new file mode 100644 index 000000000..dde7a5b66 --- /dev/null +++ b/pkg/macos/animation/layer.zig @@ -0,0 +1,2 @@ +/// https://developer.apple.com/documentation/quartzcore/calayer/contents_gravity_values?language=objc +pub extern "c" const kCAGravityTopLeft: *anyopaque; diff --git a/pkg/macos/build.zig b/pkg/macos/build.zig index 1a43c8daf..a9e3f6913 100644 --- a/pkg/macos/build.zig +++ b/pkg/macos/build.zig @@ -32,6 +32,7 @@ pub fn build(b: *std.Build) !void { lib.linkFramework("CoreGraphics"); lib.linkFramework("CoreText"); lib.linkFramework("CoreVideo"); + lib.linkFramework("QuartzCore"); if (target.result.os.tag == .macos) { lib.linkFramework("Carbon"); module.linkFramework("Carbon", .{}); @@ -42,6 +43,7 @@ pub fn build(b: *std.Build) !void { module.linkFramework("CoreGraphics", .{}); module.linkFramework("CoreText", .{}); module.linkFramework("CoreVideo", .{}); + module.linkFramework("QuartzCore", .{}); if (!target.query.isNative()) { try apple_sdk.addPaths(b, &lib.root_module); diff --git a/pkg/macos/main.zig b/pkg/macos/main.zig index 46071d55b..2b05f11ae 100644 --- a/pkg/macos/main.zig +++ b/pkg/macos/main.zig @@ -1,4 +1,5 @@ pub const foundation = @import("foundation.zig"); +pub const animation = @import("animation.zig"); pub const graphics = @import("graphics.zig"); pub const os = @import("os.zig"); pub const text = @import("text.zig"); diff --git a/src/renderer/Metal.zig b/src/renderer/Metal.zig index a0fd8ea00..2f938dad8 100644 --- a/src/renderer/Metal.zig +++ b/src/renderer/Metal.zig @@ -327,6 +327,10 @@ pub fn init(alloc: Allocator, options: renderer.Options) !Metal { if (comptime builtin.os.tag == .macos) { info.view.setProperty("layer", layer.value); info.view.setProperty("wantsLayer", true); + + // The layer gravity is set to top-left so that when we resize + // the view, the contents aren't stretched before a redraw. + layer.setProperty("contentsGravity", macos.animation.kCAGravityTopLeft); } // Ensure that our metal layer has a content scale set to match the