mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-01-02 03:22:37 +00:00
174 lines
5.5 KiB
Zig
174 lines
5.5 KiB
Zig
const std = @import("std");
|
|
const Allocator = std.mem.Allocator;
|
|
|
|
const apprt = @import("../apprt.zig");
|
|
const build_config = @import("../build_config.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. Additional details about the child
|
|
/// command are given in the `ChildExited` struct.
|
|
child_exited: ChildExited,
|
|
|
|
/// 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.ColorOperation.Kind,
|
|
color: terminal.color.RGB,
|
|
},
|
|
|
|
/// Notifies the surface that a tick of the timer that is timing
|
|
/// out selection scrolling has occurred. "selection scrolling"
|
|
/// is when the user has clicked and dragged the mouse outside
|
|
/// the viewport of the terminal and the terminal is scrolling
|
|
/// the viewport to follow the mouse cursor.
|
|
selection_scroll_tick: bool,
|
|
|
|
/// The terminal has reported a change in the working directory.
|
|
pwd_change: WriteReq,
|
|
|
|
/// The terminal encountered a bell character.
|
|
ring_bell,
|
|
|
|
/// Report the progress of an action using a GUI element
|
|
progress_report: terminal.osc.Command.ProgressReport,
|
|
|
|
pub const ReportTitleStyle = enum {
|
|
csi_21_t,
|
|
|
|
// This enum is a placeholder for future title styles.
|
|
};
|
|
|
|
pub const ChildExited = extern struct {
|
|
exit_code: u32,
|
|
runtime_ms: u64,
|
|
|
|
/// Make this a valid gobject if we're in a GTK environment.
|
|
pub const getGObjectType = switch (build_config.app_runtime) {
|
|
.gtk,
|
|
.@"gtk-ng",
|
|
=> @import("gobject").ext.defineBoxed(
|
|
ChildExited,
|
|
.{ .name = "GhosttyApprtChildExited" },
|
|
),
|
|
|
|
.none => void,
|
|
};
|
|
};
|
|
};
|
|
|
|
/// 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,
|
|
) Allocator.Error!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;
|
|
}
|