// Show something on screen — a UIWindow with a colored UIViewController root. // // Builds on 5.7's AppDelegate. Inside `didFinishLaunching`, we: // 1. [[UIWindow alloc] initWithFrame:CGRect] // 2. [[UIViewController alloc] init]; set view.backgroundColor // 3. window.rootViewController = vc // 4. [window makeKeyAndVisible] // // We hardcode the frame to 1024×1024 to avoid the struct-return ABI of // `[UIScreen mainScreen].bounds` for now — any frame bigger than the device // covers the screen, modulo safe-area insets. // // `g_window` is a module-level global so the window outlives the IMP scope // (no ARC; UIKit retains it as the key window anyway). #import "modules/std.sx"; #import "modules/ffi/objc.sx"; #framework "UIKit"; UIApplicationMain :: (argc: i32, argv: *void, principal_class: *NSString, delegate_class: *NSString) -> i32 #foreign; g_window : *void = ---; // AppDelegate's `window` property. iOS queries this getter to discover the // app's key window; without it, the legacy code path creates its own empty // window and ignores anything we configure. window_getter :: (self: *void, _cmd: *void) -> *void callconv(.c) { return g_window; } window_setter :: (self: *void, _cmd: *void, w: *void) callconv(.c) { g_window = w; } did_finish_launching :: (self: *void, _cmd: *void, app: *void, opts: *void) -> u8 callconv(.c) { UIWindow := objc_getClass("UIWindow".ptr); UIViewController := objc_getClass("UIViewController".ptr); UIColor := objc_getClass("UIColor".ptr); sel_alloc := sel_registerName("alloc".ptr); sel_init := sel_registerName("init".ptr); sel_init_with_scene := sel_registerName("initWithWindowScene:".ptr); sel_view := sel_registerName("view".ptr); sel_system_blue := sel_registerName("systemBlueColor".ptr); sel_set_bg := sel_registerName("setBackgroundColor:".ptr); sel_set_root_vc := sel_registerName("setRootViewController:".ptr); sel_make_key_visible := sel_registerName("makeKeyAndVisible".ptr); sel_connected_scenes := sel_registerName("connectedScenes".ptr); sel_any_object := sel_registerName("anyObject".ptr); msg_o : (*void, *void) -> *void callconv(.c) = xx objc_msgSend; msg_v : (*void, *void) -> void callconv(.c) = xx objc_msgSend; msg_oo : (*void, *void, *void) -> void callconv(.c) = xx objc_msgSend; msg_ooo : (*void, *void, *void) -> *void callconv(.c) = xx objc_msgSend; // Modern iOS path: get the connected windowScene, then construct the // window via initWithWindowScene: so UIKit auto-sizes it and attaches // it to the display in one step. scenes := msg_o(app, sel_connected_scenes); scene := msg_o(scenes, sel_any_object); if scene == xx 0 { NSLog(xx "[sx] scene NULL\n"); return 1; } NSLog(xx "[sx] scene: ok\n"); win_raw := msg_o(UIWindow, sel_alloc); g_window = msg_ooo(win_raw, sel_init_with_scene, scene); NSLog(xx "[sx] window: ok\n"); vc_raw := msg_o(UIViewController, sel_alloc); vc := msg_o(vc_raw, sel_init); msg_oo(g_window, sel_set_root_vc, vc); blue := msg_o(UIColor, sel_system_blue); view := msg_o(vc, sel_view); msg_oo(view, sel_set_bg, blue); msg_oo(g_window, sel_set_bg, blue); msg_v(g_window, sel_make_key_visible); NSLog(xx "[sx] makeKeyAndVisible done\n"); return 1; } main :: () -> i32 { UIResponder := objc_getClass("UIResponder".ptr); SxAppDelegate := objc_allocateClassPair(UIResponder, "SxAppDelegate".ptr, 0); class_addMethod(SxAppDelegate, sel_registerName("application:didFinishLaunchingWithOptions:".ptr), xx did_finish_launching, "c@:@@".ptr); class_addMethod(SxAppDelegate, sel_registerName("window".ptr), xx window_getter, "@@:".ptr); class_addMethod(SxAppDelegate, sel_registerName("setWindow:".ptr), xx window_setter, "v@:@".ptr); objc_registerClassPair(SxAppDelegate); return UIApplicationMain(0, xx 0, xx 0, xx "SxAppDelegate"); }