From 8102fddceb7e2c1bea1c8901977f9cab38a25618 Mon Sep 17 00:00:00 2001 From: Adam Wolf Date: Fri, 10 Jan 2025 22:42:41 -0600 Subject: [PATCH 1/2] apprt/gtk: add toggle_maximize keybind and window-maximize config option --- include/ghostty.h | 1 + src/Surface.zig | 16 ++++++++++++++++ src/apprt/action.zig | 4 ++++ src/apprt/glfw.zig | 1 + src/apprt/gtk/App.zig | 17 +++++++++++++++++ src/apprt/gtk/Window.zig | 9 +++++++++ src/config/Config.zig | 7 +++++++ src/input/Binding.zig | 4 ++++ 8 files changed, 59 insertions(+) diff --git a/include/ghostty.h b/include/ghostty.h index 29da8f37b..4275bad7e 100644 --- a/include/ghostty.h +++ b/include/ghostty.h @@ -565,6 +565,7 @@ typedef enum { GHOSTTY_ACTION_CLOSE_TAB, GHOSTTY_ACTION_NEW_SPLIT, GHOSTTY_ACTION_CLOSE_ALL_WINDOWS, + GHOSTTY_ACTION_TOGGLE_MAXIMIZE, GHOSTTY_ACTION_TOGGLE_FULLSCREEN, GHOSTTY_ACTION_TOGGLE_TAB_OVERVIEW, GHOSTTY_ACTION_TOGGLE_WINDOW_DECORATIONS, diff --git a/src/Surface.zig b/src/Surface.zig index ce00d8237..53890e287 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -646,6 +646,16 @@ pub fn init( // an initial size shouldn't stop our terminal from working. log.warn("unable to set initial window size: {s}", .{err}); }; + + if (config.@"window-maximize") { + rt_app.performAction( + .{ .surface = self }, + .toggle_maximize, + {}, + ) catch |err| { + log.warn("unable to maximize window: {s}", .{err}); + }; + } } if (config.title) |title| { @@ -4168,6 +4178,12 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool {}, ), + .toggle_maximize => try self.rt_app.performAction( + .{ .surface = self }, + .toggle_maximize, + {}, + ), + .toggle_fullscreen => try self.rt_app.performAction( .{ .surface = self }, .toggle_fullscreen, diff --git a/src/apprt/action.zig b/src/apprt/action.zig index 25e1cd640..fe2039e52 100644 --- a/src/apprt/action.zig +++ b/src/apprt/action.zig @@ -92,6 +92,9 @@ pub const Action = union(Key) { /// Close all open windows. close_all_windows, + /// Toggle maximized window state. + toggle_maximize, + /// Toggle fullscreen mode. toggle_fullscreen: Fullscreen, @@ -231,6 +234,7 @@ pub const Action = union(Key) { close_tab, new_split, close_all_windows, + toggle_maximize, toggle_fullscreen, toggle_tab_overview, toggle_window_decorations, diff --git a/src/apprt/glfw.zig b/src/apprt/glfw.zig index 8094baeb8..686a70ddb 100644 --- a/src/apprt/glfw.zig +++ b/src/apprt/glfw.zig @@ -237,6 +237,7 @@ pub const App = struct { .color_change, .pwd, .config_change, + .toggle_maximize, => log.info("unimplemented action={}", .{action}), } } diff --git a/src/apprt/gtk/App.zig b/src/apprt/gtk/App.zig index 70fc182e5..f49d275de 100644 --- a/src/apprt/gtk/App.zig +++ b/src/apprt/gtk/App.zig @@ -507,6 +507,7 @@ pub fn performAction( .app => null, .surface => |v| v, }), + .toggle_maximize => self.toggleMaximize(target), .toggle_fullscreen => self.toggleFullscreen(target, value), .new_tab => try self.newTab(target), @@ -709,6 +710,22 @@ fn controlInspector( surface.controlInspector(mode); } +fn toggleMaximize(_: *App, target: apprt.Target) void { + switch (target) { + .app => {}, + .surface => |v| { + const window = v.rt_surface.container.window() orelse { + log.info( + "toggleMaximize invalid for container={s}", + .{@tagName(v.rt_surface.container)}, + ); + return; + }; + window.toggleMaximize(); + }, + } +} + fn toggleFullscreen( _: *App, target: apprt.Target, diff --git a/src/apprt/gtk/Window.zig b/src/apprt/gtk/Window.zig index 8f111cbc9..599a4d184 100644 --- a/src/apprt/gtk/Window.zig +++ b/src/apprt/gtk/Window.zig @@ -522,6 +522,15 @@ pub fn toggleTabOverview(self: *Window) void { } } +/// Toggle the maximized state for this window. +pub fn toggleMaximize(self: *Window) void { + if (c.gtk_window_is_maximized(self.window) == 0) { + c.gtk_window_maximize(self.window); + } else { + c.gtk_window_unmaximize(self.window); + } +} + /// Toggle fullscreen for this window. pub fn toggleFullscreen(self: *Window) void { const is_fullscreen = c.gtk_window_is_fullscreen(self.window); diff --git a/src/config/Config.zig b/src/config/Config.zig index 144796554..310b11623 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -1214,6 +1214,13 @@ keybind: Keybinds = .{}, @"window-position-x": ?i16 = null, @"window-position-y": ?i16 = null, +/// Whether to start the window in a maximized state. This is only related to +/// the X11 window manager's concept of maximization. In other words, this +/// will set the _NET_WM_STATE property to _NET_WM_STATE_MAXIMIZED_VERT and +/// _NET_WM_STATE_MAXIMIZED_HORZ on launch. This will not affect the window +/// size or position. This is only supported on Linux. +@"window-maximize": bool = false, + /// Whether to enable saving and restoring window state. Window state includes /// their position, size, tabs, splits, etc. Some window state requires shell /// integration, such as preserving working directories. See `shell-integration` diff --git a/src/input/Binding.zig b/src/input/Binding.zig index 2fdbc4cba..48725fb13 100644 --- a/src/input/Binding.zig +++ b/src/input/Binding.zig @@ -391,6 +391,9 @@ pub const Action = union(enum) { /// This only works for macOS currently. close_all_windows: void, + /// Toggle maximized window state. This only works on Linux. + toggle_maximize: void, + /// Toggle fullscreen mode of window. toggle_fullscreen: void, @@ -737,6 +740,7 @@ pub const Action = union(enum) { .close_surface, .close_tab, .close_window, + .toggle_maximize, .toggle_fullscreen, .toggle_window_decorations, .toggle_secure_input, From c9636598fc21864d75d4209bdc6feccae3b7cbb5 Mon Sep 17 00:00:00 2001 From: Adam Wolf Date: Fri, 10 Jan 2025 23:24:00 -0600 Subject: [PATCH 2/2] chore: rename config value to maximize and move startup logic to proper location --- src/Surface.zig | 10 ---------- src/apprt/gtk/Window.zig | 3 +++ src/config/Config.zig | 12 +++++------- 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/src/Surface.zig b/src/Surface.zig index 53890e287..9fb103ce3 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -646,16 +646,6 @@ pub fn init( // an initial size shouldn't stop our terminal from working. log.warn("unable to set initial window size: {s}", .{err}); }; - - if (config.@"window-maximize") { - rt_app.performAction( - .{ .surface = self }, - .toggle_maximize, - {}, - ) catch |err| { - log.warn("unable to maximize window: {s}", .{err}); - }; - } } if (config.title) |title| { diff --git a/src/apprt/gtk/Window.zig b/src/apprt/gtk/Window.zig index 599a4d184..42c179462 100644 --- a/src/apprt/gtk/Window.zig +++ b/src/apprt/gtk/Window.zig @@ -265,6 +265,9 @@ pub fn init(self: *Window, app: *App) !void { c.gtk_popover_set_has_arrow(@ptrCast(@alignCast(self.context_menu)), 0); c.gtk_widget_set_halign(self.context_menu, c.GTK_ALIGN_START); + // If we want the window to be maximized, we do that here. + if (app.config.maximize) c.gtk_window_maximize(self.window); + // If we are in fullscreen mode, new windows start fullscreen. if (app.config.fullscreen) c.gtk_window_fullscreen(self.window); diff --git a/src/config/Config.zig b/src/config/Config.zig index 310b11623..6c5b64316 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -764,6 +764,11 @@ link: RepeatableLink = .{}, /// `link`). If you want to customize URL matching, use `link` and disable this. @"link-url": bool = true, +/// Whether to start the window in a maximized state. This setting applies +/// to new windows and does not apply to tabs, splits, etc. However, this setting +/// will apply to all new windows, not just the first one. +maximize: bool = false, + /// Start new windows in fullscreen. This setting applies to new windows and /// does not apply to tabs, splits, etc. However, this setting will apply to all /// new windows, not just the first one. @@ -1214,13 +1219,6 @@ keybind: Keybinds = .{}, @"window-position-x": ?i16 = null, @"window-position-y": ?i16 = null, -/// Whether to start the window in a maximized state. This is only related to -/// the X11 window manager's concept of maximization. In other words, this -/// will set the _NET_WM_STATE property to _NET_WM_STATE_MAXIMIZED_VERT and -/// _NET_WM_STATE_MAXIMIZED_HORZ on launch. This will not affect the window -/// size or position. This is only supported on Linux. -@"window-maximize": bool = false, - /// Whether to enable saving and restoring window state. Window state includes /// their position, size, tabs, splits, etc. Some window state requires shell /// integration, such as preserving working directories. See `shell-integration`