mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
Implement loading custom css in the GTK app
This commit is contained in:
@ -81,6 +81,9 @@ transient_cgroup_base: ?[]const u8 = null,
|
||||
/// CSS Provider for any styles based on ghostty configuration values
|
||||
css_provider: *c.GtkCssProvider,
|
||||
|
||||
/// Providers for loading custom stylesheets defined by user
|
||||
custom_css_providers: std.ArrayList(*c.GtkCssProvider),
|
||||
|
||||
/// The timer used to quit the application after the last window is closed.
|
||||
quit_timer: union(enum) {
|
||||
off: void,
|
||||
@ -425,6 +428,7 @@ pub fn init(core_app: *CoreApp, opts: Options) !App {
|
||||
// our "activate" call above will open a window.
|
||||
.running = c.g_application_get_is_remote(gapp) == 0,
|
||||
.css_provider = css_provider,
|
||||
.custom_css_providers = std.ArrayList(*c.GtkCssProvider).init(core_app.alloc),
|
||||
};
|
||||
}
|
||||
|
||||
@ -441,6 +445,11 @@ pub fn terminate(self: *App) void {
|
||||
if (self.context_menu) |context_menu| c.g_object_unref(context_menu);
|
||||
if (self.transient_cgroup_base) |path| self.core_app.alloc.free(path);
|
||||
|
||||
for (self.custom_css_providers.items) |provider| {
|
||||
c.g_object_unref(provider);
|
||||
}
|
||||
self.custom_css_providers.deinit();
|
||||
|
||||
self.config.deinit();
|
||||
}
|
||||
|
||||
@ -892,7 +901,7 @@ fn syncConfigChanges(self: *App) !void {
|
||||
try self.updateConfigErrors();
|
||||
try self.syncActionAccelerators();
|
||||
|
||||
// Load our runtime CSS. If this fails then our window is just stuck
|
||||
// Load our runtime and custom CSS. If this fails then our window is just stuck
|
||||
// with the old CSS but we don't want to fail the entire sync operation.
|
||||
self.loadRuntimeCss() catch |err| switch (err) {
|
||||
error.OutOfMemory => log.warn(
|
||||
@ -900,6 +909,12 @@ fn syncConfigChanges(self: *App) !void {
|
||||
.{},
|
||||
),
|
||||
};
|
||||
self.loadCustomCss() catch |err| switch (err) {
|
||||
error.OutOfMemory => log.warn(
|
||||
"out of memory loading custom CSS, no custom CSS applied",
|
||||
.{},
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
/// This should be called whenever the configuration changes to update
|
||||
@ -1040,6 +1055,44 @@ fn loadRuntimeCss(
|
||||
);
|
||||
}
|
||||
|
||||
fn loadCustomCss(self: *App) Allocator.Error!void {
|
||||
const display = c.gdk_display_get_default();
|
||||
|
||||
// unload the previously loaded style providers
|
||||
for (self.custom_css_providers.items) |provider| {
|
||||
c.gtk_style_context_remove_provider_for_display(
|
||||
display,
|
||||
@ptrCast(provider),
|
||||
);
|
||||
c.g_object_unref(provider);
|
||||
}
|
||||
self.custom_css_providers.clearRetainingCapacity();
|
||||
|
||||
for (self.config.@"gtk-custom-css".value.items) |p| {
|
||||
const path, const optional = switch (p) {
|
||||
.optional => |path| .{ path, true },
|
||||
.required => |path| .{ path, false },
|
||||
};
|
||||
std.fs.accessAbsolute(path, .{}) catch |err| {
|
||||
if (err != error.FileNotFound or !optional) {
|
||||
log.err("error opening gtk-custom-css file {s}: {}", .{ path, err });
|
||||
}
|
||||
continue;
|
||||
};
|
||||
|
||||
const provider = c.gtk_css_provider_new();
|
||||
|
||||
c.gtk_style_context_add_provider_for_display(
|
||||
display,
|
||||
@ptrCast(provider),
|
||||
c.GTK_STYLE_PROVIDER_PRIORITY_USER,
|
||||
);
|
||||
c.gtk_css_provider_load_from_path(provider, path);
|
||||
|
||||
try self.custom_css_providers.append(provider);
|
||||
}
|
||||
}
|
||||
|
||||
/// Called by CoreApp to wake up the event loop.
|
||||
pub fn wakeup(self: App) void {
|
||||
_ = self;
|
||||
|
@ -1925,6 +1925,14 @@ keybind: Keybinds = .{},
|
||||
/// Adwaita support.
|
||||
@"gtk-adwaita": bool = true,
|
||||
|
||||
/// Custom CSS files to be loaded.
|
||||
///
|
||||
/// This configuration can be repeated multiple times to load multiple files.
|
||||
/// Prepend a ? character to the file path to suppress errors if the file does
|
||||
/// not exist. If you want to include a file that begins with a literal ?
|
||||
/// character, surround the file path in double quotes (").
|
||||
@"gtk-custom-css": RepeatablePath = .{},
|
||||
|
||||
/// If `true` (default), applications running in the terminal can show desktop
|
||||
/// notifications using certain escape sequences such as OSC 9 or OSC 777.
|
||||
@"desktop-notifications": bool = true,
|
||||
|
Reference in New Issue
Block a user