Skip to content

Commit c4484cc

Browse files
committed
gtk: apply initial appearance settings before presenting
Fixes ghostty-org#5934 (only on the GTK side), ghostty-org#5960
1 parent 61f41e5 commit c4484cc

File tree

1 file changed

+35
-27
lines changed

1 file changed

+35
-27
lines changed

src/apprt/gtk/Window.zig

+35-27
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ const configpkg = @import("../../config.zig");
1414
const font = @import("../../font/main.zig");
1515
const input = @import("../../input.zig");
1616
const CoreSurface = @import("../../Surface.zig");
17+
const gtk = @import("gtk");
18+
const gobject = @import("gobject");
1719

1820
const App = @import("App.zig");
1921
const Color = configpkg.Config.Color;
@@ -73,6 +75,7 @@ pub const DerivedConfig = struct {
7375
gtk_wide_tabs: bool,
7476
gtk_toolbar_style: configpkg.Config.GtkToolbarStyle,
7577

78+
title: ?[:0]const u8,
7679
maximize: bool,
7780
fullscreen: bool,
7881
window_decoration: configpkg.Config.WindowDecoration,
@@ -88,6 +91,7 @@ pub const DerivedConfig = struct {
8891
.gtk_wide_tabs = config.@"gtk-wide-tabs",
8992
.gtk_toolbar_style = config.@"gtk-toolbar-style",
9093

94+
.title = config.title,
9195
.maximize = config.maximize,
9296
.fullscreen = config.fullscreen,
9397
.window_decoration = config.@"window-decoration",
@@ -130,17 +134,10 @@ pub fn init(self: *Window, app: *App) !void {
130134

131135
self.window = @ptrCast(@alignCast(gtk_widget));
132136

133-
c.gtk_window_set_title(self.window, "Ghostty");
134-
c.gtk_window_set_default_size(self.window, 1000, 600);
135-
c.gtk_widget_add_css_class(gtk_widget, "window");
136-
c.gtk_widget_add_css_class(gtk_widget, "terminal-window");
137-
138137
// GTK4 grabs F10 input by default to focus the menubar icon. We want
139138
// to disable this so that terminal programs can capture F10 (such as htop)
140139
c.gtk_window_set_handle_menubar_accel(self.window, 0);
141140

142-
c.gtk_window_set_icon_name(self.window, build_config.bundle_id);
143-
144141
// Create our box which will hold our widgets in the main content area.
145142
const box = c.gtk_box_new(c.GTK_ORIENTATION_VERTICAL, 0);
146143

@@ -353,11 +350,7 @@ pub fn init(self: *Window, app: *App) !void {
353350
if (!self.config.gtk_wide_tabs) c.adw_tab_bar_set_expand_tabs(tab_bar, 0);
354351
}
355352

356-
// If we want the window to be maximized, we do that here.
357-
if (self.config.maximize) c.gtk_window_maximize(self.window);
358-
359-
// If we are in fullscreen mode, new windows start fullscreen.
360-
if (self.config.fullscreen) c.gtk_window_fullscreen(self.window);
353+
try self.initAppearance();
361354

362355
// Show the window
363356
c.gtk_widget_show(gtk_widget);
@@ -380,23 +373,44 @@ pub fn updateConfig(
380373
try self.syncAppearance();
381374
}
382375

376+
/// Initializes the appearance of the window.
377+
///
378+
/// Not all appearance changes *should* be applied when a config option is
379+
/// reloaded (for instance, the maximize and fullscreen settings should only
380+
/// apply to new windows), so we apply them here.
381+
pub fn initAppearance(self: *Window) !void {
382+
const window = gobject.ext.cast(gtk.Window, self.window).?;
383+
384+
window.setTitle(self.config.title orelse "Ghostty");
385+
window.setDefaultSize(1000, 600);
386+
window.as(gtk.Widget).addCssClass("window");
387+
window.as(gtk.Widget).addCssClass("terminal-window");
388+
window.setIconName(build_config.bundle_id);
389+
390+
if (self.config.maximize) window.maximize();
391+
if (self.config.fullscreen) window.fullscreen();
392+
393+
try self.syncAppearance();
394+
}
395+
383396
/// Updates appearance based on config settings. Will be called once upon window
384397
/// realization, every time the config is reloaded, and every time a window state
385398
/// is toggled (un-/maximized, un-/fullscreened, window decorations toggled, etc.)
386399
///
387400
/// TODO: Many of the initial style settings in `create` could possibly be made
388401
/// reactive by moving them here.
389402
pub fn syncAppearance(self: *Window) !void {
403+
const window = gobject.ext.cast(gtk.Window, self.window).?;
390404
const csd_enabled = self.winproto.clientSideDecorationEnabled();
391-
c.gtk_window_set_decorated(self.window, @intFromBool(csd_enabled));
405+
window.setDecorated(@intFromBool(csd_enabled));
392406

393407
// Fix any artifacting that may occur in window corners. The .ssd CSS
394408
// class is defined in the GtkWindow documentation:
395409
// https://docs.gtk.org/gtk4/class.Window.html#css-nodes. A definition
396410
// for .ssd is provided by GTK and Adwaita.
397-
toggleCssClass(@ptrCast(self.window), "csd", csd_enabled);
398-
toggleCssClass(@ptrCast(self.window), "ssd", !csd_enabled);
399-
toggleCssClass(@ptrCast(self.window), "no-border-radius", !csd_enabled);
411+
toggleCssClass(window, "csd", csd_enabled);
412+
toggleCssClass(window, "ssd", !csd_enabled);
413+
toggleCssClass(window, "no-border-radius", !csd_enabled);
400414

401415
self.headerbar.setVisible(visible: {
402416
// Never display the header bar when CSDs are disabled.
@@ -414,7 +428,7 @@ pub fn syncAppearance(self: *Window) !void {
414428
});
415429

416430
toggleCssClass(
417-
@ptrCast(self.window),
431+
window,
418432
"background",
419433
self.config.background_opacity >= 1,
420434
);
@@ -423,7 +437,7 @@ pub fn syncAppearance(self: *Window) !void {
423437
// GTK version is before 4.16. The conditional is because above 4.16
424438
// we use GTK CSS color variables.
425439
toggleCssClass(
426-
@ptrCast(self.window),
440+
window,
427441
"window-theme-ghostty",
428442
!version.atLeast(4, 16, 0) and self.config.window_theme == .ghostty,
429443
);
@@ -451,23 +465,17 @@ pub fn syncAppearance(self: *Window) !void {
451465
self.winproto.syncAppearance() catch |err| {
452466
log.warn("failed to sync winproto appearance error={}", .{err});
453467
};
454-
455-
toggleCssClass(
456-
@ptrCast(self.window),
457-
"background",
458-
self.config.background_opacity >= 1,
459-
);
460468
}
461469

462470
fn toggleCssClass(
463-
widget: *c.GtkWidget,
471+
widget: anytype,
464472
class: [:0]const u8,
465473
v: bool,
466474
) void {
467475
if (v) {
468-
c.gtk_widget_add_css_class(widget, class);
476+
widget.as(gtk.Widget).addCssClass(class);
469477
} else {
470-
c.gtk_widget_remove_css_class(widget, class);
478+
widget.as(gtk.Widget).removeCssClass(class);
471479
}
472480
}
473481

0 commit comments

Comments
 (0)