Merge pull request #1120 from mitchellh/macos-close-all

macos: close all windows
This commit is contained in:
Mitchell Hashimoto
2023-12-17 20:56:20 -08:00
committed by GitHub
7 changed files with 83 additions and 3 deletions

View File

@ -21,6 +21,7 @@ class AppDelegate: NSObject, ObservableObject, NSApplicationDelegate, UNUserNoti
@IBOutlet private var menuSplitVertical: NSMenuItem?
@IBOutlet private var menuClose: NSMenuItem?
@IBOutlet private var menuCloseWindow: NSMenuItem?
@IBOutlet private var menuCloseAllWindows: NSMenuItem?
@IBOutlet private var menuCopy: NSMenuItem?
@IBOutlet private var menuPaste: NSMenuItem?
@ -218,6 +219,7 @@ class AppDelegate: NSObject, ObservableObject, NSApplicationDelegate, UNUserNoti
syncMenuShortcut(action: "new_tab", menuItem: self.menuNewTab)
syncMenuShortcut(action: "close_surface", menuItem: self.menuClose)
syncMenuShortcut(action: "close_window", menuItem: self.menuCloseWindow)
syncMenuShortcut(action: "close_all_windows", menuItem: self.menuCloseAllWindows)
syncMenuShortcut(action: "new_split:right", menuItem: self.menuSplitHorizontal)
syncMenuShortcut(action: "new_split:down", menuItem: self.menuSplitVertical)
@ -360,6 +362,11 @@ class AppDelegate: NSObject, ObservableObject, NSApplicationDelegate, UNUserNoti
NSApp.activate(ignoringOtherApps: true)
}
@IBAction func closeAllWindows(_ sender: Any?) {
terminalManager.closeAllWindows()
AboutController.shared.hide()
}
@IBAction func showAbout(_ sender: Any?) {
AboutController.shared.show()
}

View File

@ -16,8 +16,11 @@ class AboutController: NSWindowController, NSWindowDelegate {
// MARK: - Functions
func show() {
guard let window = window else { return }
window.makeKeyAndOrderFront(nil)
window?.makeKeyAndOrderFront(nil)
}
func hide() {
window?.close()
}
//MARK: - First Responder

View File

@ -189,6 +189,52 @@ class TerminalManager {
}
}
/// Close all windows, asking for confirmation if necessary.
func closeAllWindows() {
var needsConfirm: Bool = false
for w in self.windows {
if (w.controller.surfaceTree?.needsConfirmQuit() ?? false) {
needsConfirm = true
break
}
}
if (!needsConfirm) {
for w in self.windows {
w.controller.close()
}
return
}
// If we don't have a main window, we just close all windows because
// we have no window to show the modal on top of. I'm sure there's a way
// to do an app-level alert but I don't know how and this case should never
// really happen.
guard let alertWindow = mainWindow?.controller.window else {
for w in self.windows {
w.controller.close()
}
return
}
// If we need confirmation by any, show one confirmation for all windows
let alert = NSAlert()
alert.messageText = "Close All Windows?"
alert.informativeText = "All terminal sessions will be terminated."
alert.addButton(withTitle: "Close All Windows")
alert.addButton(withTitle: "Cancel")
alert.alertStyle = .warning
alert.beginSheetModal(for: alertWindow, completionHandler: { response in
if (response == .alertFirstButtonReturn) {
for w in self.windows {
w.controller.close()
}
}
})
}
/// Relabels all the tabs with the proper keyboard shortcut.
func relabelAllTabs() {
for w in windows {

View File

@ -15,6 +15,7 @@
<customObject id="bbz-4X-AYv" userLabel="AppDelegate" customClass="AppDelegate" customModule="Ghostty" customModuleProvider="target">
<connections>
<outlet property="menuClose" destination="DVo-aG-piG" id="R3t-0C-aSU"/>
<outlet property="menuCloseAllWindows" destination="yKr-Vi-Yqw" id="Zet-Ir-zbm"/>
<outlet property="menuCloseWindow" destination="W5w-UZ-crk" id="6ff-BT-ENV"/>
<outlet property="menuCopy" destination="Jqf-pv-Zcu" id="bKd-1C-oy9"/>
<outlet property="menuDecreaseFontSize" destination="kzb-SZ-dOA" id="Y1B-Vh-6Z2"/>
@ -134,6 +135,12 @@
<action selector="closeWindow:" target="-1" id="ovs-xn-3ju"/>
</connections>
</menuItem>
<menuItem title="Close All Windows" id="yKr-Vi-Yqw">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="closeAllWindows:" target="-1" id="hrz-eb-l5t"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>

View File

@ -2885,6 +2885,12 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool
.close_window => try self.app.closeSurface(self),
.close_all_windows => {
if (@hasDecl(apprt.Surface, "closeAllWindows")) {
self.rt_surface.closeAllWindows();
} else log.warn("runtime doesn't implement closeAllWindows", .{});
},
.quit => try self.app.setQuit(),
}

View File

@ -1183,6 +1183,11 @@ pub fn default(alloc_gpa: Allocator) Allocator.Error!Config {
.{ .key = .w, .mods = .{ .super = true, .shift = true } },
.{ .close_window = {} },
);
try result.keybind.set.put(
alloc,
.{ .key = .w, .mods = .{ .super = true, .shift = true, .alt = true } },
.{ .close_all_windows = {} },
);
try result.keybind.set.put(
alloc,
.{ .key = .t, .mods = .{ .super = true } },

View File

@ -221,12 +221,18 @@ pub const Action = union(enum) {
reload_config: void,
/// Close the current "surface", whether that is a window, tab, split,
/// etc. This only closes ONE surface.
/// etc. This only closes ONE surface. This will trigger close confirmation
/// as configured.
close_surface: void,
/// Close the window, regardless of how many tabs or splits there may be.
/// This will trigger close confirmation as configured.
close_window: void,
/// Close all windows. This will trigger close confirmation as configured.
/// This only works for macOS currently.
close_all_windows: void,
/// Toggle fullscreen mode of window.
toggle_fullscreen: void,