Merge pull request #2234 from jcollie/gtk-css-no-libadwaita

gtk: load css when libadwaita is not being used
This commit is contained in:
Mitchell Hashimoto
2024-10-09 09:37:30 -07:00
committed by GitHub
4 changed files with 87 additions and 48 deletions

View File

@ -1273,13 +1273,7 @@ fn addDeps(
const gresource = @import("src/apprt/gtk/gresource.zig"); const gresource = @import("src/apprt/gtk/gresource.zig");
const wf = b.addWriteFiles(); const wf = b.addWriteFiles();
const gresource_xml = wf.add( const gresource_xml = wf.add("gresource.xml", gresource.gresource_xml);
"gresource.xml",
if (config.libadwaita)
gresource.gresource_xml_libadwaita
else
gresource.gresource_xml_gtk,
);
const generate_resources_c = b.addSystemCommand(&.{ const generate_resources_c = b.addSystemCommand(&.{
"glib-compile-resources", "glib-compile-resources",
@ -1290,7 +1284,7 @@ fn addDeps(
}); });
const ghostty_resources_c = generate_resources_c.addOutputFileArg("ghostty_resources.c"); const ghostty_resources_c = generate_resources_c.addOutputFileArg("ghostty_resources.c");
generate_resources_c.addFileArg(gresource_xml); generate_resources_c.addFileArg(gresource_xml);
generate_resources_c.extra_file_dependencies = if (config.libadwaita) &gresource.dependencies_libadwaita else &gresource.dependencies_gtk; generate_resources_c.extra_file_dependencies = &gresource.dependencies;
step.addCSourceFile(.{ .file = ghostty_resources_c, .flags = &.{} }); step.addCSourceFile(.{ .file = ghostty_resources_c, .flags = &.{} });
const generate_resources_h = b.addSystemCommand(&.{ const generate_resources_h = b.addSystemCommand(&.{
@ -1302,7 +1296,7 @@ fn addDeps(
}); });
const ghostty_resources_h = generate_resources_h.addOutputFileArg("ghostty_resources.h"); const ghostty_resources_h = generate_resources_h.addOutputFileArg("ghostty_resources.h");
generate_resources_h.addFileArg(gresource_xml); generate_resources_h.addFileArg(gresource_xml);
generate_resources_h.extra_file_dependencies = if (config.libadwaita) &gresource.dependencies_libadwaita else &gresource.dependencies_gtk; generate_resources_h.extra_file_dependencies = &gresource.dependencies;
step.addIncludePath(ghostty_resources_h.dirname()); step.addIncludePath(ghostty_resources_h.dirname());
} }
}, },

View File

