From 9ed76729abfa0fd57feb9b330559a4d3dbeabd39 Mon Sep 17 00:00:00 2001 From: Leah Amelia Chen Date: Thu, 13 Feb 2025 20:12:12 +0100 Subject: [PATCH] gtk: add separate close_window apprt action For *some* reason we have a binding for close_window but it merely closes the surface and not the entire window. That is not only misleading but also just wrong. Now we make a separate apprt action for close_window that would make it show a close confirmation prompt identical to as if the user had clicked the (X) button on the window titlebar. --- include/ghostty.h | 1 + src/Surface.zig | 6 +++++- src/apprt/action.zig | 4 ++++ src/apprt/glfw.zig | 1 + src/apprt/gtk/App.zig | 21 +++++++++++++++++---- 5 files changed, 28 insertions(+), 5 deletions(-) diff --git a/include/ghostty.h b/include/ghostty.h index 29c779f2c..4fc180a1a 100644 --- a/include/ghostty.h +++ b/include/ghostty.h @@ -600,6 +600,7 @@ typedef enum { GHOSTTY_ACTION_COLOR_CHANGE, GHOSTTY_ACTION_RELOAD_CONFIG, GHOSTTY_ACTION_CONFIG_CHANGE, + GHOSTTY_ACTION_CLOSE_WINDOW, } ghostty_action_tag_e; typedef union { diff --git a/src/Surface.zig b/src/Surface.zig index f75017053..10e8428e1 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -4292,7 +4292,11 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool .close_surface => self.close(), - .close_window => self.app.closeSurface(self), + .close_window => return try self.rt_app.performAction( + .{ .surface = self }, + .close_window, + {}, + ), .crash => |location| switch (location) { .main => @panic("crash binding action, crashing intentionally"), diff --git a/src/apprt/action.zig b/src/apprt/action.zig index 62410a5a1..149118aa6 100644 --- a/src/apprt/action.zig +++ b/src/apprt/action.zig @@ -241,6 +241,9 @@ pub const Action = union(Key) { /// for changes. config_change: ConfigChange, + /// Closes the currently focused window. + close_window, + /// Sync with: ghostty_action_tag_e pub const Key = enum(c_int) { quit, @@ -283,6 +286,7 @@ pub const Action = union(Key) { color_change, reload_config, config_change, + close_window, }; /// Sync with: ghostty_action_u diff --git a/src/apprt/glfw.zig b/src/apprt/glfw.zig index bc4d32bd7..935ca85ac 100644 --- a/src/apprt/glfw.zig +++ b/src/apprt/glfw.zig @@ -219,6 +219,7 @@ pub const App = struct { .toggle_split_zoom, .present_terminal, .close_all_windows, + .close_window, .close_tab, .toggle_tab_overview, .toggle_window_decorations, diff --git a/src/apprt/gtk/App.zig b/src/apprt/gtk/App.zig index ba456c7a6..1636ac2f3 100644 --- a/src/apprt/gtk/App.zig +++ b/src/apprt/gtk/App.zig @@ -481,10 +481,11 @@ pub fn performAction( .app => null, .surface => |v| v, }), + .close_window => return try self.closeWindow(target), .toggle_maximize => self.toggleMaximize(target), .toggle_fullscreen => self.toggleFullscreen(target, value), .new_tab => try self.newTab(target), - .close_tab => try self.closeTab(target), + .close_tab => return try self.closeTab(target), .goto_tab => return self.gotoTab(target, value), .move_tab => self.moveTab(target, value), .new_split => try self.newSplit(target, value), @@ -549,19 +550,20 @@ fn newTab(_: *App, target: apprt.Target) !void { } } -fn closeTab(_: *App, target: apprt.Target) !void { +fn closeTab(_: *App, target: apprt.Target) !bool { switch (target) { - .app => {}, + .app => return false, .surface => |v| { const tab = v.rt_surface.container.tab() orelse { log.info( "close_tab invalid for container={s}", .{@tagName(v.rt_surface.container)}, ); - return; + return false; }; tab.closeWithConfirmation(); + return true; }, } } @@ -1426,6 +1428,17 @@ fn setSecureInput(_: *App, target: apprt.Target, value: apprt.action.SecureInput } } +fn closeWindow(_: *App, target: apprt.action.Target) !bool { + switch (target) { + .app => return false, + .surface => |v| { + const window = v.rt_surface.container.window() orelse return false; + window.closeWithConfirmation(); + return true; + }, + } +} + fn quit(self: *App) void { // If we're already not running, do nothing. if (!self.running) return;