Skip to content

Commit 844f20d

Browse files
authored
Handle setting _NET_WM_STATE (ghostty-org#4936)
As recommended in ghostty-org#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 ghostty-org#4646
2 parents e3ced14 + c963659 commit 844f20d

File tree

8 files changed

+50
-0
lines changed

8 files changed

+50
-0
lines changed

include/ghostty.h

+1
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,7 @@ typedef enum {
565565
GHOSTTY_ACTION_CLOSE_TAB,
566566
GHOSTTY_ACTION_NEW_SPLIT,
567567
GHOSTTY_ACTION_CLOSE_ALL_WINDOWS,
568+
GHOSTTY_ACTION_TOGGLE_MAXIMIZE,
568569
GHOSTTY_ACTION_TOGGLE_FULLSCREEN,
569570
GHOSTTY_ACTION_TOGGLE_TAB_OVERVIEW,
570571
GHOSTTY_ACTION_TOGGLE_WINDOW_DECORATIONS,

src/Surface.zig

+6
Original file line numberDiff line numberDiff line change
@@ -4177,6 +4177,12 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool
41774177
{},
41784178
),
41794179

4180+
.toggle_maximize => try self.rt_app.performAction(
4181+
.{ .surface = self },
4182+
.toggle_maximize,
4183+
{},
4184+
),
4185+
41804186
.toggle_fullscreen => try self.rt_app.performAction(
41814187
.{ .surface = self },
41824188
.toggle_fullscreen,

src/apprt/action.zig

+4
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ pub const Action = union(Key) {
9292
/// Close all open windows.
9393
close_all_windows,
9494

95+
/// Toggle maximized window state.
96+
toggle_maximize,
97+
9598
/// Toggle fullscreen mode.
9699
toggle_fullscreen: Fullscreen,
97100

@@ -231,6 +234,7 @@ pub const Action = union(Key) {
231234
close_tab,
232235
new_split,
233236
close_all_windows,
237+
toggle_maximize,
234238
toggle_fullscreen,
235239
toggle_tab_overview,
236240
toggle_window_decorations,

src/apprt/glfw.zig

+1
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ pub const App = struct {
237237
.color_change,
238238
.pwd,
239239
.config_change,
240+
.toggle_maximize,
240241
=> log.info("unimplemented action={}", .{action}),
241242
}
242243
}

src/apprt/gtk/App.zig

+17
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,7 @@ pub fn performAction(
507507
.app => null,
508508
.surface => |v| v,
509509
}),
510+
.toggle_maximize => self.toggleMaximize(target),
510511
.toggle_fullscreen => self.toggleFullscreen(target, value),
511512

512513
.new_tab => try self.newTab(target),
@@ -709,6 +710,22 @@ fn controlInspector(
709710
surface.controlInspector(mode);
710711
}
711712

713+
fn toggleMaximize(_: *App, target: apprt.Target) void {
714+
switch (target) {
715+
.app => {},
716+
.surface => |v| {
717+
const window = v.rt_surface.container.window() orelse {
718+
log.info(
719+
"toggleMaximize invalid for container={s}",
720+
.{@tagName(v.rt_surface.container)},
721+
);
722+
return;
723+
};
724+
window.toggleMaximize();
725+
},
726+
}
727+
}
728+
712729
fn toggleFullscreen(
713730
_: *App,
714731
target: apprt.Target,

src/apprt/gtk/Window.zig

+12
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,9 @@ pub fn init(self: *Window, app: *App) !void {
266266
c.gtk_popover_set_has_arrow(@ptrCast(@alignCast(self.context_menu)), 0);
267267
c.gtk_widget_set_halign(self.context_menu, c.GTK_ALIGN_START);
268268

269+
// If we want the window to be maximized, we do that here.
270+
if (app.config.maximize) c.gtk_window_maximize(self.window);
271+
269272
// If we are in fullscreen mode, new windows start fullscreen.
270273
if (app.config.fullscreen) c.gtk_window_fullscreen(self.window);
271274

@@ -523,6 +526,15 @@ pub fn toggleTabOverview(self: *Window) void {
523526
}
524527
}
525528

529+
/// Toggle the maximized state for this window.
530+
pub fn toggleMaximize(self: *Window) void {
531+
if (c.gtk_window_is_maximized(self.window) == 0) {
532+
c.gtk_window_maximize(self.window);
533+
} else {
534+
c.gtk_window_unmaximize(self.window);
535+
}
536+
}
537+
526538
/// Toggle fullscreen for this window.
527539
pub fn toggleFullscreen(self: *Window) void {
528540
const is_fullscreen = c.gtk_window_is_fullscreen(self.window);

src/config/Config.zig

+5
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,11 @@ link: RepeatableLink = .{},
764764
/// `link`). If you want to customize URL matching, use `link` and disable this.
765765
@"link-url": bool = true,
766766

767+
/// Whether to start the window in a maximized state. This setting applies
768+
/// to new windows and does not apply to tabs, splits, etc. However, this setting
769+
/// will apply to all new windows, not just the first one.
770+
maximize: bool = false,
771+
767772
/// Start new windows in fullscreen. This setting applies to new windows and
768773
/// does not apply to tabs, splits, etc. However, this setting will apply to all
769774
/// new windows, not just the first one.

src/input/Binding.zig

+4
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,9 @@ pub const Action = union(enum) {
391391
/// This only works for macOS currently.
392392
close_all_windows: void,
393393

394+
/// Toggle maximized window state. This only works on Linux.
395+
toggle_maximize: void,
396+
394397
/// Toggle fullscreen mode of window.
395398
toggle_fullscreen: void,
396399

@@ -737,6 +740,7 @@ pub const Action = union(enum) {
737740
.close_surface,
738741
.close_tab,
739742
.close_window,
743+
.toggle_maximize,
740744
.toggle_fullscreen,
741745
.toggle_window_decorations,
742746
.toggle_secure_input,

0 commit comments

Comments
 (0)