mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
apprt/gtk: style gtk titlebar to match running terminal app
This commit is contained in:
@ -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;
|
||||
|
@ -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,
|
||||
|
Reference in New Issue
Block a user