vaxis: add sync and refresh
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
This commit is contained in:
parent
5d8f78ccd2
commit
59470f18e8
3 changed files with 50 additions and 17 deletions
|
@ -34,6 +34,8 @@ pub fn main() !void {
|
||||||
var text_input = TextInput.init(alloc);
|
var text_input = TextInput.init(alloc);
|
||||||
defer text_input.deinit();
|
defer text_input.deinit();
|
||||||
|
|
||||||
|
try vx.queryTerminal();
|
||||||
|
|
||||||
// The main event loop. Vaxis provides a thread safe, blocking, buffered
|
// The main event loop. Vaxis provides a thread safe, blocking, buffered
|
||||||
// queue which can serve as the primary event queue for an application
|
// queue which can serve as the primary event queue for an application
|
||||||
outer: while (true) {
|
outer: while (true) {
|
||||||
|
@ -49,9 +51,12 @@ pub fn main() !void {
|
||||||
else => color_idx + 1,
|
else => color_idx + 1,
|
||||||
};
|
};
|
||||||
try text_input.update(.{ .key_press = key });
|
try text_input.update(.{ .key_press = key });
|
||||||
if (key.codepoint == 'c' and key.mods.ctrl) {
|
if (key.matches('c', .{ .ctrl = true })) {
|
||||||
break :outer;
|
break :outer;
|
||||||
}
|
}
|
||||||
|
if (key.matches('l', .{ .ctrl = true })) {
|
||||||
|
vx.queueRefresh();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
.winsize => |ws| {
|
.winsize => |ws| {
|
||||||
try vx.resize(alloc, ws);
|
try vx.resize(alloc, ws);
|
||||||
|
|
|
@ -10,6 +10,10 @@ pub const csi_u_query = "\x1b[?u";
|
||||||
pub const kitty_graphics_query = "\x1b_Gi=1,a=q\x1b\\";
|
pub const kitty_graphics_query = "\x1b_Gi=1,a=q\x1b\\";
|
||||||
pub const sixel_geometry_query = "\x1b[?2;1;0S";
|
pub const sixel_geometry_query = "\x1b[?2;1;0S";
|
||||||
|
|
||||||
|
// sync
|
||||||
|
pub const sync_set = "\x1b[?2026h";
|
||||||
|
pub const sync_reset = "\x1b[?2026l";
|
||||||
|
|
||||||
// Key encoding
|
// Key encoding
|
||||||
pub const csi_u_push = "\x1b[>{d}u";
|
pub const csi_u_push = "\x1b[>{d}u";
|
||||||
pub const csi_u_pop = "\x1b[<u";
|
pub const csi_u_pop = "\x1b[<u";
|
||||||
|
|
|
@ -36,13 +36,18 @@ pub fn Vaxis(comptime T: type) type {
|
||||||
|
|
||||||
tty: ?Tty,
|
tty: ?Tty,
|
||||||
|
|
||||||
|
/// the screen we write to
|
||||||
screen: Screen,
|
screen: Screen,
|
||||||
// The last screen we drew. We keep this so we can efficiently update on
|
/// The last screen we drew. We keep this so we can efficiently update on
|
||||||
// the next render
|
/// the next render
|
||||||
screen_last: InternalScreen = undefined,
|
screen_last: InternalScreen = undefined,
|
||||||
|
|
||||||
|
/// alt_screen state. We track so we can exit on deinit
|
||||||
alt_screen: bool,
|
alt_screen: bool,
|
||||||
|
|
||||||
|
/// if we should redraw the entire screen on the next render
|
||||||
|
refresh: bool = false,
|
||||||
|
|
||||||
// statistics
|
// statistics
|
||||||
renders: usize = 0,
|
renders: usize = 0,
|
||||||
render_dur: i128 = 0,
|
render_dur: i128 = 0,
|
||||||
|
@ -161,26 +166,37 @@ pub fn Vaxis(comptime T: type) type {
|
||||||
var tty = self.tty orelse return;
|
var tty = self.tty orelse return;
|
||||||
|
|
||||||
const colorterm = std.os.getenv("COLORTERM") orelse "";
|
const colorterm = std.os.getenv("COLORTERM") orelse "";
|
||||||
if (std.mem.eql(u8, colorterm, "truecolor" or
|
if (std.mem.eql(u8, colorterm, "truecolor") or
|
||||||
std.mem.eql(u8, colorterm, "24bit")))
|
std.mem.eql(u8, colorterm, "24bit"))
|
||||||
{
|
{
|
||||||
// TODO: Notify rgb support
|
// TODO: Notify rgb support
|
||||||
}
|
}
|
||||||
|
|
||||||
const writer = tty.buffered_writer.writer();
|
// TODO: decide if we actually want to query for focus and sync. It
|
||||||
_ = try writer.write(ctlseqs.decrqm_focus);
|
// doesn't hurt to blindly use them
|
||||||
_ = try writer.write(ctlseqs.decrqm_sync);
|
// _ = try tty.write(ctlseqs.decrqm_focus);
|
||||||
_ = try writer.write(ctlseqs.decrqm_unicode);
|
// _ = try tty.write(ctlseqs.decrqm_sync);
|
||||||
_ = try writer.write(ctlseqs.decrqm_color_theme);
|
_ = try tty.write(ctlseqs.decrqm_unicode);
|
||||||
_ = try writer.write(ctlseqs.xtversion);
|
_ = try tty.write(ctlseqs.decrqm_color_theme);
|
||||||
_ = try writer.write(ctlseqs.csi_u_query);
|
// TODO: XTVERSION has a DCS response. uncomment when we can parse
|
||||||
_ = try writer.write(ctlseqs.kitty_graphics_query);
|
// that
|
||||||
_ = try writer.write(ctlseqs.sixel_geometry_query);
|
// _ = try tty.write(ctlseqs.xtversion);
|
||||||
|
_ = try tty.write(ctlseqs.csi_u_query);
|
||||||
|
// TODO: KITTY_GRAPHICS has an APC response. uncomment when we can
|
||||||
|
// parse that
|
||||||
|
// that
|
||||||
|
// _ = try tty.write(ctlseqs.kitty_graphics_query);
|
||||||
|
_ = try tty.write(ctlseqs.sixel_geometry_query);
|
||||||
|
|
||||||
// TODO: XTGETTCAP queries ("RGB", "Smulx")
|
// TODO: XTGETTCAP queries ("RGB", "Smulx")
|
||||||
|
|
||||||
_ = try writer.write(ctlseqs.primary_device_attrs);
|
_ = try tty.write(ctlseqs.primary_device_attrs);
|
||||||
try writer.flush();
|
try tty.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
// the next render call will refresh the entire screen
|
||||||
|
pub fn queueRefresh(self: *Self) void {
|
||||||
|
self.refresh = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// draws the screen to the terminal
|
/// draws the screen to the terminal
|
||||||
|
@ -192,8 +208,16 @@ pub fn Vaxis(comptime T: type) type {
|
||||||
self.render_dur += std.time.microTimestamp() - timer_start;
|
self.render_dur += std.time.microTimestamp() - timer_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defer self.refresh = false;
|
||||||
defer tty.flush() catch {};
|
defer tty.flush() catch {};
|
||||||
|
|
||||||
|
// Set up sync before we write anything
|
||||||
|
// TODO: optimize sync so we only sync _when we have changes_. This
|
||||||
|
// requires a smarter buffered writer, we'll probably have to write
|
||||||
|
// our own
|
||||||
|
_ = try tty.write(ctlseqs.sync_set);
|
||||||
|
defer _ = tty.write(ctlseqs.sync_reset) catch {};
|
||||||
|
|
||||||
// Send the cursor to 0,0
|
// Send the cursor to 0,0
|
||||||
// TODO: this needs to move after we optimize writes. We only do
|
// TODO: this needs to move after we optimize writes. We only do
|
||||||
// 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
|
||||||
|
@ -218,7 +242,7 @@ pub fn Vaxis(comptime T: type) type {
|
||||||
}
|
}
|
||||||
// If cell is the same as our last frame, we don't need to do
|
// If cell is the same as our last frame, we don't need to do
|
||||||
// anything
|
// anything
|
||||||
if (self.screen_last.buf[i].eql(cell)) {
|
if (!self.refresh and self.screen_last.buf[i].eql(cell)) {
|
||||||
reposition = true;
|
reposition = true;
|
||||||
// Close any osc8 sequence we might be in before
|
// Close any osc8 sequence we might be in before
|
||||||
// repositioning
|
// repositioning
|
||||||
|
|
Loading…
Reference in a new issue