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, /// 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 report_color_scheme: 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) !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; }