Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
jcollie committed Jan 24, 2025
1 parent 69dcea5 commit e9bc6bb
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 17 deletions.
23 changes: 23 additions & 0 deletions src/apprt/gtk/Surface.zig
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,8 @@ im_len: u7 = 0,
/// details on what this is.
cgroup_path: ?[]const u8 = null,

cfg: DerivedConfig = undefined,

/// Configuration used for initializing the surface. We have to copy some
/// data since initialization is delayed with GTK (on realize).
pub const InitConfig = struct {
Expand Down Expand Up @@ -408,6 +410,25 @@ pub const InitConfig = struct {
}
};

// copy of configurations necessary to for the operation of the
// surface.

pub const DerivedConfig = struct {
pub fn init(self: *DerivedConfig, config: *const configpkg.Config) void {
_ = self;
_ = config;
}

pub fn reconfigure(self: *DerivedConfig, config: *const configpkg.Config) void {
_ = self;
_ = config;
}

pub fn deinit(self: *DerivedConfig) void {
_ = self;
}
};

pub fn create(alloc: Allocator, app: *App, opts: Options) !*Surface {
var surface = try alloc.create(Surface);
errdefer alloc.destroy(surface);
Expand All @@ -416,6 +437,8 @@ pub fn create(alloc: Allocator, app: *App, opts: Options) !*Surface {
}

pub fn init(self: *Surface, app: *App, opts: Options) !void {
self.cfg.init(&app.config);

const gl_area = c.gtk_gl_area_new();

// Create an overlay so we can layer the GL area with other widgets.
Expand Down
70 changes: 53 additions & 17 deletions src/apprt/gtk/Window.zig
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ const log = std.log.scoped(.gtk);

app: *App,

cfg: DerivedConfig,

/// Our window
window: *c.GtkWindow,

Expand Down Expand Up @@ -73,10 +75,51 @@ pub fn create(alloc: Allocator, app: *App) !*Window {
return window;
}

// copy of configurations necessary to for the operation of the
// surface.

pub const DerivedConfig = struct {
// adwaita_enabled should not be refreshed
adwaita_enabled: bool,
background_opacity: f64,
gtk_titlebar: bool,
window_theme: configpkg.WindowTheme,

pub fn init(self: *DerivedConfig, config: *const configpkg.Config) void {
self.* = .{
.adwaita_enabled = adwaita.enabled(config),
.background_opacity = config.@"background-opacity",
.gtk_titlebar = config.@"gtk-titlebar",
.window_theme = config.@"window-theme",
};
}

pub fn updateConfig(self: *DerivedConfig, config: *const configpkg.Config) void {
const window: *Window = @fieldParentPtr("cfg", self);

self.background_opacity = config.@"background-opacity";
self.gtk_titlebar = config.@"gtk-titlebar";
self.window_theme = config.@"window-theme";

window.winproto.updateConfigEvent(config) catch |err| {
// We want to continue attempting to make the other config
// changes necessary so we just log the error and continue.
log.warn("failed to update window protocol config error={}", .{err});
};

window.syncAppearance();
}

pub fn deinit(self: *DerivedConfig) void {
_ = self;
}
};

pub fn init(self: *Window, app: *App) !void {
// Set up our own state
self.* = .{
.app = app,
.cfg = undefined,
.window = undefined,
.headerbar = undefined,
.tab_overview = null,
Expand All @@ -86,9 +129,11 @@ pub fn init(self: *Window, app: *App) !void {
.winproto = .none,
};

self.cfg.init(&app.config);

// Create the window
const window: *c.GtkWidget = window: {
if ((comptime adwaita.versionAtLeast(0, 0, 0)) and adwaita.enabled(&self.app.config)) {
if ((comptime adwaita.versionAtLeast(0, 0, 0)) and self.cfg.adwaita_enabled) {
const window = c.adw_application_window_new(app.app);
c.gtk_widget_add_css_class(@ptrCast(window), "adw");
break :window window;
Expand Down Expand Up @@ -116,7 +161,7 @@ pub fn init(self: *Window, app: *App) !void {
// Apply class to color headerbar if window-theme is set to `ghostty` and
// GTK version is before 4.16. The conditional is because above 4.16
// we use GTK CSS color variables.
if (!version.atLeast(4, 16, 0) and app.config.@"window-theme" == .ghostty) {
if (!version.atLeast(4, 16, 0) and self.cfg.window_theme == .ghostty) {
c.gtk_widget_add_css_class(@ptrCast(gtk_window), "window-theme-ghostty");
}

Expand Down Expand Up @@ -374,44 +419,37 @@ pub fn updateConfig(
self: *Window,
config: *const configpkg.Config,
) !void {
self.winproto.updateConfigEvent(config) catch |err| {
// We want to continue attempting to make the other config
// changes necessary so we just log the error and continue.
log.warn("failed to update window protocol config error={}", .{err});
};

// We always resync our appearance whenever the config changes.
try self.syncAppearance(config);
self.cfg.updateConfig(config);
}

/// Updates appearance based on config settings. Will be called once upon window
/// realization, and every time the config is reloaded.
///
/// TODO: Many of the initial style settings in `create` could possibly be made
/// reactive by moving them here.
pub fn syncAppearance(self: *Window, config: *const configpkg.Config) !void {
pub fn syncAppearance(self: *Window) void {
self.winproto.syncAppearance() catch |err| {
log.warn("failed to sync winproto appearance error={}", .{err});
};

toggleCssClass(
@ptrCast(self.window),
"background",
config.@"background-opacity" >= 1,
self.cfg.background_opacity >= 1,
);

// If we are disabling CSDs then disable them right away.
const csd_enabled = self.winproto.clientSideDecorationEnabled();
c.gtk_window_set_decorated(self.window, @intFromBool(csd_enabled));

// If we are not decorated then we hide the titlebar.
self.headerbar.setVisible(config.@"gtk-titlebar" and csd_enabled);
self.headerbar.setVisible(self.cfg.gtk_titlebar and csd_enabled);

// Disable the title buttons (close, maximize, minimize, ...)
// *inside* the tab overview if CSDs are disabled.
// We do spare the search button, though.
if ((comptime adwaita.versionAtLeast(1, 4, 0)) and
adwaita.enabled(&self.app.config))
self.cfg.adwaita_enabled)
{
if (self.tab_overview) |tab_overview| {
c.adw_tab_overview_set_show_start_title_buttons(
Expand Down Expand Up @@ -626,9 +664,7 @@ fn gtkRealize(v: *c.GtkWindow, ud: ?*anyopaque) callconv(.C) bool {
}

// When we are realized we always setup our appearance
self.syncAppearance(&self.app.config) catch |err| {
log.err("failed to initialize appearance={}", .{err});
};
self.syncAppearance();

return true;
}
Expand Down
1 change: 1 addition & 0 deletions src/config.zig
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub const RepeatableString = Config.RepeatableString;
pub const RepeatablePath = Config.RepeatablePath;
pub const ShellIntegrationFeatures = Config.ShellIntegrationFeatures;
pub const WindowPaddingColor = Config.WindowPaddingColor;
pub const WindowTheme = Config.WindowTheme;

// Alternate APIs
pub const CAPI = @import("config/CAPI.zig");
Expand Down

0 comments on commit e9bc6bb

Please sign in to comment.