vaxis: mode cleanup, initial mouse implementation

Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
This commit is contained in:
Tim Culverhouse 2024-01-24 18:36:45 -06:00
parent 85060b001f
commit 9950c9eac5
3 changed files with 50 additions and 15 deletions

View file

@ -13,6 +13,7 @@ const Event = union(enum) {
key_press: vaxis.Key, key_press: vaxis.Key,
winsize: vaxis.Winsize, winsize: vaxis.Winsize,
focus_in, focus_in,
focus_out,
foo: u8, foo: u8,
}; };
@ -53,6 +54,8 @@ pub fn main() !void {
// _always_ be called, but is left to the application to decide when // _always_ be called, but is left to the application to decide when
try vx.queryTerminal(); try vx.queryTerminal();
try vx.setMouseMode(true);
// 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) {

View file

@ -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";
// mouse
pub const mouse_set = "\x1b[?1003;1004;1006h";
pub const mouse_reset = "\x1b[?1003;1004;1006l";
// sync // sync
pub const sync_set = "\x1b[?2026h"; pub const sync_set = "\x1b[?2026h";
pub const sync_reset = "\x1b[?2026l"; pub const sync_reset = "\x1b[?2026l";

View file

@ -51,11 +51,14 @@ pub fn Vaxis(comptime T: type) type {
/// 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 state: struct {
alt_screen: bool, /// if we are in the alt screen
alt_screen: bool = false,
/// if we have entered kitty keyboard /// if we have entered kitty keyboard
kitty_keyboard: bool = false, kitty_keyboard: bool = false,
bracketed_paste: bool = false,
mouse: bool = false,
} = .{},
caps: Capabilities = .{}, caps: Capabilities = .{},
@ -77,7 +80,6 @@ pub fn Vaxis(comptime T: type) type {
.tty = null, .tty = null,
.screen = .{}, .screen = .{},
.screen_last = .{}, .screen_last = .{},
.alt_screen = false,
}; };
} }
@ -88,10 +90,16 @@ pub fn Vaxis(comptime T: type) type {
pub fn deinit(self: *Self, alloc: ?std.mem.Allocator) void { pub fn deinit(self: *Self, alloc: ?std.mem.Allocator) void {
if (self.tty) |_| { if (self.tty) |_| {
var tty = &self.tty.?; var tty = &self.tty.?;
if (self.kitty_keyboard) { if (self.state.kitty_keyboard) {
_ = tty.write(ctlseqs.csi_u_pop) catch {}; _ = tty.write(ctlseqs.csi_u_pop) catch {};
} }
if (self.alt_screen) { if (self.state.mouse) {
_ = tty.write(ctlseqs.mouse_reset) catch {};
}
if (self.state.bracketed_paste) {
_ = tty.write(ctlseqs.bp_reset) catch {};
}
if (self.state.alt_screen) {
_ = tty.write(ctlseqs.rmcup) catch {}; _ = tty.write(ctlseqs.rmcup) catch {};
} }
tty.flush() catch {}; tty.flush() catch {};
@ -165,20 +173,20 @@ pub fn Vaxis(comptime T: type) type {
/// enter the alternate screen. The alternate screen will automatically /// enter the alternate screen. The alternate screen will automatically
/// be exited if calling deinit while in the alt screen /// be exited if calling deinit while in the alt screen
pub fn enterAltScreen(self: *Self) !void { pub fn enterAltScreen(self: *Self) !void {
if (self.alt_screen) return; if (self.state.alt_screen) return;
var tty = self.tty orelse return; var tty = self.tty orelse return;
_ = try tty.write(ctlseqs.smcup); _ = try tty.write(ctlseqs.smcup);
try tty.flush(); try tty.flush();
self.alt_screen = true; self.state.alt_screen = true;
} }
/// exit the alternate screen /// exit the alternate screen
pub fn exitAltScreen(self: *Self) !void { pub fn exitAltScreen(self: *Self) !void {
if (!self.alt_screen) return; if (!self.state.alt_screen) return;
var tty = self.tty orelse return; var tty = self.tty orelse return;
_ = try tty.write(ctlseqs.rmcup); _ = try tty.write(ctlseqs.rmcup);
try tty.flush(); try tty.flush();
self.alt_screen = false; self.state.alt_screen = false;
} }
/// write queries to the terminal to determine capabilities. Individual /// write queries to the terminal to determine capabilities. Individual
@ -468,7 +476,7 @@ pub fn Vaxis(comptime T: type) type {
} }
fn enableKittyKeyboard(self: *Self, flags: Key.KittyFlags) !void { fn enableKittyKeyboard(self: *Self, flags: Key.KittyFlags) !void {
self.kitty_keyboard = true; self.state.kitty_keyboard = true;
const flag_int: u5 = @bitCast(flags); const flag_int: u5 = @bitCast(flags);
try std.fmt.format( try std.fmt.format(
self.tty.?.buffered_writer.writer(), self.tty.?.buffered_writer.writer(),
@ -511,9 +519,16 @@ pub fn Vaxis(comptime T: type) type {
// turn bracketed paste on or off. An event will be sent at the // turn bracketed paste on or off. An event will be sent at the
// beginning and end of a detected paste. All keystrokes between these // beginning and end of a detected paste. All keystrokes between these
// events were pasted // events were pasted
pub fn bracketedPaste(self: *Self, enable: bool) !void { pub fn setBracketedPaste(self: *Self, enable: bool) !void {
if (self.tty == null) return; if (self.tty == null) return;
const seq = if (enable) ctlseqs.bp_set else ctlseqs.bp_reset; self.state.bracketed_paste = enable;
const seq = if (enable) {
self.state.bracketed_paste = true;
ctlseqs.bp_set;
} else {
self.state.bracketed_paste = true;
ctlseqs.bp_reset;
};
_ = try self.tty.?.write(seq); _ = try self.tty.?.write(seq);
try self.tty.?.flush(); try self.tty.?.flush();
} }
@ -522,6 +537,19 @@ pub fn Vaxis(comptime T: type) type {
pub fn setMouseShape(self: *Self, shape: Shape) void { pub fn setMouseShape(self: *Self, shape: Shape) void {
self.screen.mouse_shape = shape; self.screen.mouse_shape = shape;
} }
/// turn mouse reporting on or off
pub fn setMouseMode(self: *Self, enable: bool) !void {
var tty = self.tty orelse return;
self.state.mouse = enable;
if (enable) {
_ = try tty.write(ctlseqs.mouse_set);
try tty.flush();
} else {
_ = try tty.write(ctlseqs.mouse_reset);
try tty.flush();
}
}
}; };
} }