From 7ccc18133205e504ad08e992d1d52411465f0312 Mon Sep 17 00:00:00 2001 From: Aaron Ruan Date: Thu, 15 May 2025 13:34:44 +0800 Subject: [PATCH 1/3] macos: add "Check for Updates" action, menu item & key-binding support --- include/ghostty.h | 1 + macos/Sources/App/macOS/AppDelegate.swift | 9 +++++---- macos/Sources/App/macOS/MainMenu.xib | 3 +++ macos/Sources/Ghostty/Ghostty.App.swift | 11 +++++++++++ src/App.zig | 1 + src/apprt/action.zig | 3 +++ src/input/Binding.zig | 6 ++++++ src/input/command.zig | 6 ++++++ 8 files changed, 36 insertions(+), 4 deletions(-) diff --git a/include/ghostty.h b/include/ghostty.h index 72f23b22b..941223943 100644 --- a/include/ghostty.h +++ b/include/ghostty.h @@ -667,6 +667,7 @@ typedef enum { GHOSTTY_ACTION_CONFIG_CHANGE, GHOSTTY_ACTION_CLOSE_WINDOW, GHOSTTY_ACTION_RING_BELL, + GHOSTTY_ACTION_CHECK_FOR_UPDATES } ghostty_action_tag_e; typedef union { diff --git a/macos/Sources/App/macOS/AppDelegate.swift b/macos/Sources/App/macOS/AppDelegate.swift index c5d63f55d..38b26f606 100644 --- a/macos/Sources/App/macOS/AppDelegate.swift +++ b/macos/Sources/App/macOS/AppDelegate.swift @@ -154,10 +154,6 @@ class AppDelegate: NSObject, toggleSecureInput(self) } - // Hook up updater menu - menuCheckForUpdates?.target = updaterController - menuCheckForUpdates?.action = #selector(SPUStandardUpdaterController.checkForUpdates(_:)) - // Initial config loading ghosttyConfigDidChange(config: ghostty.config) @@ -374,6 +370,7 @@ class AppDelegate: NSObject, private func syncMenuShortcuts(_ config: Ghostty.Config) { guard ghostty.readiness == .ready else { return } + syncMenuShortcut(config, action: "check_for_updates", menuItem: self.menuCheckForUpdates) syncMenuShortcut(config, action: "open_config", menuItem: self.menuOpenConfig) syncMenuShortcut(config, action: "reload_config", menuItem: self.menuReloadConfig) syncMenuShortcut(config, action: "quit", menuItem: self.menuQuit) @@ -791,6 +788,10 @@ class AppDelegate: NSObject, ghostty.reloadConfig() } + @IBAction func checkForUpdates(_ sender: Any?) { + updaterController.checkForUpdates(sender) + } + @IBAction func newWindow(_ sender: Any?) { terminalManager.newWindow() diff --git a/macos/Sources/App/macOS/MainMenu.xib b/macos/Sources/App/macOS/MainMenu.xib index 724f21355..828e82bd0 100644 --- a/macos/Sources/App/macOS/MainMenu.xib +++ b/macos/Sources/App/macOS/MainMenu.xib @@ -76,6 +76,9 @@ + + + diff --git a/macos/Sources/Ghostty/Ghostty.App.swift b/macos/Sources/Ghostty/Ghostty.App.swift index 65e91ce83..7b9e49f4c 100644 --- a/macos/Sources/Ghostty/Ghostty.App.swift +++ b/macos/Sources/Ghostty/Ghostty.App.swift @@ -550,6 +550,9 @@ extension Ghostty { case GHOSTTY_ACTION_RING_BELL: ringBell(app, target: target) + case GHOSTTY_ACTION_CHECK_FOR_UPDATES: + checkForUpdates(app) + case GHOSTTY_ACTION_CLOSE_ALL_WINDOWS: fallthrough case GHOSTTY_ACTION_TOGGLE_TAB_OVERVIEW: @@ -588,6 +591,14 @@ extension Ghostty { #endif } + private static func checkForUpdates( + _ app: ghostty_app_t, + ) { + if let appDelegate = NSApplication.shared.delegate as? AppDelegate { + appDelegate.checkForUpdates(nil) + } + } + private static func newWindow(_ app: ghostty_app_t, target: ghostty_target_s) { switch (target.tag) { case GHOSTTY_TARGET_APP: diff --git a/src/App.zig b/src/App.zig index 15859d115..005b745a6 100644 --- a/src/App.zig +++ b/src/App.zig @@ -444,6 +444,7 @@ pub fn performAction( .close_all_windows => _ = try rt_app.performAction(.app, .close_all_windows, {}), .toggle_quick_terminal => _ = try rt_app.performAction(.app, .toggle_quick_terminal, {}), .toggle_visibility => _ = try rt_app.performAction(.app, .toggle_visibility, {}), + .check_for_updates => _ = try rt_app.performAction(.app, .check_for_updates, {}), } } diff --git a/src/apprt/action.zig b/src/apprt/action.zig index 4be296f09..8a23bc1a4 100644 --- a/src/apprt/action.zig +++ b/src/apprt/action.zig @@ -255,6 +255,8 @@ pub const Action = union(Key) { /// it needs to ring the bell. This is usually a sound or visual effect. ring_bell, + check_for_updates, + /// Sync with: ghostty_action_tag_e pub const Key = enum(c_int) { quit, @@ -301,6 +303,7 @@ pub const Action = union(Key) { config_change, close_window, ring_bell, + check_for_updates, }; /// Sync with: ghostty_action_u diff --git a/src/input/Binding.zig b/src/input/Binding.zig index 89c5e4352..a22eb174d 100644 --- a/src/input/Binding.zig +++ b/src/input/Binding.zig @@ -509,6 +509,11 @@ pub const Action = union(enum) { /// This currently only works on macOS. toggle_visibility, + /// Check for updates. + /// + /// This currently only works on macOS. + check_for_updates, + /// Quit ghostty. quit, @@ -791,6 +796,7 @@ pub const Action = union(enum) { .quit, .toggle_quick_terminal, .toggle_visibility, + .check_for_updates, => .app, // These are app but can be special-cased in a surface context. diff --git a/src/input/command.zig b/src/input/command.zig index 1f685269b..8ef4a5f0e 100644 --- a/src/input/command.zig +++ b/src/input/command.zig @@ -364,6 +364,12 @@ fn actionCommands(action: Action.Key) []const Command { .description = "Toggle secure input mode.", }}, + .check_for_updates => comptime &.{.{ + .action = .check_for_updates, + .title = "Check for Updates", + .description = "Check for updates to the application.", + }}, + .quit => comptime &.{.{ .action = .quit, .title = "Quit", From f6d56f4f03ceb33b52e8cc9358eb7128807652f4 Mon Sep 17 00:00:00 2001 From: Aaron Ruan Date: Thu, 15 May 2025 23:26:47 +0800 Subject: [PATCH 2/3] Handle check_for_updates as unimplemented action --- src/apprt/glfw.zig | 1 + src/apprt/gtk/App.zig | 1 + 2 files changed, 2 insertions(+) diff --git a/src/apprt/glfw.zig b/src/apprt/glfw.zig index e416d5645..221d5344a 100644 --- a/src/apprt/glfw.zig +++ b/src/apprt/glfw.zig @@ -249,6 +249,7 @@ pub const App = struct { .prompt_title, .reset_window_size, .ring_bell, + .check_for_updates, => { log.info("unimplemented action={}", .{action}); return false; diff --git a/src/apprt/gtk/App.zig b/src/apprt/gtk/App.zig index 06cc41b9d..cddcf7159 100644 --- a/src/apprt/gtk/App.zig +++ b/src/apprt/gtk/App.zig @@ -504,6 +504,7 @@ pub fn performAction( .renderer_health, .color_change, .reset_window_size, + .check_for_updates, => { log.warn("unimplemented action={}", .{action}); return false; From f343e1ba461b00baf380539ac7a8f161d600f60e Mon Sep 17 00:00:00 2001 From: Aaron Ruan Date: Fri, 16 May 2025 00:40:25 +0800 Subject: [PATCH 3/3] Fix comma typo --- macos/Sources/Ghostty/Ghostty.App.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/macos/Sources/Ghostty/Ghostty.App.swift b/macos/Sources/Ghostty/Ghostty.App.swift index 7b9e49f4c..6736449a4 100644 --- a/macos/Sources/Ghostty/Ghostty.App.swift +++ b/macos/Sources/Ghostty/Ghostty.App.swift @@ -592,7 +592,7 @@ extension Ghostty { } private static func checkForUpdates( - _ app: ghostty_app_t, + _ app: ghostty_app_t ) { if let appDelegate = NSApplication.shared.delegate as? AppDelegate { appDelegate.checkForUpdates(nil)