diff --git a/include/ghostty.h b/include/ghostty.h
index 357d40de5..0b70e2549 100644
--- a/include/ghostty.h
+++ b/include/ghostty.h
@@ -354,6 +354,7 @@ typedef struct {
typedef void (*ghostty_runtime_wakeup_cb)(void *);
typedef const ghostty_config_t (*ghostty_runtime_reload_config_cb)(void *);
+typedef void (*ghostty_runtime_open_config_cb)(void *);
typedef void (*ghostty_runtime_set_title_cb)(void *, const char *);
typedef void (*ghostty_runtime_set_mouse_shape_cb)(void *, ghostty_mouse_shape_e);
typedef void (*ghostty_runtime_set_mouse_visibility_cb)(void *, bool);
@@ -381,6 +382,7 @@ typedef struct {
bool supports_selection_clipboard;
ghostty_runtime_wakeup_cb wakeup_cb;
ghostty_runtime_reload_config_cb reload_config_cb;
+ ghostty_runtime_open_config_cb open_config_cb;
ghostty_runtime_set_title_cb set_title_cb;
ghostty_runtime_set_mouse_shape_cb set_mouse_shape_cb;
ghostty_runtime_set_mouse_visibility_cb set_mouse_visibility_cb;
@@ -422,12 +424,14 @@ bool ghostty_config_get(ghostty_config_t, void *, const char *, uintptr_t);
ghostty_input_trigger_s ghostty_config_trigger(ghostty_config_t, const char *, uintptr_t);
uint32_t ghostty_config_errors_count(ghostty_config_t);
ghostty_error_s ghostty_config_get_error(ghostty_config_t, uint32_t);
+void ghostty_config_open();
ghostty_app_t ghostty_app_new(const ghostty_runtime_config_s *, ghostty_config_t);
void ghostty_app_free(ghostty_app_t);
bool ghostty_app_tick(ghostty_app_t);
void *ghostty_app_userdata(ghostty_app_t);
void ghostty_app_keyboard_changed(ghostty_app_t);
+void ghostty_app_open_config(ghostty_app_t);
void ghostty_app_reload_config(ghostty_app_t);
bool ghostty_app_needs_confirm_quit(ghostty_app_t);
diff --git a/macos/Sources/AppDelegate.swift b/macos/Sources/AppDelegate.swift
index 44e11ef28..d1b16d176 100644
--- a/macos/Sources/AppDelegate.swift
+++ b/macos/Sources/AppDelegate.swift
@@ -12,6 +12,7 @@ class AppDelegate: NSObject, ObservableObject, NSApplicationDelegate, UNUserNoti
)
/// Various menu items so that we can programmatically sync the keyboard shortcut with the Ghostty config.
+ @IBOutlet private var menuOpenConfig: NSMenuItem?
@IBOutlet private var menuReloadConfig: NSMenuItem?
@IBOutlet private var menuQuit: NSMenuItem?
@@ -212,6 +213,7 @@ class AppDelegate: NSObject, ObservableObject, NSApplicationDelegate, UNUserNoti
private func syncMenuShortcuts() {
guard ghostty.config != nil else { return }
+ syncMenuShortcut(action: "open_config", menuItem: self.menuOpenConfig)
syncMenuShortcut(action: "reload_config", menuItem: self.menuReloadConfig)
syncMenuShortcut(action: "quit", menuItem: self.menuQuit)
@@ -342,6 +344,10 @@ class AppDelegate: NSObject, ObservableObject, NSApplicationDelegate, UNUserNoti
//MARK: - IB Actions
+ @IBAction func openConfig(_ sender: Any?) {
+ ghostty.openConfig()
+ }
+
@IBAction func reloadConfig(_ sender: Any?) {
ghostty.reloadConfig()
}
diff --git a/macos/Sources/Ghostty/AppState.swift b/macos/Sources/Ghostty/AppState.swift
index f9f4da8b8..ca457f211 100644
--- a/macos/Sources/Ghostty/AppState.swift
+++ b/macos/Sources/Ghostty/AppState.swift
@@ -147,6 +147,7 @@ extension Ghostty {
supports_selection_clipboard: false,
wakeup_cb: { userdata in AppState.wakeup(userdata) },
reload_config_cb: { userdata in AppState.reloadConfig(userdata) },
+ open_config_cb: { userdata in AppState.openConfig(userdata) },
set_title_cb: { userdata, title in AppState.setTitle(userdata, title: title) },
set_mouse_shape_cb: { userdata, shape in AppState.setMouseShape(userdata, shape: shape) },
set_mouse_visibility_cb: { userdata, visible in AppState.setMouseVisibility(userdata, visible: visible) },
@@ -267,6 +268,11 @@ extension Ghostty {
NSApplication.shared.terminate(nil)
}
+ func openConfig() {
+ guard let app = self.app else { return }
+ ghostty_app_open_config(app)
+ }
+
func reloadConfig() {
guard let app = self.app else { return }
ghostty_app_reload_config(app)
@@ -489,6 +495,10 @@ extension Ghostty {
)
}
+ static func openConfig(_ userdata: UnsafeMutableRawPointer?) {
+ ghostty_config_open();
+ }
+
static func reloadConfig(_ userdata: UnsafeMutableRawPointer?) -> ghostty_config_t? {
guard let newConfig = Self.loadConfig() else {
AppDelegate.logger.warning("failed to reload configuration")
diff --git a/macos/Sources/MainMenu.xib b/macos/Sources/MainMenu.xib
index 1b6c88fa3..df7635f9a 100644
--- a/macos/Sources/MainMenu.xib
+++ b/macos/Sources/MainMenu.xib
@@ -28,6 +28,7 @@
+
@@ -58,7 +59,11 @@
-
+