Skip to content

Commit

Permalink
Handle setting _NET_WM_STATE (#4936)
Browse files Browse the repository at this point in the history
As recommended in
#4927 (comment),
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 #4646
  • Loading branch information
mitchellh authored Jan 13, 2025
2 parents e3ced14 + c963659 commit 844f20d
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/ghostty.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 6 additions & 0 deletions src/Surface.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 4 additions & 0 deletions src/apprt/action.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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,

Expand Down Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions src/apprt/glfw.zig
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ pub const App = struct {
.color_change,
.pwd,
.config_change,
.toggle_maximize,
=> log.info("unimplemented action={}", .{action}),
}
}
Expand Down
17 changes: 17 additions & 0 deletions src/apprt/gtk/App.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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,
Expand Down
12 changes: 12 additions & 0 deletions src/apprt/gtk/Window.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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);
Expand Down
5 changes: 5 additions & 0 deletions src/config/Config.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 4 additions & 0 deletions src/input/Binding.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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,

Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 844f20d

Please sign in to comment.