mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +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 for any styles based on ghostty configuration values
|
||||||
css_provider: *c.GtkCssProvider,
|
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.
|
/// The timer used to quit the application after the last window is closed.
|
||||||
quit_timer: union(enum) {
|
quit_timer: union(enum) {
|
||||||
off: void,
|
off: void,
|
||||||
@ -425,6 +428,7 @@ pub fn init(core_app: *CoreApp, opts: Options) !App {
|
|||||||
// our "activate" call above will open a window.
|
// our "activate" call above will open a window.
|
||||||
.running = c.g_application_get_is_remote(gapp) == 0,
|
.running = c.g_application_get_is_remote(gapp) == 0,
|
||||||
.css_provider = css_provider,
|
.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.context_menu) |context_menu| c.g_object_unref(context_menu);
|
||||||
if (self.transient_cgroup_base) |path| self.core_app.alloc.free(path);
|
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();
|
self.config.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -892,7 +901,7 @@ fn syncConfigChanges(self: *App) !void {
|
|||||||
try self.updateConfigErrors();
|
try self.updateConfigErrors();
|
||||||
try self.syncActionAccelerators();
|
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.
|
// with the old CSS but we don't want to fail the entire sync operation.
|
||||||
self.loadRuntimeCss() catch |err| switch (err) {
|
self.loadRuntimeCss() catch |err| switch (err) {
|
||||||
error.OutOfMemory => log.warn(
|
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
|
/// 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.
|
/// Called by CoreApp to wake up the event loop.
|
||||||
pub fn wakeup(self: App) void {
|
pub fn wakeup(self: App) void {
|
||||||
_ = self;
|
_ = self;
|
||||||
|
@ -1925,6 +1925,14 @@ keybind: Keybinds = .{},
|
|||||||
/// Adwaita support.
|
/// Adwaita support.
|
||||||
@"gtk-adwaita": bool = true,
|
@"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
|
/// If `true` (default), applications running in the terminal can show desktop
|
||||||
/// notifications using certain escape sequences such as OSC 9 or OSC 777.
|
/// notifications using certain escape sequences such as OSC 9 or OSC 777.
|
||||||
@"desktop-notifications": bool = true,
|
@"desktop-notifications": bool = true,
|
||||||
|
Reference in New Issue
Block a user