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_tab_overview => self.toggleTabOverview(target),
|
||||||
.toggle_window_decorations => self.toggleWindowDecorations(target),
|
.toggle_window_decorations => self.toggleWindowDecorations(target),
|
||||||
.quit_timer => self.quitTimer(value),
|
.quit_timer => self.quitTimer(value),
|
||||||
|
.color_change => try self.colorChange(target, value),
|
||||||
|
|
||||||
// Unimplemented
|
// Unimplemented
|
||||||
.close_all_windows,
|
.close_all_windows,
|
||||||
@ -485,7 +486,6 @@ pub fn performAction(
|
|||||||
.key_sequence,
|
.key_sequence,
|
||||||
.render_inspector,
|
.render_inspector,
|
||||||
.renderer_health,
|
.renderer_health,
|
||||||
.color_change,
|
|
||||||
=> log.warn("unimplemented action={}", .{action}),
|
=> log.warn("unimplemented action={}", .{action}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -797,6 +797,17 @@ fn showDesktopNotification(
|
|||||||
c.g_application_send_notification(g_app, n.body.ptr, notification);
|
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.
|
/// Reload the configuration. This should return the new configuration.
|
||||||
/// The old value can be freed immediately at this point assuming a
|
/// The old value can be freed immediately at this point assuming a
|
||||||
/// successful return.
|
/// successful return.
|
||||||
@ -898,6 +909,25 @@ fn loadRuntimeCss(
|
|||||||
alloc: Allocator,
|
alloc: Allocator,
|
||||||
config: *const Config,
|
config: *const Config,
|
||||||
provider: *c.GtkCssProvider,
|
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 {
|
) Allocator.Error!void {
|
||||||
var stack_alloc = std.heap.stackFallback(4096, alloc);
|
var stack_alloc = std.heap.stackFallback(4096, alloc);
|
||||||
var buf = std.ArrayList(u8).init(stack_alloc.get());
|
var buf = std.ArrayList(u8).init(stack_alloc.get());
|
||||||
@ -906,8 +936,8 @@ fn loadRuntimeCss(
|
|||||||
|
|
||||||
const window_theme = config.@"window-theme";
|
const window_theme = config.@"window-theme";
|
||||||
const unfocused_fill: Config.Color = config.@"unfocused-split-fill" orelse config.background;
|
const unfocused_fill: Config.Color = config.@"unfocused-split-fill" orelse config.background;
|
||||||
const headerbar_background = config.background;
|
const headerbar_background = background_color;
|
||||||
const headerbar_foreground = config.foreground;
|
const headerbar_foreground = foreground_color;
|
||||||
|
|
||||||
try writer.print(
|
try writer.print(
|
||||||
\\widget.unfocused-split {{
|
\\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.
|
/// Called by CoreApp to wake up the event loop.
|
||||||
pub fn wakeup(self: App) void {
|
pub fn wakeup(self: App) void {
|
||||||
_ = self;
|
_ = self;
|
||||||
|
@ -5,7 +5,7 @@ const Surface = @This();
|
|||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const configpkg = @import("../../config.zig");
|
const Config = @import("../../config.zig").Config;
|
||||||
const apprt = @import("../../apprt.zig");
|
const apprt = @import("../../apprt.zig");
|
||||||
const font = @import("../../font/main.zig");
|
const font = @import("../../font/main.zig");
|
||||||
const input = @import("../../input.zig");
|
const input = @import("../../input.zig");
|
||||||
@ -342,6 +342,12 @@ cursor: ?*c.GdkCursor = null,
|
|||||||
/// pass it to GTK.
|
/// pass it to GTK.
|
||||||
title_text: ?[:0]const u8 = null,
|
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
|
/// The core surface backing this surface
|
||||||
core_surface: CoreSurface,
|
core_surface: CoreSurface,
|
||||||
|
|
||||||
@ -837,6 +843,32 @@ pub fn getTitle(self: *Surface) ?[:0]const u8 {
|
|||||||
return self.title_text;
|
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(
|
pub fn setMouseShape(
|
||||||
self: *Surface,
|
self: *Surface,
|
||||||
shape: terminal.MouseShape,
|
shape: terminal.MouseShape,
|
||||||
|
Reference in New Issue
Block a user