mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-22 19:56:08 +03:00
core: colorSchemeCallback on surface, can report
This commit is contained in:
@ -90,6 +90,11 @@ mouse: Mouse,
|
|||||||
/// less important.
|
/// less important.
|
||||||
pressed_key: ?input.KeyEvent = null,
|
pressed_key: ?input.KeyEvent = null,
|
||||||
|
|
||||||
|
/// The current color scheme of the GUI element containing this surface.
|
||||||
|
/// This will default to light until the apprt sends us the actual color
|
||||||
|
/// scheme. This is used by mode 3031 and CSI 996 n.
|
||||||
|
color_scheme: apprt.ColorScheme = .light,
|
||||||
|
|
||||||
/// The hash value of the last keybinding trigger that we performed. This
|
/// The hash value of the last keybinding trigger that we performed. This
|
||||||
/// is only set if the last key input matched a keybinding, consumed it,
|
/// is only set if the last key input matched a keybinding, consumed it,
|
||||||
/// and performed it. This is used to prevent sending release/repeat events
|
/// and performed it. This is used to prevent sending release/repeat events
|
||||||
@ -832,6 +837,16 @@ pub fn handleMessage(self: *Surface, msg: Message) !void {
|
|||||||
},
|
},
|
||||||
|
|
||||||
.renderer_health => |health| self.updateRendererHealth(health),
|
.renderer_health => |health| self.updateRendererHealth(health),
|
||||||
|
|
||||||
|
.report_color_scheme => {
|
||||||
|
const output = switch (self.color_scheme) {
|
||||||
|
.light => "\x1B[?997;2n",
|
||||||
|
.dark => "\x1B[?997;1n",
|
||||||
|
};
|
||||||
|
|
||||||
|
_ = self.io_thread.mailbox.push(.{ .write_stable = output }, .{ .forever = {} });
|
||||||
|
try self.io_thread.wakeup.notify();
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2786,6 +2801,12 @@ fn dragLeftClickBefore(
|
|||||||
return screen_point.before(click_point);
|
return screen_point.before(click_point);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Call to notify Ghostty that the color scheme for the terminal has
|
||||||
|
/// changed.
|
||||||
|
pub fn colorSchemeCallback(self: *Surface, scheme: apprt.ColorScheme) void {
|
||||||
|
self.color_scheme = scheme;
|
||||||
|
}
|
||||||
|
|
||||||
fn posToViewport(self: Surface, xpos: f64, ypos: f64) terminal.point.Viewport {
|
fn posToViewport(self: Surface, xpos: f64, ypos: f64) terminal.point.Viewport {
|
||||||
// xpos/ypos need to be adjusted for window padding
|
// xpos/ypos need to be adjusted for window padding
|
||||||
// (i.e. "window-padding-*" settings.
|
// (i.e. "window-padding-*" settings.
|
||||||
|
@ -61,3 +61,9 @@ pub const DesktopNotification = struct {
|
|||||||
/// The body of a notification. This will always be shown.
|
/// The body of a notification. This will always be shown.
|
||||||
body: []const u8,
|
body: []const u8,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// The color scheme in use (light vs dark).
|
||||||
|
pub const ColorScheme = enum(u2) {
|
||||||
|
light = 0,
|
||||||
|
dark = 1,
|
||||||
|
};
|
||||||
|
@ -57,6 +57,9 @@ pub const Message = union(enum) {
|
|||||||
|
|
||||||
/// Health status change for the renderer.
|
/// Health status change for the renderer.
|
||||||
renderer_health: renderer.Health,
|
renderer_health: renderer.Health,
|
||||||
|
|
||||||
|
/// Report the color scheme
|
||||||
|
report_color_scheme: void,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A surface mailbox.
|
/// A surface mailbox.
|
||||||
|
67
src/terminal/device_status.zig
Normal file
67
src/terminal/device_status.zig
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
/// An enum(u16) of the available device status requests.
|
||||||
|
pub const Request = dsr_enum: {
|
||||||
|
const EnumField = std.builtin.Type.EnumField;
|
||||||
|
var fields: [entries.len]EnumField = undefined;
|
||||||
|
for (entries, 0..) |entry, i| {
|
||||||
|
fields[i] = .{
|
||||||
|
.name = entry.name,
|
||||||
|
.value = @as(Tag.Backing, @bitCast(Tag{
|
||||||
|
.value = entry.value,
|
||||||
|
.question = entry.question,
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
break :dsr_enum @Type(.{ .Enum = .{
|
||||||
|
.tag_type = Tag.Backing,
|
||||||
|
.fields = &fields,
|
||||||
|
.decls = &.{},
|
||||||
|
.is_exhaustive = true,
|
||||||
|
} });
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The tag type for our enum is a u16 but we use a packed struct
|
||||||
|
/// in order to pack the question bit into the tag. The "u16" size is
|
||||||
|
/// chosen somewhat arbitrarily to match the largest expected size
|
||||||
|
/// we see as a multiple of 8 bits.
|
||||||
|
pub const Tag = packed struct(u16) {
|
||||||
|
pub const Backing = @typeInfo(@This()).Struct.backing_integer.?;
|
||||||
|
value: u15,
|
||||||
|
question: bool = false,
|
||||||
|
|
||||||
|
test "order" {
|
||||||
|
const t: Tag = .{ .value = 1 };
|
||||||
|
const int: Backing = @bitCast(t);
|
||||||
|
try std.testing.expectEqual(@as(Backing, 1), int);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn reqFromInt(v: u16, question: bool) ?Request {
|
||||||
|
inline for (entries) |entry| {
|
||||||
|
if (entry.value == v and entry.question == question) {
|
||||||
|
const tag: Tag = .{ .question = question, .value = entry.value };
|
||||||
|
const int: Tag.Backing = @bitCast(tag);
|
||||||
|
return @enumFromInt(int);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A single entry of a possible device status request we support. The
|
||||||
|
/// "question" field determines if it is valid with or without the "?"
|
||||||
|
/// prefix.
|
||||||
|
const Entry = struct {
|
||||||
|
name: [:0]const u8,
|
||||||
|
value: comptime_int,
|
||||||
|
question: bool = false, // "?" request
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The full list of device status request entries.
|
||||||
|
const entries: []const Entry = &.{
|
||||||
|
.{ .name = "operating_status", .value = 5 },
|
||||||
|
.{ .name = "cursor_position", .value = 6 },
|
||||||
|
.{ .name = "theme", .value = 996, .question = true },
|
||||||
|
};
|
@ -2375,7 +2375,7 @@ const StreamHandler = struct {
|
|||||||
self.messageWriter(msg);
|
self.messageWriter(msg);
|
||||||
},
|
},
|
||||||
|
|
||||||
.theme => {},
|
.theme => self.surfaceMessageWriter(.{ .report_color_scheme = {} }),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user