diff --git a/README.md b/README.md index bac9bd9d9..1e83824ab 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ beta users using Ghostty as their primary terminal. See more in | Platform / Package | Links | Notes | | ------------------ | -------------------------------------------------------------------------- | -------------------------- | -| macOS | [Tip ("Nightly")](https://github.com/ghostty-org/ghostty/releases/tag/tip) | MacOS 12+ Universal Binary | +| macOS | [Tip ("Nightly")](https://github.com/ghostty-org/ghostty/releases/tag/tip) | MacOS 13+ Universal Binary | | Linux | [Build from Source](#developing-ghostty) | | | Linux (NixOS/Nix) | [Use the Flake](#nix-package) | | | Linux (Arch) | [Use the AUR package](https://aur.archlinux.org/packages/ghostty-git) | | diff --git a/build.zig b/build.zig index e272932e5..0c9cc9441 100644 --- a/build.zig +++ b/build.zig @@ -759,12 +759,10 @@ pub fn build(b: *std.Build) !void { /// be used generally, it should only be used for Darwin-based OS currently. fn osVersionMin(tag: std.Target.Os.Tag) ?std.Target.Query.OsVersion { return switch (tag) { - // The lowest supported version of macOS is 12.x because - // this is the first version to support Apple Silicon so it is - // the earliest version we can virtualize to test (I only have - // an Apple Silicon machine for macOS). + // We support back to the earliest officially supported version + // of macOS by Apple. EOL versions are not supported. .macos => .{ .semver = .{ - .major = 12, + .major = 13, .minor = 0, .patch = 0, } }, diff --git a/macos/Ghostty.xcodeproj/project.pbxproj b/macos/Ghostty.xcodeproj/project.pbxproj index 502eb3e6a..b60eb11f5 100644 --- a/macos/Ghostty.xcodeproj/project.pbxproj +++ b/macos/Ghostty.xcodeproj/project.pbxproj @@ -731,7 +731,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = 12.0; + MACOSX_DEPLOYMENT_TARGET = 13.0; MARKETING_VERSION = 0.1; "OTHER_LDFLAGS[arch=*]" = "-lstdc++"; PRODUCT_BUNDLE_IDENTIFIER = com.mitchellh.ghostty; @@ -898,7 +898,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = 12.0; + MACOSX_DEPLOYMENT_TARGET = 13.0; MARKETING_VERSION = 0.1; "OTHER_LDFLAGS[arch=*]" = "-lstdc++"; PRODUCT_BUNDLE_IDENTIFIER = com.mitchellh.ghostty.debug; @@ -951,7 +951,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = 12.0; + MACOSX_DEPLOYMENT_TARGET = 13.0; MARKETING_VERSION = 0.1; "OTHER_LDFLAGS[arch=*]" = "-lstdc++"; PRODUCT_BUNDLE_IDENTIFIER = com.mitchellh.ghostty; diff --git a/macos/Sources/Features/Terminal/TerminalToolbar.swift b/macos/Sources/Features/Terminal/TerminalToolbar.swift index a9f3b530e..ba6906a77 100644 --- a/macos/Sources/Features/Terminal/TerminalToolbar.swift +++ b/macos/Sources/Features/Terminal/TerminalToolbar.swift @@ -29,12 +29,7 @@ class TerminalToolbar: NSToolbar, NSToolbarDelegate { super.init(identifier: identifier) delegate = self - - if #available(macOS 13.0, *) { - centeredItemIdentifiers.insert(.titleText) - } else { - centeredItemIdentifier = .titleText - } + centeredItemIdentifiers.insert(.titleText) } func toolbar(_ toolbar: NSToolbar, diff --git a/macos/Sources/Ghostty/Ghostty.TerminalSplit.swift b/macos/Sources/Ghostty/Ghostty.TerminalSplit.swift index 6d288b434..d4f82620c 100644 --- a/macos/Sources/Ghostty/Ghostty.TerminalSplit.swift +++ b/macos/Sources/Ghostty/Ghostty.TerminalSplit.swift @@ -447,19 +447,6 @@ extension Ghostty { } window.makeFirstResponder(to) - - // On newer versions of macOS everything above works great so we're done. - if #available(macOS 13, *) { return } - - // On macOS 12, splits do not properly gain focus. I don't know why, but - // it seems like the `focused` SwiftUI method doesn't work. We use - // NotificationCenter as a blunt force instrument to make it work. - if #available(macOS 12, *) { - NotificationCenter.default.post( - name: Notification.didBecomeFocusedSurface, - object: to - ) - } } } } diff --git a/macos/Sources/Ghostty/Package.swift b/macos/Sources/Ghostty/Package.swift index 63a41596a..f6fab532e 100644 --- a/macos/Sources/Ghostty/Package.swift +++ b/macos/Sources/Ghostty/Package.swift @@ -230,10 +230,6 @@ extension Ghostty.Notification { static let ghosttyToggleFullscreen = Notification.Name("com.mitchellh.ghostty.toggleFullscreen") static let FullscreenModeKey = ghosttyToggleFullscreen.rawValue - /// Notification that a surface is becoming focused. This is only sent on macOS 12 to - /// work around bugs. macOS 13+ should use the ".focused()" attribute. - static let didBecomeFocusedSurface = Notification.Name("com.mitchellh.ghostty.didBecomeFocusedSurface") - /// Notification sent to toggle split maximize/unmaximize. static let didToggleSplitZoom = Notification.Name("com.mitchellh.ghostty.didToggleSplitZoom") diff --git a/macos/Sources/Ghostty/SurfaceView.swift b/macos/Sources/Ghostty/SurfaceView.swift index b7643aada..738c6331f 100644 --- a/macos/Sources/Ghostty/SurfaceView.swift +++ b/macos/Sources/Ghostty/SurfaceView.swift @@ -84,10 +84,6 @@ extension Ghostty { // is up to date. See TerminalSurfaceView for why we don't use the NSView // resize callback. GeometryReader { geo in - // We use these notifications to determine when the window our surface is - // attached to is or is not focused. - let pubBecomeFocused = center.publisher(for: Notification.didBecomeFocusedSurface, object: surfaceView) - #if canImport(AppKit) let pubBecomeKey = center.publisher(for: NSWindow.didBecomeKeyNotification) let pubResign = center.publisher(for: NSWindow.didResignKeyNotification) @@ -130,45 +126,6 @@ extension Ghostty { return true } #endif - .onReceive(pubBecomeFocused) { notification in - // We only want to run this on older macOS versions where the .focused - // method doesn't work properly. See the dispatch of this notification - // for more information. - if #available(macOS 13, *) { return } - - DispatchQueue.main.async { - surfaceFocus = true - } - } - .onAppear() { - // 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 - // not set to true for the first surface in a window. As a result, - // new windows are key (they have window focus) but the terminal surface - // does not have surface until the user clicks. Bad! - // - // There is a very real chance that I am doing something wrong, but it - // works great as-is on macOS 13, so I've instead decided to make the - // older macOS hacky. A workaround is on initial appearance to "steal - // focus" under certain conditions that seem to imply we're in the - // screwy state. - if #available(macOS 13, *) { - // If we're on a more modern version of macOS, do nothing. - return - } - if #available(macOS 12, *) { - // On macOS 13, the view is attached to a window at this point, - // so this is one extra check that we're a new view and behaving odd. - guard surfaceView.window == nil else { return } - DispatchQueue.main.async { - surfaceFocus = true - } - } - - // I don't know how older macOS versions behave but Ghostty only - // supports back to macOS 12 so its moot. - } // If our geo size changed then we show the resize overlay as configured. if let surfaceSize = surfaceView.surfaceSize { @@ -338,7 +295,7 @@ extension Ghostty { let overlay: Ghostty.Config.ResizeOverlay let position: Ghostty.Config.ResizeOverlayPosition let duration: UInt - let focusInstant: Any? + let focusInstant: ContinuousClock.Instant? // This is the last size that we processed. This is how we handle our // timer state. @@ -361,14 +318,12 @@ extension Ghostty { // If we were focused recently we hide it as well. This avoids showing // the resize overlay when SwiftUI is lazily resizing. - if #available(macOS 13, iOS 16, *) { - if let instant = focusInstant as? ContinuousClock.Instant { - let d = instant.duration(to: ContinuousClock.now) - if (d < .milliseconds(500)) { - // Avoid this size completely. - lastSize = geoSize - return true; - } + if let instant = focusInstant { + let d = instant.duration(to: ContinuousClock.now) + if (d < .milliseconds(500)) { + // Avoid this size completely. + lastSize = geoSize + return true; } } diff --git a/macos/Sources/Ghostty/SurfaceView_AppKit.swift b/macos/Sources/Ghostty/SurfaceView_AppKit.swift index 3b96ac012..c59c47e16 100644 --- a/macos/Sources/Ghostty/SurfaceView_AppKit.swift +++ b/macos/Sources/Ghostty/SurfaceView_AppKit.swift @@ -35,7 +35,7 @@ extension Ghostty { // The time this surface last became focused. This is a ContinuousClock.Instant // on supported platforms. - @Published var focusInstant: Any? = nil + @Published var focusInstant: ContinuousClock.Instant? = nil // Returns sizing information for the surface. This is the raw C // structure because I'm lazy. @@ -232,10 +232,8 @@ extension Ghostty { } // On macOS 13+ we can store our continuous clock... - if #available(macOS 13, iOS 16, *) { - if (focused) { - focusInstant = ContinuousClock.now - } + if (focused) { + focusInstant = ContinuousClock.now } } diff --git a/macos/Sources/Ghostty/SurfaceView_UIKit.swift b/macos/Sources/Ghostty/SurfaceView_UIKit.swift index b8c58caaa..1c2357960 100644 --- a/macos/Sources/Ghostty/SurfaceView_UIKit.swift +++ b/macos/Sources/Ghostty/SurfaceView_UIKit.swift @@ -30,7 +30,7 @@ extension Ghostty { // The time this surface last became focused. This is a ContinuousClock.Instant // on supported platforms. - @Published var focusInstant: Any? = nil + @Published var focusInstant: ContinuousClock.Instant? = nil // Returns sizing information for the surface. This is the raw C // structure because I'm lazy. @@ -73,10 +73,8 @@ extension Ghostty { ghostty_surface_set_focus(surface, focused) // On macOS 13+ we can store our continuous clock... - if #available(macOS 13, iOS 16, *) { - if (focused) { - focusInstant = ContinuousClock.now - } + if (focused) { + focusInstant = ContinuousClock.now } } diff --git a/macos/Sources/Helpers/Backport.swift b/macos/Sources/Helpers/Backport.swift index 8c3c10502..a28be15ae 100644 --- a/macos/Sources/Helpers/Backport.swift +++ b/macos/Sources/Helpers/Backport.swift @@ -15,13 +15,7 @@ extension Scene { } extension Backport where Content: Scene { - func defaultSize(width: CGFloat, height: CGFloat) -> some Scene { - if #available(macOS 13, *) { - return content.defaultSize(width: width, height: height) - } else { - return content - } - } + // None currently } extension Backport where Content: View { diff --git a/macos/Sources/Helpers/NSScreen+Extension.swift b/macos/Sources/Helpers/NSScreen+Extension.swift index 1091436dd..ef2c02908 100644 --- a/macos/Sources/Helpers/NSScreen+Extension.swift +++ b/macos/Sources/Helpers/NSScreen+Extension.swift @@ -29,11 +29,7 @@ extension NSScreen { // We need to see if our visible frame height is less than the full // screen height minus the menu and notch and such. let menuHeight = NSApp.mainMenu?.menuBarHeight ?? 0 - let notchInset: CGFloat = if #available(macOS 12, *) { - safeAreaInsets.top - } else { - 0 - } + let notchInset: CGFloat = safeAreaInsets.top let boundaryAreaPadding = 5.0 return visibleFrame.height < (frame.height - max(menuHeight, notchInset) - boundaryAreaPadding) diff --git a/src/apprt/glfw.zig b/src/apprt/glfw.zig index 980c2dba3..cbb9b7e48 100644 --- a/src/apprt/glfw.zig +++ b/src/apprt/glfw.zig @@ -559,25 +559,15 @@ pub const Surface = struct { // Clean up our core surface so that all the rendering and IO stop. self.core_surface.deinit(); - var tabgroup_opt: if (App.Darwin.enabled) ?objc.Object else void = undefined; if (App.Darwin.enabled) { const nswindow = objc.Object.fromId(glfwNative.getCocoaWindow(self.window).?); const tabgroup = nswindow.getProperty(objc.Object, "tabGroup"); - - // On macOS versions prior to Ventura, we lose window focus on tab close - // for some reason. We manually fix this by keeping track of the tab - // group and just selecting the next window. - if (internal_os.macosVersionAtLeast(13, 0, 0)) - tabgroup_opt = null - else - tabgroup_opt = tabgroup; - const windows = tabgroup.getProperty(objc.Object, "windows"); switch (windows.getProperty(usize, "count")) { // If we're going down to one window our tab bar is going to be // destroyed so unset it so that the later logic doesn't try to // use it. - 1 => tabgroup_opt = null, + 1 => {}, // If our tab bar is visible and we are going down to 1 window, // hide the tab bar. The check is "2" because our current window @@ -597,15 +587,6 @@ pub const Surface = struct { c.destroy(); self.cursor = null; } - - // If we have a tabgroup set, we want to manually focus the next window. - // We should NOT have to do this usually, see the comments above. - if (App.Darwin.enabled) { - if (tabgroup_opt) |tabgroup| { - const selected = tabgroup.getProperty(objc.Object, "selectedWindow"); - selected.msgSend(void, objc.sel("makeKeyWindow"), .{}); - } - } } /// Checks if the glfw window is in fullscreen.