mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
macos: correct scale factor propagated
This commit is contained in:
@ -53,6 +53,8 @@ int ghostty_app_tick(ghostty_app_t);
|
|||||||
|
|
||||||
ghostty_surface_t ghostty_surface_new(ghostty_app_t, ghostty_surface_config_s*);
|
ghostty_surface_t ghostty_surface_new(ghostty_app_t, ghostty_surface_config_s*);
|
||||||
void ghostty_surface_free(ghostty_surface_t);
|
void ghostty_surface_free(ghostty_surface_t);
|
||||||
|
void ghostty_surface_refresh(ghostty_surface_t);
|
||||||
|
void ghostty_surface_set_content_scale(ghostty_surface_t, double, double);
|
||||||
void ghostty_surface_set_size(ghostty_surface_t, uint32_t, uint32_t);
|
void ghostty_surface_set_size(ghostty_surface_t, uint32_t, uint32_t);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -33,6 +33,10 @@ class TerminalSurfaceView_Real: NSView, ObservableObject {
|
|||||||
// We need to support being a first responder so that we can get input events
|
// We need to support being a first responder so that we can get input events
|
||||||
override var acceptsFirstResponder: Bool { return true }
|
override var acceptsFirstResponder: Bool { return true }
|
||||||
|
|
||||||
|
// I don't thikn we need this but this lets us know we should redraw our layer
|
||||||
|
// so we'll use that to tell ghostty to refresh.
|
||||||
|
override var wantsUpdateLayer: Bool { return true }
|
||||||
|
|
||||||
private var surface: ghostty_surface_t? = nil
|
private var surface: ghostty_surface_t? = nil
|
||||||
private var error: Error? = nil
|
private var error: Error? = nil
|
||||||
|
|
||||||
@ -45,7 +49,7 @@ class TerminalSurfaceView_Real: NSView, ObservableObject {
|
|||||||
// Setup our surface. This will also initialize all the terminal IO.
|
// Setup our surface. This will also initialize all the terminal IO.
|
||||||
var surface_cfg = ghostty_surface_config_s(
|
var surface_cfg = ghostty_surface_config_s(
|
||||||
nsview: Unmanaged.passUnretained(self).toOpaque(),
|
nsview: Unmanaged.passUnretained(self).toOpaque(),
|
||||||
scale_factor: 1.0)
|
scale_factor: NSScreen.main!.backingScaleFactor)
|
||||||
guard let surface = ghostty_surface_new(app, &surface_cfg) else {
|
guard let surface = ghostty_surface_new(app, &surface_cfg) else {
|
||||||
self.error = AppError.surfaceCreateError
|
self.error = AppError.surfaceCreateError
|
||||||
return
|
return
|
||||||
@ -62,16 +66,44 @@ class TerminalSurfaceView_Real: NSView, ObservableObject {
|
|||||||
super.resize(withOldSuperviewSize: oldSize)
|
super.resize(withOldSuperviewSize: oldSize)
|
||||||
|
|
||||||
if let surface = self.surface {
|
if let surface = self.surface {
|
||||||
ghostty_surface_set_size(surface, UInt32(self.bounds.size.width), UInt32(self.bounds.size.height))
|
// Ghostty wants to know the actual framebuffer size...
|
||||||
|
let fbFrame = self.convertToBacking(self.frame);
|
||||||
|
ghostty_surface_set_size(surface, UInt32(fbFrame.size.width), UInt32(fbFrame.size.height))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func viewDidChangeBackingProperties() {
|
||||||
|
guard let surface = self.surface else { return }
|
||||||
|
|
||||||
|
// Detect our X/Y scale factor so we can update our surface
|
||||||
|
let fbFrame = self.convertToBacking(self.frame)
|
||||||
|
let xScale = fbFrame.size.width / self.frame.size.width
|
||||||
|
let yScale = fbFrame.size.height / self.frame.size.height
|
||||||
|
ghostty_surface_set_content_scale(surface, xScale, yScale)
|
||||||
|
|
||||||
|
// When our scale factor changes, so does our fb size so we send that too
|
||||||
|
ghostty_surface_set_size(surface, UInt32(fbFrame.size.width), UInt32(fbFrame.size.height))
|
||||||
|
}
|
||||||
|
|
||||||
|
override func updateLayer() {
|
||||||
|
guard let surface = self.surface else { return }
|
||||||
|
ghostty_surface_refresh(surface);
|
||||||
|
}
|
||||||
|
|
||||||
override func mouseDown(with event: NSEvent) {
|
override func mouseDown(with event: NSEvent) {
|
||||||
print("Mouse down: \(event)")
|
print("Mouse down: \(event)")
|
||||||
}
|
}
|
||||||
|
|
||||||
override func keyDown(with event: NSEvent) {
|
override func keyDown(with event: NSEvent) {
|
||||||
print("Key down: \(event)")
|
print("Key down: \(event)")
|
||||||
|
self.interpretKeyEvents([event])
|
||||||
|
}
|
||||||
|
|
||||||
|
override func doCommand(by selector: Selector) {
|
||||||
|
// This currently just prevents NSBeep from interpretKeyEvents but in the future
|
||||||
|
// we may want to make some of this work.
|
||||||
|
|
||||||
|
// print("SEL: \(selector)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
src/App.zig
10
src/App.zig
@ -397,9 +397,19 @@ pub const CAPI = struct {
|
|||||||
if (ptr) |v| v.app.closeWindow(v);
|
if (ptr) |v| v.app.closeWindow(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Tell the surface that it needs to schedule a render
|
||||||
|
export fn ghostty_surface_refresh(win: *Window) void {
|
||||||
|
win.window.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
/// Update the size of a surface. This will trigger resize notifications
|
/// Update the size of a surface. This will trigger resize notifications
|
||||||
/// to the pty and the renderer.
|
/// to the pty and the renderer.
|
||||||
export fn ghostty_surface_set_size(win: *Window, w: u32, h: u32) void {
|
export fn ghostty_surface_set_size(win: *Window, w: u32, h: u32) void {
|
||||||
win.window.updateSize(w, h);
|
win.window.updateSize(w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Update the content scale of the surface.
|
||||||
|
export fn ghostty_surface_set_content_scale(win: *Window, x: f64, y: f64) void {
|
||||||
|
win.window.updateContentScale(x, y);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@ -49,8 +49,8 @@ pub const App = struct {
|
|||||||
|
|
||||||
pub const Window = struct {
|
pub const Window = struct {
|
||||||
nsview: objc.Object,
|
nsview: objc.Object,
|
||||||
scale_factor: f64,
|
|
||||||
core_win: *CoreWindow,
|
core_win: *CoreWindow,
|
||||||
|
content_scale: apprt.ContentScale,
|
||||||
size: apprt.WindowSize,
|
size: apprt.WindowSize,
|
||||||
|
|
||||||
pub const Options = extern struct {
|
pub const Options = extern struct {
|
||||||
@ -67,7 +67,10 @@ pub const Window = struct {
|
|||||||
return .{
|
return .{
|
||||||
.core_win = core_win,
|
.core_win = core_win,
|
||||||
.nsview = objc.Object.fromId(opts.nsview),
|
.nsview = objc.Object.fromId(opts.nsview),
|
||||||
.scale_factor = opts.scale_factor,
|
.content_scale = .{
|
||||||
|
.x = @floatCast(f32, opts.scale_factor),
|
||||||
|
.y = @floatCast(f32, opts.scale_factor),
|
||||||
|
},
|
||||||
.size = .{ .width = 800, .height = 600 },
|
.size = .{ .width = 800, .height = 600 },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -77,8 +80,7 @@ pub const Window = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getContentScale(self: *const Window) !apprt.ContentScale {
|
pub fn getContentScale(self: *const Window) !apprt.ContentScale {
|
||||||
_ = self;
|
return self.content_scale;
|
||||||
return apprt.ContentScale{ .x = 1, .y = 1 };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getSize(self: *const Window) !apprt.WindowSize {
|
pub fn getSize(self: *const Window) !apprt.WindowSize {
|
||||||
@ -115,6 +117,20 @@ pub const Window = struct {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn refresh(self: *Window) void {
|
||||||
|
self.core_win.refreshCallback() catch |err| {
|
||||||
|
log.err("error in refresh callback err={}", .{err});
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn updateContentScale(self: *Window, x: f64, y: f64) void {
|
||||||
|
self.content_scale = .{
|
||||||
|
.x = @floatCast(f32, x),
|
||||||
|
.y = @floatCast(f32, y),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub fn updateSize(self: *Window, width: u32, height: u32) void {
|
pub fn updateSize(self: *Window, width: u32, height: u32) void {
|
||||||
self.size = .{
|
self.size = .{
|
||||||
.width = width,
|
.width = width,
|
||||||
|
@ -326,7 +326,7 @@ pub fn finalizeWindowInit(self: *const Metal, win: apprt.runtime.Window) !void {
|
|||||||
|
|
||||||
apprt.embedded => .{
|
apprt.embedded => .{
|
||||||
.view = win.nsview,
|
.view = win.nsview,
|
||||||
.scaleFactor = win.scale_factor,
|
.scaleFactor = @floatCast(f64, win.content_scale.x),
|
||||||
},
|
},
|
||||||
|
|
||||||
else => @compileError("unsupported apprt for metal"),
|
else => @compileError("unsupported apprt for metal"),
|
||||||
|
Reference in New Issue
Block a user