apprt/gtk: style gtk titlebar to match running terminal app

This commit is contained in:
CJ van den Berg
2024-10-28 12:30:42 +01:00
parent 444cf3b402
commit 1f1b8293a4
2 changed files with 88 additions and 4 deletions

View File

@ -473,6 +473,7 @@ pub fn performAction(
.toggle_tab_overview => self.toggleTabOverview(target),
.toggle_window_decorations => self.toggleWindowDecorations(target),
.quit_timer => self.quitTimer(value),
.color_change => try self.colorChange(target, value),
// Unimplemented
.close_all_windows,
@ -485,7 +486,6 @@ pub fn performAction(
.key_sequence,
.render_inspector,
.renderer_health,
.color_change,
=> log.warn("unimplemented action={}", .{action}),
}
}
@ -797,6 +797,17 @@ fn showDesktopNotification(
c.g_application_send_notification(g_app, n.body.ptr, notification);
}
fn colorChange(
_: *App,
target: apprt.Target,
value: apprt.action.ColorChange,
) !void {
switch (target) {
.app => {},
.surface => |v| try v.rt_surface.colorChange(value),
}
}
/// Reload the configuration. This should return the new configuration.
/// The old value can be freed immediately at this point assuming a
/// successful return.
@ -898,6 +909,25 @@ fn loadRuntimeCss(
alloc: Allocator,
config: *const Config,
provider: *c.GtkCssProvider,
) Allocator.Error!void {
const headerbar_background = config.background;
const headerbar_foreground = config.foreground;
return loadRuntimeCssRGB(
alloc,
config,
provider,
headerbar_background,
headerbar_foreground,
);
}
fn loadRuntimeCssRGB(
alloc: Allocator,
config: *const Config,
provider: *c.GtkCssProvider,
background_color: Config.Color,
foreground_color: Config.Color,
) Allocator.Error!void {
var stack_alloc = std.heap.stackFallback(4096, alloc);
var buf = std.ArrayList(u8).init(stack_alloc.get());
@ -906,8 +936,8 @@ fn loadRuntimeCss(
const window_theme = config.@"window-theme";
const unfocused_fill: Config.Color = config.@"unfocused-split-fill" orelse config.background;
const headerbar_background = config.background;
const headerbar_foreground = config.foreground;
const headerbar_background = background_color;
const headerbar_foreground = foreground_color;
try writer.print(
\\widget.unfocused-split {{
@ -972,6 +1002,28 @@ fn loadRuntimeCss(
);
}
/// Call this anytime the color scheme changes.
pub fn syncColorChanges(
self: *App,
background_color: ?Config.Color,
foreground_color: ?Config.Color,
) !void {
// Load our runtime 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.
loadRuntimeCssRGB(
self.core_app.alloc,
&self.config,
self.css_provider,
background_color orelse self.config.background,
foreground_color orelse self.config.foreground,
) catch |err| switch (err) {
error.OutOfMemory => log.warn(
"out of memory loading runtime CSS, no runtime CSS applied",
.{},
),
};
}
/// Called by CoreApp to wake up the event loop.
pub fn wakeup(self: App) void {
_ = self;

View File

@ -5,7 +5,7 @@ const Surface = @This();
const std = @import("std");
const Allocator = std.mem.Allocator;
const configpkg = @import("../../config.zig");
const Config = @import("../../config.zig").Config;
const apprt = @import("../../apprt.zig");
const font = @import("../../font/main.zig");
const input = @import("../../input.zig");
@ -342,6 +342,12 @@ cursor: ?*c.GdkCursor = null,
/// pass it to GTK.
title_text: ?[:0]const u8 = null,
/// Local background color override.
background_color: ?Config.Color = null,
/// Local foreground color override.
foreground_color: ?Config.Color = null,
/// The core surface backing this surface
core_surface: CoreSurface,
@ -837,6 +843,32 @@ pub fn getTitle(self: *Surface) ?[:0]const u8 {
return self.title_text;
}
fn updateStyle(self: *Surface) !void {
// If we have no style, then we have nothing to update.
if (self.background_color == null and self.foreground_color == null) return;
try self.app.syncColorChanges(self.background_color, self.foreground_color);
}
pub fn colorChange(self: *Surface, value: apprt.action.ColorChange) !void {
const color: Config.Color = .{
.r = value.r,
.g = value.g,
.b = value.b,
};
switch (value.kind) {
.background => {
self.background_color = color;
try self.updateStyle();
},
.foreground => {
self.foreground_color = color;
try self.updateStyle();
},
else => {},
}
}
pub fn setMouseShape(
self: *Surface,
shape: terminal.MouseShape,