Handle setting _NET_WM_STATE (#4936)

As recommended in
https://github.com/ghostty-org/ghostty/pull/4927#issuecomment-2585003934,
adds a config option `maximize` for starting a window in a maximized
state in terms of window properties. Also adds a `toggle_maximize`
keybind to allow users to manually toggle this feature on and off.

It might make more sense to make this an optional config value so that
we don't toggle the state off if the WM already handles that for us, but
I'll let a reviewer decide.

Closes https://github.com/ghostty-org/ghostty/issues/4646
This commit is contained in:
Mitchell Hashimoto
2025-01-13 13:14:31 -08:00
committed by GitHub
8 changed files with 50 additions and 0 deletions

View File

@ -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,

View File

@ -4177,6 +4177,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,

View File

@ -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,

View File

@ -237,6 +237,7 @@ pub const App = struct {
.color_change,
.pwd,
.config_change,
.toggle_maximize,
=> log.info("unimplemented action={}", .{action}),
}
}

View File

@ -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,

View File

@ -266,6 +266,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);
@ -523,6 +526,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);

View File

@ -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.

View File

@ -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,