refactor(tty): move state into Vaxis struct

Move tty state (*not* termios, though) into Vaxis struct
This commit is contained in:
Tim Culverhouse 2024-05-28 12:18:07 -05:00
parent 49003b0e2b
commit d7c3a7496d
2 changed files with 35 additions and 51 deletions

View file

@ -24,21 +24,6 @@ should_quit: bool = false,
buffered_writer: BufferedWriter, buffered_writer: BufferedWriter,
state: struct {
/// if we are in the alt screen
alt_screen: bool = false,
/// if we have entered kitty keyboard
kitty_keyboard: bool = false,
bracketed_paste: bool = false,
mouse: bool = false,
pixel_mouse: bool = false,
color_scheme_updates: bool = false,
cursor: struct {
row: usize = 0,
col: usize = 0,
} = .{},
} = .{},
/// initializes a Tty instance by opening /dev/tty and "making it raw" /// initializes a Tty instance by opening /dev/tty and "making it raw"
pub fn init() !Tty { pub fn init() !Tty {
// Open our tty // Open our tty
@ -56,21 +41,6 @@ pub fn init() !Tty {
/// release resources associated with the Tty return it to its original state /// release resources associated with the Tty return it to its original state
pub fn deinit(self: *Tty) void { pub fn deinit(self: *Tty) void {
if (self.state.kitty_keyboard) {
_ = self.write(ctlseqs.csi_u_pop) catch {};
}
if (self.state.mouse) {
_ = self.write(ctlseqs.mouse_reset) catch {};
}
if (self.state.bracketed_paste) {
_ = self.write(ctlseqs.bp_reset) catch {};
}
if (self.state.alt_screen) {
_ = self.write(ctlseqs.rmcup) catch {};
}
if (self.state.color_scheme_updates) {
_ = self.write(ctlseqs.color_scheme_reset) catch {};
}
// always show the cursor on exit // always show the cursor on exit
_ = self.write(ctlseqs.show_cursor) catch {}; _ = self.write(ctlseqs.show_cursor) catch {};
self.flush() catch {}; self.flush() catch {};

View file

@ -77,6 +77,21 @@ sgr: enum {
legacy, legacy,
} = .standard, } = .standard,
state: struct {
/// if we are in the alt screen
alt_screen: bool = false,
/// if we have entered kitty keyboard
kitty_keyboard: bool = false,
bracketed_paste: bool = false,
mouse: bool = false,
pixel_mouse: bool = false,
color_scheme_updates: bool = false,
cursor: struct {
row: usize = 0,
col: usize = 0,
} = .{},
} = .{},
/// Initialize Vaxis with runtime options /// Initialize Vaxis with runtime options
pub fn init(alloc: std.mem.Allocator, opts: Options) !Vaxis { pub fn init(alloc: std.mem.Allocator, opts: Options) !Vaxis {
return .{ return .{
@ -124,12 +139,12 @@ pub fn resize(self: *Vaxis, alloc: std.mem.Allocator, winsize: Winsize) !void {
self.screen_last.deinit(alloc); self.screen_last.deinit(alloc);
self.screen_last = try InternalScreen.init(alloc, winsize.cols, winsize.rows); self.screen_last = try InternalScreen.init(alloc, winsize.cols, winsize.rows);
var tty = self.tty orelse return; var tty = self.tty orelse return;
if (tty.state.alt_screen) if (self.state.alt_screen)
_ = try tty.write(ctlseqs.home) _ = try tty.write(ctlseqs.home)
else { else {
_ = try tty.buffered_writer.write("\r"); _ = try tty.buffered_writer.write("\r");
var i: usize = 0; var i: usize = 0;
while (i < tty.state.cursor.row) : (i += 1) { while (i < self.state.cursor.row) : (i += 1) {
_ = try tty.buffered_writer.write(ctlseqs.ri); _ = try tty.buffered_writer.write(ctlseqs.ri);
} }
} }
@ -152,20 +167,20 @@ pub fn window(self: *Vaxis) Window {
/// be exited if calling deinit while in the alt screen /// be exited if calling deinit while in the alt screen
pub fn enterAltScreen(self: *Vaxis) !void { pub fn enterAltScreen(self: *Vaxis) !void {
if (self.tty) |*tty| { if (self.tty) |*tty| {
if (tty.state.alt_screen) return; if (self.state.alt_screen) return;
_ = try tty.write(ctlseqs.smcup); _ = try tty.write(ctlseqs.smcup);
try tty.flush(); try tty.flush();
tty.state.alt_screen = true; self.state.alt_screen = true;
} }
} }
/// exit the alternate screen /// exit the alternate screen
pub fn exitAltScreen(self: *Vaxis) !void { pub fn exitAltScreen(self: *Vaxis) !void {
if (self.tty) |*tty| { if (self.tty) |*tty| {
if (!tty.state.alt_screen) return; if (!self.state.alt_screen) return;
_ = try tty.write(ctlseqs.rmcup); _ = try tty.write(ctlseqs.rmcup);
try tty.flush(); try tty.flush();
tty.state.alt_screen = false; self.state.alt_screen = false;
} }
} }
@ -278,12 +293,12 @@ pub fn render(self: *Vaxis) !void {
// this if we have an update to make. We also need to hide cursor // this if we have an update to make. We also need to hide cursor
// and then reshow it if needed // and then reshow it if needed
_ = try tty.write(ctlseqs.hide_cursor); _ = try tty.write(ctlseqs.hide_cursor);
if (tty.state.alt_screen) if (self.state.alt_screen)
_ = try tty.write(ctlseqs.home) _ = try tty.write(ctlseqs.home)
else { else {
_ = try tty.write("\r"); _ = try tty.write("\r");
var i: usize = 0; var i: usize = 0;
while (i < tty.state.cursor.row) : (i += 1) { while (i < self.state.cursor.row) : (i += 1) {
_ = try tty.write(ctlseqs.ri); _ = try tty.write(ctlseqs.ri);
} }
} }
@ -353,7 +368,7 @@ pub fn render(self: *Vaxis) !void {
// reposition the cursor, if needed // reposition the cursor, if needed
if (reposition) { if (reposition) {
reposition = false; reposition = false;
if (tty.state.alt_screen) if (self.state.alt_screen)
try std.fmt.format(tty.buffered_writer.writer(), ctlseqs.cup, .{ row + 1, col + 1 }) try std.fmt.format(tty.buffered_writer.writer(), ctlseqs.cup, .{ row + 1, col + 1 })
else { else {
if (cursor_pos.row == row) { if (cursor_pos.row == row) {
@ -589,7 +604,7 @@ pub fn render(self: *Vaxis) !void {
cursor_pos.row = row; cursor_pos.row = row;
} }
if (self.screen.cursor_vis) { if (self.screen.cursor_vis) {
if (tty.state.alt_screen) { if (self.state.alt_screen) {
try std.fmt.format( try std.fmt.format(
tty.buffered_writer.writer(), tty.buffered_writer.writer(),
ctlseqs.cup, ctlseqs.cup,
@ -615,12 +630,12 @@ pub fn render(self: *Vaxis) !void {
try std.fmt.format(tty.buffered_writer.writer(), ctlseqs.cuf, .{self.screen.cursor_col}); try std.fmt.format(tty.buffered_writer.writer(), ctlseqs.cuf, .{self.screen.cursor_col});
} }
} }
self.tty.?.state.cursor.row = self.screen.cursor_row; self.state.cursor.row = self.screen.cursor_row;
self.tty.?.state.cursor.col = self.screen.cursor_col; self.state.cursor.col = self.screen.cursor_col;
_ = try tty.write(ctlseqs.show_cursor); _ = try tty.write(ctlseqs.show_cursor);
} else { } else {
self.tty.?.state.cursor.row = cursor_pos.row; self.state.cursor.row = cursor_pos.row;
self.tty.?.state.cursor.col = cursor_pos.col; self.state.cursor.col = cursor_pos.col;
} }
if (self.screen.mouse_shape != self.screen_last.mouse_shape) { if (self.screen.mouse_shape != self.screen_last.mouse_shape) {
try std.fmt.format( try std.fmt.format(
@ -651,7 +666,7 @@ fn enableKittyKeyboard(self: *Vaxis, flags: Key.KittyFlags) !void {
}, },
); );
try tty.flush(); try tty.flush();
tty.state.kitty_keyboard = true; self.state.kitty_keyboard = true;
} }
} }
@ -696,7 +711,7 @@ pub fn setBracketedPaste(self: *Vaxis, enable: bool) !void {
ctlseqs.bp_reset; ctlseqs.bp_reset;
_ = try tty.write(seq); _ = try tty.write(seq);
try tty.flush(); try tty.flush();
tty.state.bracketed_paste = enable; self.state.bracketed_paste = enable;
} }
} }
@ -709,10 +724,10 @@ pub fn setMouseShape(self: *Vaxis, shape: Shape) void {
pub fn setMouseMode(self: *Vaxis, enable: bool) !void { pub fn setMouseMode(self: *Vaxis, enable: bool) !void {
if (self.tty) |*tty| { if (self.tty) |*tty| {
if (enable) { if (enable) {
tty.state.mouse = true; self.state.mouse = true;
if (self.caps.sgr_pixels) { if (self.caps.sgr_pixels) {
log.debug("enabling mouse mode: pixel coordinates", .{}); log.debug("enabling mouse mode: pixel coordinates", .{});
tty.state.pixel_mouse = true; self.state.pixel_mouse = true;
_ = try tty.write(ctlseqs.mouse_set_pixels); _ = try tty.write(ctlseqs.mouse_set_pixels);
} else { } else {
log.debug("enabling mouse mode: cell coordinates", .{}); log.debug("enabling mouse mode: cell coordinates", .{});
@ -728,8 +743,7 @@ pub fn setMouseMode(self: *Vaxis, enable: bool) !void {
/// Translate pixel mouse coordinates to cell + offset /// Translate pixel mouse coordinates to cell + offset
pub fn translateMouse(self: Vaxis, mouse: Mouse) Mouse { pub fn translateMouse(self: Vaxis, mouse: Mouse) Mouse {
var result = mouse; var result = mouse;
const tty = self.tty orelse return result; if (self.state.pixel_mouse) {
if (tty.state.pixel_mouse) {
std.debug.assert(mouse.xoffset == 0); std.debug.assert(mouse.xoffset == 0);
std.debug.assert(mouse.yoffset == 0); std.debug.assert(mouse.yoffset == 0);
const xpos = mouse.col; const xpos = mouse.col;
@ -884,5 +898,5 @@ pub fn subscribeToColorSchemeUpdates(self: Vaxis) !void {
_ = try tty.write(ctlseqs.color_scheme_request); _ = try tty.write(ctlseqs.color_scheme_request);
_ = try tty.write(ctlseqs.color_scheme_set); _ = try tty.write(ctlseqs.color_scheme_set);
try tty.flush(); try tty.flush();
tty.state.color_scheme_updates = true; self.state.color_scheme_updates = true;
} }