# macOS app, MA1: foundation Design and work split: `macos-app-design.md`. Crate `crates/ghostty-macos` (lib `ghostty_macos`, bin `ghostty-macos-app`; empty stub off Apple). Compile-checked only (`just check-macos`, aarch64 + x86_64, clippy `-D warnings`, lib + tests + bin); never run on a Mac. Platform independent logic is unit-tested on Linux (125+ tests). ## Ported (Swift -> Rust) * `App/macOS/main.swift` -> `app/entry.rs`; `AppDelegate.swift` -> `app/app_delegate.rs` (all delegate methods, lifecycle, dock menu, open-file with execute confirmation, quit confirmation incl. shutdown/restart AppleEvent check, SIGUSR2 reload, local key monitor, bell/dock badge, user notifications via objc2-user-notifications, appearance KVO, config-change handling, menu shortcut sync + `performGhosttyBindingMenuKeyEquivalent`, float-on-top, set-as-default-terminal, `validateMenuItem`, toggle visibility); `AppDelegate+Ghostty.swift` -> `app/app_delegate_ghostty.rs`. * `MainMenu.xib` -> `app/menu_spec/` (tables generated by `scripts/gen-macos-menu-spec.py`, plus `Outlet`, `SYNCED_SHORTCUTS`, `MENU_IMAGES`, `MenuShortcutKey`, dock menu; tested) and `app/main_menu.rs` (builds the NSMenus, system menus, NSFontManager). * `Ghostty.App/Config/ConfigTypes/Command/Action/Error/Event/Shell/Surface`, `GhosttyPackage`, `NSEvent+Extension`, top of `Ghostty.Input`, `SurfaceConfiguration`, a model-only `SurfaceView` -> `ghostty/*` (by forks F1-F3 of MA1; see design doc). * `Helpers/*` generic ones -> `helpers/*`; unportable SwiftUI-only helpers listed in the design doc. * `scripts/macos-bundle.sh` (Ghostty.app assembly, dry-run off macOS), `scripts/gen-macos-capi-consts.py`, `scripts/gen-macos-menu-spec.py`, `scripts/macos-crosscheck.sh` now includes `ghostty-macos` (+ its bin). * Stubs with the surface `AppDelegate`/`Ghostty.App` use (owners replace them): `features/terminal` (MA3), `quick_terminal::controller`, `settings`, `about`, `secure_input`, `global_keybinds`, `services`, `custom_app_icon` (MA4), `update` (MA5). ## Deviations * Menu outlets: the xib's `menuSelectionForSearch` outlet does not exist in Swift (and "Jump to Selection" is unconnected), so those two items never get a config shortcut -- kept as upstream (module docs of `menu_spec`). * `NSApplicationMain` + nib -> explicit NSApplication/delegate/menu setup in `entry::run` (no `NSMainNibFile`). * `application(_:willEncode/didDecodeRestorableState:)`: quick terminal state not encoded yet (TODO(MA4)). * `updateAppIcon`: AppIcon persistence is MA4's; only the distributed `iconDidChange` notification is posted. * Fork-reported deviations: `Ghostty.Config.backgroundColor` falls back to a fixed light gray (Swift: dynamic `windowBackgroundColor`); `window_fullscreen*` getters return raw strings until MA3 (typed `FullscreenMode`); `open_config` passes the byte length of the URL (Swift `String.count` truncates non-ASCII paths); desktop notifications hop to the main queue before touching the view; `CodableBridge` archives are not byte-compatible with Swift's; `ExpiringTarget` drop only invalidates the timer; MIME->UTI lookups use CoreServices C functions; tab-add error is `ObjCException{name,reason}`; `PasteboardHandle` is an identity `usize`; user-visible duration format "1 hr, 2 min, 3 sec" matches Foundation en_US abbreviated style but the `.hide` fractional rounding is unverified off macOS. ## Known gaps / TODO(integration) * Nothing here has run on a Mac; objc2 method signatures were only type-checked. * `TODO(MA2)` in `ghostty/surface_view.rs`/`surface.rs`, `TODO(MA3)` terminal stubs and `fullscreen::set_is_tab_bar_hook`, `TODO(MA4)` feature stubs, `TODO(MA5)` update. * `SurfaceView::set_password_input` does not yet drive `SecureInput` (MA4). * The bundle script does not embed Sparkle/the DockTilePlugin (MA5/MA4); no `.lproj` localizations exist in the Swift tree either.