@ -128,6 +128,9 @@ pub fn init(core_app: *CoreApp, opts: Options) !App {
} }
} }
c.gtk_init();
const display = c.gdk_display_get_default();
// If we're using libadwaita, log the version // If we're using libadwaita, log the version
if (adwaita.enabled(&config)) { if (adwaita.enabled(&config)) {
log.info("libadwaita version build={s} runtime={}.{}.{}", .{ log.info("libadwaita version build={s} runtime={}.{}.{}", .{
@ -183,6 +186,51 @@ pub fn init(core_app: *CoreApp, opts: Options) !App {
if ((comptime !adwaita.versionAtLeast(0, 0, 0)) or if ((comptime !adwaita.versionAtLeast(0, 0, 0)) or
!adwaita.enabled(&config)) !adwaita.enabled(&config))
{ {
{
const provider = c.gtk_css_provider_new();
defer c.g_object_unref(provider);
switch (config.@"window-theme") {
.system, .light => {},
.dark => {
c.gtk_css_provider_load_from_resource(
provider,
"/com/mitchellh/ghostty/style-dark.css",
);
c.gtk_style_context_add_provider_for_display(
display,
@ptrCast(provider),
c.GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + 2,
);
},
.auto, .ghostty => {
const lum = config.background.toTerminalRGB().perceivedLuminance();
if (lum <= 0.5) {
c.gtk_css_provider_load_from_resource(
provider,
"/com/mitchellh/ghostty/style-dark.css",
);
c.gtk_style_context_add_provider_for_display(
display,
@ptrCast(provider),
c.GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + 2,
);
}
},
}
}
{
const provider = c.gtk_css_provider_new();
defer c.g_object_unref(provider);
c.gtk_css_provider_load_from_resource(provider, "/com/mitchellh/ghostty/style.css");
c.gtk_style_context_add_provider_for_display(
display,
@ptrCast(provider),
c.GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + 1,
);
}
break :app @as(?*c.GtkApplication, @ptrCast(c.gtk_application_new( break :app @as(?*c.GtkApplication, @ptrCast(c.gtk_application_new(
app_id.ptr, app_id.ptr,
app_flags, app_flags,
@ -277,7 +325,6 @@ pub fn init(core_app: *CoreApp, opts: Options) !App {
// keyboard state but the block does more than that (i.e. setting up // keyboard state but the block does more than that (i.e. setting up
// WM_CLASS). // WM_CLASS).
const x11_xkb: ?x11.Xkb = x11_xkb: { const x11_xkb: ?x11.Xkb = x11_xkb: {
const display = c.gdk_display_get_default();
if (!x11.is_display(display)) break :x11_xkb null; if (!x11.is_display(display)) break :x11_xkb null;
// Set the X11 window class property (WM_CLASS) if are are on an X11 // Set the X11 window class property (WM_CLASS) if are are on an X11
@ -335,7 +382,14 @@ pub fn init(core_app: *CoreApp, opts: Options) !App {
); );
} }
// Internally, GTK ensures that only one instance of this provider exists in the provider list
// for the display.
const css_provider = c.gtk_css_provider_new(); const css_provider = c.gtk_css_provider_new();
c.gtk_style_context_add_provider_for_display(
display,
@ptrCast(css_provider),
c.GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + 3,
);
try loadRuntimeCss(&config, css_provider); try loadRuntimeCss(&config, css_provider);
return .{ return .{

View File

@ -80,10 +80,17 @@ pub fn init(self: *Window, app: *App) !void {
}; };
// Create the window // Create the window
const window: *c.GtkWidget = if (self.isAdwWindow()) const window: *c.GtkWidget = window: {
c.adw_application_window_new(app.app) if (self.isAdwWindow()) {
else const window = c.adw_application_window_new(app.app);
c.gtk_application_window_new(app.app); c.gtk_widget_add_css_class(@ptrCast(window), "adw");
break :window window;
} else {
const window = c.gtk_application_window_new(app.app);
c.gtk_widget_add_css_class(@ptrCast(window), "gtk");
break :window window;
}
};
const gtk_window: *c.GtkWindow = @ptrCast(window); const gtk_window: *c.GtkWindow = @ptrCast(window);
errdefer if (self.isAdwWindow()) { errdefer if (self.isAdwWindow()) {
@ -111,11 +118,6 @@ pub fn init(self: *Window, app: *App) !void {
c.gtk_widget_remove_css_class(@ptrCast(window), "background"); c.gtk_widget_remove_css_class(@ptrCast(window), "background");
} }
// Internally, GTK ensures that only one instance of this provider exists in the provider list
// for the display.
const display = c.gdk_display_get_default();
c.gtk_style_context_add_provider_for_display(display, @ptrCast(app.css_provider), c.GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
// Create our box which will hold our widgets in the main content area. // Create our box which will hold our widgets in the main content area.
const box = c.gtk_box_new(c.GTK_ORIENTATION_VERTICAL, 0); const box = c.gtk_box_new(c.GTK_ORIENTATION_VERTICAL, 0);

View File

@ -49,45 +49,42 @@ const icons = [_]struct {
}, },
}; };
pub const gresource_xml_gtk = comptimeGenerateGResourceXML(false); pub const gresource_xml = comptimeGenerateGResourceXML();
pub const gresource_xml_libadwaita = comptimeGenerateGResourceXML(true);
fn comptimeGenerateGResourceXML(comptime libadwaita: bool) []const u8 { fn comptimeGenerateGResourceXML() []const u8 {
comptime { comptime {
@setEvalBranchQuota(13000); @setEvalBranchQuota(13000);
var counter = std.io.countingWriter(std.io.null_writer); var counter = std.io.countingWriter(std.io.null_writer);
try writeGResourceXML(libadwaita, &counter.writer()); try writeGResourceXML(&counter.writer());
var buf: [counter.bytes_written]u8 = undefined; var buf: [counter.bytes_written]u8 = undefined;
var stream = std.io.fixedBufferStream(&buf); var stream = std.io.fixedBufferStream(&buf);
try writeGResourceXML(libadwaita, stream.writer()); try writeGResourceXML(stream.writer());
const final = buf; const final = buf;
return final[0..stream.getWritten().len]; return final[0..stream.getWritten().len];
} }
} }
fn writeGResourceXML(libadwaita: bool, writer: anytype) !void { fn writeGResourceXML(writer: anytype) !void {
try writer.writeAll( try writer.writeAll(
\\<?xml version="1.0" encoding="UTF-8"?> \\<?xml version="1.0" encoding="UTF-8"?>
\\<gresources> \\<gresources>
\\ \\
); );
if (libadwaita) { try writer.writeAll(
try writer.writeAll( \\ <gresource prefix="/com/mitchellh/ghostty">
\\ <gresource prefix="/com/mitchellh/ghostty"> \\
\\ );
); for (css_files) |css_file| {
for (css_files) |css_file| { try writer.print(
try writer.print( " <file compressed=\"true\" alias=\"{s}\">src/apprt/gtk/{s}</file>\n",
" <file compressed=\"true\" alias=\"{s}\">src/apprt/gtk/{s}</file>\n", .{ css_file, css_file },
.{ css_file, css_file },
);
}
try writer.writeAll(
\\ </gresource>
\\
); );
} }
try writer.writeAll(
\\ </gresource>
\\
);
try writer.writeAll( try writer.writeAll(
\\ <gresource prefix="/com/mitchellh/ghostty/icons"> \\ <gresource prefix="/com/mitchellh/ghostty/icons">
\\ \\
@ -105,15 +102,7 @@ fn writeGResourceXML(libadwaita: bool, writer: anytype) !void {
); );
} }
pub const dependencies_gtk = deps: { pub const dependencies = deps: {
var deps: [icons.len][]const u8 = undefined;
for (icons, 0..) |icon, i| {
deps[i] = std.fmt.comptimePrint("images/icons/icon_{s}.png", .{icon.source});
}
break :deps deps;
};
pub const dependencies_libadwaita = deps: {
var deps: [css_files.len + icons.len][]const u8 = undefined; var deps: [css_files.len + icons.len][]const u8 = undefined;
for (css_files, 0..) |css_file, i| { for (css_files, 0..) |css_file, i| {
deps[i] = std.fmt.comptimePrint("src/apprt/gtk/{s}", .{css_file}); deps[i] = std.fmt.comptimePrint("src/apprt/gtk/{s}", .{css_file});