vaxis: mode cleanup, initial mouse implementation
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
This commit is contained in:
parent
85060b001f
commit
9950c9eac5
3 changed files with 50 additions and 15 deletions
|
@ -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) {
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue