mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +03:00
termio: reader => backend
This commit is contained in:
@ -460,7 +460,7 @@ pub fn init(
|
|||||||
.padding = padding,
|
.padding = padding,
|
||||||
.full_config = config,
|
.full_config = config,
|
||||||
.config = try termio.Termio.DerivedConfig.init(alloc, config),
|
.config = try termio.Termio.DerivedConfig.init(alloc, config),
|
||||||
.reader = .{ .exec = io_exec },
|
.backend = .{ .exec = io_exec },
|
||||||
.writer = io_writer,
|
.writer = io_writer,
|
||||||
.renderer_state = &self.renderer_state,
|
.renderer_state = &self.renderer_state,
|
||||||
.renderer_wakeup = render_thread.wakeup,
|
.renderer_wakeup = render_thread.wakeup,
|
||||||
|
@ -5,15 +5,15 @@
|
|||||||
const stream_handler = @import("termio/stream_handler.zig");
|
const stream_handler = @import("termio/stream_handler.zig");
|
||||||
|
|
||||||
pub usingnamespace @import("termio/message.zig");
|
pub usingnamespace @import("termio/message.zig");
|
||||||
pub const reader = @import("termio/reader.zig");
|
pub const backend = @import("termio/backend.zig");
|
||||||
pub const writer = @import("termio/writer.zig");
|
pub const writer = @import("termio/writer.zig");
|
||||||
pub const Exec = @import("termio/Exec.zig");
|
pub const Exec = @import("termio/Exec.zig");
|
||||||
pub const Options = @import("termio/Options.zig");
|
pub const Options = @import("termio/Options.zig");
|
||||||
pub const Termio = @import("termio/Termio.zig");
|
pub const Termio = @import("termio/Termio.zig");
|
||||||
pub const Thread = @import("termio/Thread.zig");
|
pub const Thread = @import("termio/Thread.zig");
|
||||||
|
pub const Backend = backend.Backend;
|
||||||
pub const DerivedConfig = Termio.DerivedConfig;
|
pub const DerivedConfig = Termio.DerivedConfig;
|
||||||
pub const Mailbox = writer.Mailbox;
|
pub const Mailbox = writer.Mailbox;
|
||||||
pub const Reader = reader.Reader;
|
|
||||||
pub const StreamHandler = stream_handler.StreamHandler;
|
pub const StreamHandler = stream_handler.StreamHandler;
|
||||||
pub const Writer = writer.Writer;
|
pub const Writer = writer.Writer;
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ const windows = internal_os.windows;
|
|||||||
|
|
||||||
const log = std.log.scoped(.io_exec);
|
const log = std.log.scoped(.io_exec);
|
||||||
|
|
||||||
/// The subprocess state for our exec reader.
|
/// The subprocess state for our exec backend.
|
||||||
subprocess: Subprocess,
|
subprocess: Subprocess,
|
||||||
|
|
||||||
/// Initialize the exec state. This will NOT start it, this only sets
|
/// Initialize the exec state. This will NOT start it, this only sets
|
||||||
@ -45,7 +45,7 @@ pub fn deinit(self: *Exec) void {
|
|||||||
self.subprocess.deinit();
|
self.subprocess.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Call to initialize the terminal state as necessary for this reader.
|
/// Call to initialize the terminal state as necessary for this backend.
|
||||||
/// This is called before any termio begins. This should not be called
|
/// This is called before any termio begins. This should not be called
|
||||||
/// after termio begins because it may put the internal terminal state
|
/// after termio begins because it may put the internal terminal state
|
||||||
/// into a bad state.
|
/// into a bad state.
|
||||||
@ -121,8 +121,8 @@ pub fn threadEnter(
|
|||||||
);
|
);
|
||||||
read_thread.setName("io-reader") catch {};
|
read_thread.setName("io-reader") catch {};
|
||||||
|
|
||||||
// Setup our threadata reader state to be our own
|
// Setup our threadata backend state to be our own
|
||||||
td.reader = .{ .exec = .{
|
td.backend = .{ .exec = .{
|
||||||
.start = process_start,
|
.start = process_start,
|
||||||
.abnormal_runtime_threshold_ms = io.config.abnormal_runtime_threshold_ms,
|
.abnormal_runtime_threshold_ms = io.config.abnormal_runtime_threshold_ms,
|
||||||
.wait_after_command = io.config.wait_after_command,
|
.wait_after_command = io.config.wait_after_command,
|
||||||
@ -136,7 +136,7 @@ pub fn threadEnter(
|
|||||||
// Start our process watcher
|
// Start our process watcher
|
||||||
process.wait(
|
process.wait(
|
||||||
td.loop,
|
td.loop,
|
||||||
&td.reader.exec.process_wait_c,
|
&td.backend.exec.process_wait_c,
|
||||||
termio.Termio.ThreadData,
|
termio.Termio.ThreadData,
|
||||||
td,
|
td,
|
||||||
processExit,
|
processExit,
|
||||||
@ -144,8 +144,8 @@ pub fn threadEnter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn threadExit(self: *Exec, td: *termio.Termio.ThreadData) void {
|
pub fn threadExit(self: *Exec, td: *termio.Termio.ThreadData) void {
|
||||||
assert(td.reader == .exec);
|
assert(td.backend == .exec);
|
||||||
const exec = &td.reader.exec;
|
const exec = &td.backend.exec;
|
||||||
|
|
||||||
if (exec.exited) self.subprocess.externalExit();
|
if (exec.exited) self.subprocess.externalExit();
|
||||||
self.subprocess.stop();
|
self.subprocess.stop();
|
||||||
@ -282,8 +282,8 @@ fn processExit(
|
|||||||
const exit_code = r catch unreachable;
|
const exit_code = r catch unreachable;
|
||||||
|
|
||||||
const td = td_.?;
|
const td = td_.?;
|
||||||
assert(td.reader == .exec);
|
assert(td.backend == .exec);
|
||||||
const execdata = &td.reader.exec;
|
const execdata = &td.backend.exec;
|
||||||
execdata.exited = true;
|
execdata.exited = true;
|
||||||
|
|
||||||
// Determine how long the process was running for.
|
// Determine how long the process was running for.
|
||||||
@ -366,7 +366,7 @@ pub fn queueWrite(
|
|||||||
linefeed: bool,
|
linefeed: bool,
|
||||||
) !void {
|
) !void {
|
||||||
_ = self;
|
_ = self;
|
||||||
const exec = &td.reader.exec;
|
const exec = &td.backend.exec;
|
||||||
|
|
||||||
// If our process is exited then we send our surface a message
|
// If our process is exited then we send our surface a message
|
||||||
// about it but we don't queue any more writes.
|
// about it but we don't queue any more writes.
|
||||||
|
@ -25,8 +25,8 @@ full_config: *const Config,
|
|||||||
/// The derived configuration for this termio implementation.
|
/// The derived configuration for this termio implementation.
|
||||||
config: termio.Termio.DerivedConfig,
|
config: termio.Termio.DerivedConfig,
|
||||||
|
|
||||||
/// The reader for the terminal.
|
/// The backend for termio that implements where reads/writes are sourced.
|
||||||
reader: termio.Reader,
|
backend: termio.Backend,
|
||||||
|
|
||||||
/// The writer for the terminal. This is how messages are delivered.
|
/// The writer for the terminal. This is how messages are delivered.
|
||||||
/// If you're using termio.Thread this MUST be "mailbox".
|
/// If you're using termio.Thread this MUST be "mailbox".
|
||||||
|
@ -34,7 +34,7 @@ const log = std.log.scoped(.io_exec);
|
|||||||
alloc: Allocator,
|
alloc: Allocator,
|
||||||
|
|
||||||
/// This is the implementation responsible for io.
|
/// This is the implementation responsible for io.
|
||||||
reader: termio.Reader,
|
backend: termio.Backend,
|
||||||
|
|
||||||
/// The derived configuration for this termio implementation.
|
/// The derived configuration for this termio implementation.
|
||||||
config: DerivedConfig,
|
config: DerivedConfig,
|
||||||
@ -168,9 +168,9 @@ pub fn init(self: *Termio, alloc: Allocator, opts: termio.Options) !void {
|
|||||||
// Set our default cursor style
|
// Set our default cursor style
|
||||||
term.screen.cursor.cursor_style = opts.config.cursor_style;
|
term.screen.cursor.cursor_style = opts.config.cursor_style;
|
||||||
|
|
||||||
// Setup our reader.
|
// Setup our backend.
|
||||||
var reader = opts.reader;
|
var backend = opts.backend;
|
||||||
reader.initTerminal(&term);
|
backend.initTerminal(&term);
|
||||||
|
|
||||||
// Setup our terminal size in pixels for certain requests.
|
// Setup our terminal size in pixels for certain requests.
|
||||||
const screen_size = opts.screen_size.subPadding(opts.padding);
|
const screen_size = opts.screen_size.subPadding(opts.padding);
|
||||||
@ -216,7 +216,7 @@ pub fn init(self: *Termio, alloc: Allocator, opts: termio.Options) !void {
|
|||||||
.renderer_mailbox = opts.renderer_mailbox,
|
.renderer_mailbox = opts.renderer_mailbox,
|
||||||
.surface_mailbox = opts.surface_mailbox,
|
.surface_mailbox = opts.surface_mailbox,
|
||||||
.grid_size = opts.grid_size,
|
.grid_size = opts.grid_size,
|
||||||
.reader = opts.reader,
|
.backend = opts.backend,
|
||||||
.writer = opts.writer,
|
.writer = opts.writer,
|
||||||
.terminal_stream = .{
|
.terminal_stream = .{
|
||||||
.handler = handler,
|
.handler = handler,
|
||||||
@ -232,7 +232,7 @@ pub fn init(self: *Termio, alloc: Allocator, opts: termio.Options) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Termio) void {
|
pub fn deinit(self: *Termio) void {
|
||||||
self.reader.deinit();
|
self.backend.deinit();
|
||||||
self.terminal.deinit(self.alloc);
|
self.terminal.deinit(self.alloc);
|
||||||
self.config.deinit();
|
self.config.deinit();
|
||||||
self.writer.deinit(self.alloc);
|
self.writer.deinit(self.alloc);
|
||||||
@ -258,15 +258,15 @@ pub fn threadEnter(self: *Termio, thread: *termio.Thread, data: *ThreadData) !vo
|
|||||||
.writer = &self.writer,
|
.writer = &self.writer,
|
||||||
|
|
||||||
// Placeholder until setup below
|
// Placeholder until setup below
|
||||||
.reader = .{ .manual = {} },
|
.backend = .{ .manual = {} },
|
||||||
};
|
};
|
||||||
|
|
||||||
// Setup our reader
|
// Setup our backend
|
||||||
try self.reader.threadEnter(alloc, self, data);
|
try self.backend.threadEnter(alloc, self, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn threadExit(self: *Termio, data: *ThreadData) void {
|
pub fn threadExit(self: *Termio, data: *ThreadData) void {
|
||||||
self.reader.threadExit(data);
|
self.backend.threadExit(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send a message using the writer. Depending on the writer type in
|
/// Send a message using the writer. Depending on the writer type in
|
||||||
@ -300,7 +300,7 @@ pub inline fn queueWrite(
|
|||||||
data: []const u8,
|
data: []const u8,
|
||||||
linefeed: bool,
|
linefeed: bool,
|
||||||
) !void {
|
) !void {
|
||||||
try self.reader.queueWrite(self.alloc, td, data, linefeed);
|
try self.backend.queueWrite(self.alloc, td, data, linefeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the configuration.
|
/// Update the configuration.
|
||||||
@ -320,7 +320,7 @@ pub fn changeConfig(self: *Termio, td: *ThreadData, config: *DerivedConfig) !voi
|
|||||||
// renderer mutex so this is safe to do despite being executed
|
// renderer mutex so this is safe to do despite being executed
|
||||||
// from another thread.
|
// from another thread.
|
||||||
self.terminal_stream.handler.changeConfig(&self.config);
|
self.terminal_stream.handler.changeConfig(&self.config);
|
||||||
td.reader.changeConfig(&self.config);
|
td.backend.changeConfig(&self.config);
|
||||||
|
|
||||||
// Update the configuration that we know about.
|
// Update the configuration that we know about.
|
||||||
//
|
//
|
||||||
@ -363,7 +363,7 @@ pub fn resize(
|
|||||||
) !void {
|
) !void {
|
||||||
// Update the size of our pty.
|
// Update the size of our pty.
|
||||||
const padded_size = screen_size.subPadding(padding);
|
const padded_size = screen_size.subPadding(padding);
|
||||||
try self.reader.resize(grid_size, padded_size);
|
try self.backend.resize(grid_size, padded_size);
|
||||||
|
|
||||||
// Update our cached grid size
|
// Update our cached grid size
|
||||||
self.grid_size = grid_size;
|
self.grid_size = grid_size;
|
||||||
@ -466,7 +466,7 @@ pub fn childExitedAbnormally(self: *Termio, exit_code: u32, runtime_ms: u64) !vo
|
|||||||
self.renderer_state.mutex.lock();
|
self.renderer_state.mutex.lock();
|
||||||
defer self.renderer_state.mutex.unlock();
|
defer self.renderer_state.mutex.unlock();
|
||||||
const t = self.renderer_state.terminal;
|
const t = self.renderer_state.terminal;
|
||||||
try self.reader.childExitedAbnormally(self.alloc, t, exit_code, runtime_ms);
|
try self.backend.childExitedAbnormally(self.alloc, t, exit_code, runtime_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Process output from the pty. This is the manual API that users can
|
/// Process output from the pty. This is the manual API that users can
|
||||||
@ -550,12 +550,12 @@ pub const ThreadData = struct {
|
|||||||
/// Mailboxes for different threads
|
/// Mailboxes for different threads
|
||||||
surface_mailbox: apprt.surface.Mailbox,
|
surface_mailbox: apprt.surface.Mailbox,
|
||||||
|
|
||||||
/// Data associated with the reader implementation (i.e. pty/exec state)
|
/// Data associated with the backend implementation (i.e. pty/exec state)
|
||||||
reader: termio.reader.ThreadData,
|
backend: termio.backend.ThreadData,
|
||||||
writer: *termio.Writer,
|
writer: *termio.Writer,
|
||||||
|
|
||||||
pub fn deinit(self: *ThreadData) void {
|
pub fn deinit(self: *ThreadData) void {
|
||||||
self.reader.deinit(self.alloc);
|
self.backend.deinit(self.alloc);
|
||||||
self.* = undefined;
|
self.* = undefined;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -34,19 +34,20 @@ pub const Config = union(Kind) {
|
|||||||
exec: termio.Exec.Config,
|
exec: termio.Exec.Config,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Reader implementations
|
/// Backend implementations. A backend is responsible for owning the pty
|
||||||
pub const Reader = union(Kind) {
|
/// behavior and providing read/write capabilities.
|
||||||
|
pub const Backend = union(Kind) {
|
||||||
manual: void,
|
manual: void,
|
||||||
exec: termio.Exec,
|
exec: termio.Exec,
|
||||||
|
|
||||||
pub fn deinit(self: *Reader) void {
|
pub fn deinit(self: *Backend) void {
|
||||||
switch (self.*) {
|
switch (self.*) {
|
||||||
.manual => {},
|
.manual => {},
|
||||||
.exec => |*exec| exec.deinit(),
|
.exec => |*exec| exec.deinit(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn initTerminal(self: *Reader, t: *terminal.Terminal) void {
|
pub fn initTerminal(self: *Backend, t: *terminal.Terminal) void {
|
||||||
switch (self.*) {
|
switch (self.*) {
|
||||||
.manual => {},
|
.manual => {},
|
||||||
.exec => |*exec| exec.initTerminal(t),
|
.exec => |*exec| exec.initTerminal(t),
|
||||||
@ -54,7 +55,7 @@ pub const Reader = union(Kind) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn threadEnter(
|
pub fn threadEnter(
|
||||||
self: *Reader,
|
self: *Backend,
|
||||||
alloc: Allocator,
|
alloc: Allocator,
|
||||||
io: *termio.Termio,
|
io: *termio.Termio,
|
||||||
td: *termio.Termio.ThreadData,
|
td: *termio.Termio.ThreadData,
|
||||||
@ -65,7 +66,7 @@ pub const Reader = union(Kind) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn threadExit(self: *Reader, td: *termio.Termio.ThreadData) void {
|
pub fn threadExit(self: *Backend, td: *termio.Termio.ThreadData) void {
|
||||||
switch (self.*) {
|
switch (self.*) {
|
||||||
.manual => {},
|
.manual => {},
|
||||||
.exec => |*exec| exec.threadExit(td),
|
.exec => |*exec| exec.threadExit(td),
|
||||||
@ -73,7 +74,7 @@ pub const Reader = union(Kind) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn resize(
|
pub fn resize(
|
||||||
self: *Reader,
|
self: *Backend,
|
||||||
grid_size: renderer.GridSize,
|
grid_size: renderer.GridSize,
|
||||||
screen_size: renderer.ScreenSize,
|
screen_size: renderer.ScreenSize,
|
||||||
) !void {
|
) !void {
|
||||||
@ -84,7 +85,7 @@ pub const Reader = union(Kind) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn queueWrite(
|
pub fn queueWrite(
|
||||||
self: *Reader,
|
self: *Backend,
|
||||||
alloc: Allocator,
|
alloc: Allocator,
|
||||||
td: *termio.Termio.ThreadData,
|
td: *termio.Termio.ThreadData,
|
||||||
data: []const u8,
|
data: []const u8,
|
||||||
@ -97,7 +98,7 @@ pub const Reader = union(Kind) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn childExitedAbnormally(
|
pub fn childExitedAbnormally(
|
||||||
self: *Reader,
|
self: *Backend,
|
||||||
gpa: Allocator,
|
gpa: Allocator,
|
||||||
t: *terminal.Terminal,
|
t: *terminal.Terminal,
|
||||||
exit_code: u32,
|
exit_code: u32,
|
Reference in New Issue
Block a user