diff --git a/include/ghostty.h b/include/ghostty.h
index 29da8f37bd..8fc16f6907 100644
--- a/include/ghostty.h
+++ b/include/ghostty.h
@@ -596,6 +596,7 @@ typedef enum {
GHOSTTY_ACTION_COLOR_CHANGE,
GHOSTTY_ACTION_RELOAD_CONFIG,
GHOSTTY_ACTION_CONFIG_CHANGE,
+ GHOSTTY_ACTION_BRING_ALL_TO_FRONT,
} ghostty_action_tag_e;
typedef union {
diff --git a/macos/Sources/App/macOS/AppDelegate.swift b/macos/Sources/App/macOS/AppDelegate.swift
index 4b11b68aa6..8bc4d6b2ef 100644
--- a/macos/Sources/App/macOS/AppDelegate.swift
+++ b/macos/Sources/App/macOS/AppDelegate.swift
@@ -41,6 +41,7 @@ class AppDelegate: NSObject,
@IBOutlet private var menuToggleVisibility: NSMenuItem?
@IBOutlet private var menuToggleFullScreen: NSMenuItem?
+ @IBOutlet private var menuBringAllToFront: NSMenuItem?
@IBOutlet private var menuZoomSplit: NSMenuItem?
@IBOutlet private var menuPreviousSplit: NSMenuItem?
@IBOutlet private var menuNextSplit: NSMenuItem?
@@ -383,6 +384,7 @@ class AppDelegate: NSObject,
syncMenuShortcut(config, action: "inspector:toggle", menuItem: self.menuTerminalInspector)
syncMenuShortcut(config, action: "toggle_secure_input", menuItem: self.menuSecureInput)
+ syncMenuShortcut(config, action: "bring_all_to_front", menuItem: self.menuBringAllToFront)
// This menu item is NOT synced with the configuration because it disables macOS
// global fullscreen keyboard shortcut. The shortcut in the Ghostty config will continue
@@ -727,6 +729,16 @@ class AppDelegate: NSObject,
self.hiddenWindows.forEach { $0.value?.orderFrontRegardless() }
self.hiddenWindows = []
}
+
+ @IBAction func bringAllToFront(_ sender: Any) {
+ NSApp.activate(ignoringOtherApps: true)
+
+ for window in NSApp.windows.filter({ $0.windowController is BaseTerminalController }) {
+ if window.isVisible {
+ window.makeKeyAndOrderFront(nil)
+ }
+ }
+ }
private struct DerivedConfig {
let initialWindow: Bool
diff --git a/macos/Sources/App/macOS/MainMenu.xib b/macos/Sources/App/macOS/MainMenu.xib
index 4a01d5c62e..99e3fbef6d 100644
--- a/macos/Sources/App/macOS/MainMenu.xib
+++ b/macos/Sources/App/macOS/MainMenu.xib
@@ -14,6 +14,7 @@
+
diff --git a/macos/Sources/Ghostty/Ghostty.App.swift b/macos/Sources/Ghostty/Ghostty.App.swift
index 43c0f245aa..4e4678fc58 100644
--- a/macos/Sources/Ghostty/Ghostty.App.swift
+++ b/macos/Sources/Ghostty/Ghostty.App.swift
@@ -541,6 +541,9 @@ extension Ghostty {
fallthrough
case GHOSTTY_ACTION_QUIT_TIMER:
Ghostty.logger.info("known but unimplemented action action=\(action.tag.rawValue)")
+
+ case GHOSTTY_ACTION_BRING_ALL_TO_FRONT:
+ bringAllToFront(app, target: target)
default:
Ghostty.logger.warning("unknown action action=\(action.tag.rawValue)")
@@ -712,6 +715,15 @@ extension Ghostty {
guard let appDelegate = NSApplication.shared.delegate as? AppDelegate else { return }
appDelegate.toggleVisibility(self)
}
+
+ private static func bringAllToFront(
+ _ app: ghostty_app_t,
+ target: ghostty_target_s
+ ) {
+ guard let appDelegate = NSApplication.shared.delegate as? AppDelegate else { return }
+ appDelegate.bringAllToFront(self)
+ }
+
private static func moveTab(
_ app: ghostty_app_t,
diff --git a/src/App.zig b/src/App.zig
index a6b54db232..36b2c8f2c3 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, {}),
+ .bring_all_to_front => try rt_app.performAction(.app, .bring_all_to_front, {}),
}
}
diff --git a/src/apprt/action.zig b/src/apprt/action.zig
index 25e1cd6407..47cc76cf5f 100644
--- a/src/apprt/action.zig
+++ b/src/apprt/action.zig
@@ -223,6 +223,9 @@ pub const Action = union(Key) {
/// for changes.
config_change: ConfigChange,
+ /// Bring all ghostty windows in front of all other windows.
+ bring_all_to_front,
+
/// Sync with: ghostty_action_tag_e
pub const Key = enum(c_int) {
quit,
@@ -262,6 +265,7 @@ pub const Action = union(Key) {
color_change,
reload_config,
config_change,
+ bring_all_to_front,
};
/// Sync with: ghostty_action_u
diff --git a/src/apprt/glfw.zig b/src/apprt/glfw.zig
index 8094baeb86..f19a056ce9 100644
--- a/src/apprt/glfw.zig
+++ b/src/apprt/glfw.zig
@@ -237,6 +237,7 @@ pub const App = struct {
.color_change,
.pwd,
.config_change,
+ .bring_all_to_front,
=> log.info("unimplemented action={}", .{action}),
}
}
diff --git a/src/apprt/gtk/App.zig b/src/apprt/gtk/App.zig
index 70fc182e5c..d8f6fa0f09 100644
--- a/src/apprt/gtk/App.zig
+++ b/src/apprt/gtk/App.zig
@@ -545,6 +545,7 @@ pub fn performAction(
.render_inspector,
.renderer_health,
.color_change,
+ .bring_all_to_front,
=> log.warn("unimplemented action={}", .{action}),
}
}
diff --git a/src/input/Binding.zig b/src/input/Binding.zig
index 2fdbc4cbaa..34a93434bc 100644
--- a/src/input/Binding.zig
+++ b/src/input/Binding.zig
@@ -466,6 +466,9 @@ pub const Action = union(enum) {
///
crash: CrashThread,
+ /// Bring all ghostty windows in front of all other windows.
+ bring_all_to_front: void,
+
pub const Key = @typeInfo(Action).Union.tag_type.?;
pub const CrashThread = enum {
@@ -702,6 +705,7 @@ pub const Action = union(enum) {
.quit,
.toggle_quick_terminal,
.toggle_visibility,
+ .bring_all_to_front,
=> .app,
// These are app but can be special-cased in a surface context.