mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00

Related #2755 From the mode 2031 spec[1]: > Send CSI ? 2031 h to the terminal to enable unsolicited DSR (device status > report) messages for color palette updates and CSI ? 2031 l respectively to > disable it again. > > The sent out DSR looks equivalent to the already above mentioned. This > notification is not just sent when dark/light mode has been changed by the > operating system / desktop, but also if the user explicitly changed color > scheme, e.g. by configuration. My reading of this paired with the original discussion is that this is meant to be sent out for anything that could possibly change terminal colors. Previous to this commit, we only sent out the DSR when the actual system light/dark mode changed. This commit changes it to send out the DSR on any operation that _may_ change the terminal colors. [1]: https://contour-terminal.org/vt-extensions/color-palette-update-notifications/#example-source-code
136 lines
4.2 KiB
Zig
136 lines
4.2 KiB
Zig
const apprt = @import("../apprt.zig");
|
|
const App = @import("../App.zig");
|
|
const Surface = @import("../Surface.zig");
|
|
const renderer = @import("../renderer.zig");
|
|
const termio = @import("../termio.zig");
|
|
const terminal = @import("../terminal/main.zig");
|
|
const Config = @import("../config.zig").Config;
|
|
|
|
/// The message types that can be sent to a single surface.
|
|
pub const Message = union(enum) {
|
|
/// Represents a write request. Magic number comes from the max size
|
|
/// we want this union to be.
|
|
pub const WriteReq = termio.MessageData(u8, 255);
|
|
|
|
/// Set the title of the surface.
|
|
/// TODO: we should change this to a "WriteReq" style structure in
|
|
/// the termio message so that we can more efficiently send strings
|
|
/// of any length
|
|
set_title: [256]u8,
|
|
|
|
/// Report the window title back to the terminal
|
|
report_title: ReportTitleStyle,
|
|
|
|
/// Set the mouse shape.
|
|
set_mouse_shape: terminal.MouseShape,
|
|
|
|
/// Read the clipboard and write to the pty.
|
|
clipboard_read: apprt.Clipboard,
|
|
|
|
/// Write the clipboard contents.
|
|
clipboard_write: struct {
|
|
clipboard_type: apprt.Clipboard,
|
|
req: WriteReq,
|
|
},
|
|
|
|
/// Change the configuration to the given configuration. The pointer is
|
|
/// not valid after receiving this message so any config must be used
|
|
/// and derived immediately.
|
|
change_config: *const Config,
|
|
|
|
/// Close the surface. This will only close the current surface that
|
|
/// receives this, not the full application.
|
|
close: void,
|
|
|
|
/// The child process running in the surface has exited. This may trigger
|
|
/// a surface close, it may not.
|
|
child_exited: void,
|
|
|
|
/// Show a desktop notification.
|
|
desktop_notification: struct {
|
|
/// Desktop notification title.
|
|
title: [63:0]u8,
|
|
|
|
/// Desktop notification body.
|
|
body: [255:0]u8,
|
|
},
|
|
|
|
/// Health status change for the renderer.
|
|
renderer_health: renderer.Health,
|
|
|
|
/// Report the color scheme. The bool parameter is whether to force or not.
|
|
/// If force is true, the color scheme should be reported even if mode
|
|
/// 2031 is not set.
|
|
report_color_scheme: bool,
|
|
|
|
/// Tell the surface to present itself to the user. This may require raising
|
|
/// a window and switching tabs.
|
|
present_surface: void,
|
|
|
|
/// Notifies the surface that password input has started within
|
|
/// the terminal. This should always be followed by a false value
|
|
/// unless the surface exits.
|
|
password_input: bool,
|
|
|
|
/// A terminal color was changed using OSC sequences.
|
|
color_change: struct {
|
|
kind: terminal.osc.Command.ColorKind,
|
|
color: terminal.color.RGB,
|
|
},
|
|
|
|
/// The terminal has reported a change in the working directory.
|
|
pwd_change: WriteReq,
|
|
|
|
pub const ReportTitleStyle = enum {
|
|
csi_21_t,
|
|
|
|
// This enum is a placeholder for future title styles.
|
|
};
|
|
};
|
|
|
|
/// A surface mailbox.
|
|
pub const Mailbox = struct {
|
|
surface: *Surface,
|
|
app: App.Mailbox,
|
|
|
|
/// Send a message to the surface.
|
|
pub fn push(
|
|
self: Mailbox,
|
|
msg: Message,
|
|
timeout: App.Mailbox.Queue.Timeout,
|
|
) App.Mailbox.Queue.Size {
|
|
// Surface message sending is actually implemented on the app
|
|
// thread, so we have to rewrap the message with our surface
|
|
// pointer and send it to the app thread.
|
|
return self.app.push(.{
|
|
.surface_message = .{
|
|
.surface = self.surface,
|
|
.message = msg,
|
|
},
|
|
}, timeout);
|
|
}
|
|
};
|
|
|
|
/// Returns a new config for a surface for the given app that should be
|
|
/// used for any new surfaces. The resulting config should be deinitialized
|
|
/// after the surface is initialized.
|
|
pub fn newConfig(app: *const App, config: *const Config) !Config {
|
|
// Create a shallow clone
|
|
var copy = config.shallowClone(app.alloc);
|
|
|
|
// Our allocator is our config's arena
|
|
const alloc = copy._arena.?.allocator();
|
|
|
|
// Get our previously focused surface for some inherited values.
|
|
const prev = app.focusedSurface();
|
|
if (prev) |p| {
|
|
if (config.@"window-inherit-working-directory") {
|
|
if (try p.pwd(alloc)) |pwd| {
|
|
copy.@"working-directory" = pwd;
|
|
}
|
|
}
|
|
}
|
|
|
|
return copy;
|
|
}
|