fix(iOS): fix iOS app startup failure

Fixes #7643

This commit address the issue with 3 minor fixes:
1. Initialize ghostty lib before app start, or global allocator will
   be null.
2. `addSublayer` should be called on CALayer object, which is the
   property 'layer' of UIView
3. According to apple's [document](https://developer.apple.com/documentation/metal/mtlstoragemode/managed?language=objc),
   managed storage mode is not supported by iOS. So always use shared
   mode.

FYI, another [fix](https://github.com/mitchellh/libxev/pull/204) in libxev
is also required to make iOS app work.
This commit is contained in:
Zongyuan Li
2025-12-26 18:33:00 +08:00
committed by Zongyuan Li
parent f705b9f46a
commit 88e471e015
2 changed files with 16 additions and 4 deletions

View File

@@ -1,8 +1,16 @@
import SwiftUI
import GhosttyKit
@main
struct Ghostty_iOSApp: App {
@StateObject private var ghostty_app = Ghostty.App()
@StateObject private var ghostty_app: Ghostty.App
init() {
if ghostty_init(UInt(CommandLine.argc), CommandLine.unsafeArgv) != GHOSTTY_SUCCESS {
preconditionFailure("Initialize ghostty backend failed")
}
_ghostty_app = StateObject(wrappedValue: Ghostty.App())
}
var body: some Scene {
WindowGroup {

View File

@@ -76,8 +76,11 @@ pub fn init(alloc: Allocator, opts: rendererpkg.Options) !Metal {
errdefer queue.release();
// Grab metadata about the device.
const default_storage_mode: mtl.MTLResourceOptions.StorageMode =
if (device.getProperty(bool, "hasUnifiedMemory")) .shared else .managed;
const default_storage_mode: mtl.MTLResourceOptions.StorageMode = switch (comptime builtin.os.tag) {
// manage mode is not supported by iOS
.ios => .shared,
else => if (device.getProperty(bool, "hasUnifiedMemory")) .shared else .managed,
};
const max_texture_size = queryMaxTextureSize(device);
log.debug(
"device properties default_storage_mode={} max_texture_size={}",
@@ -123,7 +126,8 @@ pub fn init(alloc: Allocator, opts: rendererpkg.Options) !Metal {
},
.ios => {
info.view.msgSend(void, objc.sel("addSublayer"), .{layer.layer.value});
const view_layer = objc.Object.fromId(info.view.getProperty(?*anyopaque, "layer"));
view_layer.msgSend(void, objc.sel("addSublayer:"), .{layer.layer.value});
},
else => @compileError("unsupported target for Metal"),