pull/10961/merge
jake-stewart 2026-06-02 03:16:11 +08:00 committed by GitHub
commit 6334b8c368
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 63 additions and 2 deletions

View File

@ -157,6 +157,9 @@ pub const DerivedConfig = struct {
arena: ArenaAllocator,
palette: terminalpkg.color.Palette,
palette_generate: bool,
palette_harmonious: bool,
config_palette_mask: terminalpkg.color.PaletteMask,
image_storage_limit: usize,
cursor_style: terminalpkg.CursorStyle,
cursor_blink: ?bool,
@ -193,6 +196,9 @@ pub const DerivedConfig = struct {
return .{
.palette = palette,
.config_palette_mask = config.palette.mask,
.palette_generate = config.@"palette-generate",
.palette_harmonious = config.@"palette-harmonious",
.image_storage_limit = config.@"image-storage-limit",
.cursor_style = config.@"cursor-style",
.cursor_blink = config.@"cursor-style-blink",
@ -283,6 +289,9 @@ pub fn init(self: *Termio, alloc: Allocator, opts: termio.Options) !void {
.renderer_mailbox = opts.renderer_mailbox,
.size = &self.size,
.terminal = &self.terminal,
.config_palette_mask = opts.config.config_palette_mask,
.palette_generate = opts.config.palette_generate,
.palette_harmonious = opts.config.palette_harmonious,
.osc_color_report_format = opts.config.osc_color_report_format,
.clipboard_write = opts.config.clipboard_write,
.enquiry_response = opts.config.enquiry_response,

View File

@ -50,6 +50,14 @@ pub const StreamHandler = struct {
/// whoever owns StreamHandler.
enquiry_response: []const u8,
/// Palette generation parameters, used to regenerate the extended
/// palette when foreground/background changes via OSC 4/10/11.
palette_generate: bool,
palette_harmonious: bool,
// When generating the palette, we avoid replacing manually set colors.
config_palette_mask: terminal.color.PaletteMask,
/// The color reporting format for OSC requests.
osc_color_report_format: configpkg.Config.OSCColorReportFormat,
@ -107,6 +115,9 @@ pub const StreamHandler = struct {
/// Change the configuration for this handler.
pub fn changeConfig(self: *StreamHandler, config: *termio.DerivedConfig) void {
self.palette_generate = config.palette_generate;
self.palette_harmonious = config.palette_harmonious;
self.config_palette_mask = config.config_palette_mask;
self.osc_color_report_format = config.osc_color_report_format;
self.clipboard_write = config.clipboard_write;
self.enquiry_response = config.enquiry_response;
@ -1208,6 +1219,17 @@ pub const StreamHandler = struct {
}
}
fn regeneratePalette(self: *StreamHandler) void {
self.terminal.colors.palette.current = terminal.color.generate256Color(
self.terminal.colors.palette.current,
self.terminal.colors.palette.mask.unionWith(self.config_palette_mask),
self.terminal.colors.background.get() orelse return,
self.terminal.colors.foreground.get() orelse return,
self.palette_harmonious,
);
self.terminal.flags.dirty.palette = true;
}
fn colorOperation(
self: *StreamHandler,
op: terminal.osc.color.Operation,
@ -1228,6 +1250,11 @@ pub const StreamHandler = struct {
const writer = response.writer(alloc);
var it = requests.constIterator(0);
// If FG, BG, or one of the 6 primary/secondary normal colors change,
// we should regenerate the 256-color palette.
var should_regenerate_palette = false;
while (it.next()) |req| {
switch (req.*) {
.set => |set| {
@ -1235,10 +1262,17 @@ pub const StreamHandler = struct {
.palette => |i| {
self.terminal.flags.dirty.palette = true;
self.terminal.colors.palette.set(i, set.color);
should_regenerate_palette |= i > 0 and i < 7;
},
.dynamic => |dynamic| switch (dynamic) {
.foreground => self.terminal.colors.foreground.set(set.color),
.background => self.terminal.colors.background.set(set.color),
.foreground => {
self.terminal.colors.foreground.set(set.color);
should_regenerate_palette = true;
},
.background => {
self.terminal.colors.background.set(set.color);
should_regenerate_palette = true;
},
.cursor => self.terminal.colors.cursor.set(set.color),
.pointer_foreground,
.pointer_background,
@ -1265,6 +1299,7 @@ pub const StreamHandler = struct {
.palette => |i| {
self.terminal.flags.dirty.palette = true;
self.terminal.colors.palette.reset(i);
should_regenerate_palette |= i > 0 and i < 7;
self.surfaceMessageWriter(.{
.color_change = .{
@ -1276,6 +1311,7 @@ pub const StreamHandler = struct {
.dynamic => |dynamic| switch (dynamic) {
.foreground => {
self.terminal.colors.foreground.reset();
should_regenerate_palette = true;
if (self.terminal.colors.foreground.default) |c| {
self.surfaceMessageWriter(.{ .color_change = .{
@ -1286,6 +1322,7 @@ pub const StreamHandler = struct {
},
.background => {
self.terminal.colors.background.reset();
should_regenerate_palette = true;
if (self.terminal.colors.background.default) |c| {
self.surfaceMessageWriter(.{ .color_change = .{
@ -1332,6 +1369,7 @@ pub const StreamHandler = struct {
});
}
mask.* = .initEmpty();
should_regenerate_palette = false;
},
.reset_special => log.warn(
@ -1423,6 +1461,20 @@ pub const StreamHandler = struct {
}
}
if (should_regenerate_palette and self.palette_generate) {
self.regeneratePalette();
const mask = &self.terminal.colors.palette.mask;
var mask_it = mask.iterator(.{ .kind = .unset });
while (mask_it.next()) |i| {
self.surfaceMessageWriter(.{
.color_change = .{
.target = .{ .palette = @intCast(i) },
.color = self.terminal.colors.palette.current[i],
},
});
}
}
if (response.items.len > 0) {
// If any of the operations were reports, finalize the report
// string and send it to the terminal.