add(input): mouse support
All checks were successful
Zig Project Action / Lint, Spell-check and test zig project (push) Successful in 46s
All checks were successful
Zig Project Action / Lint, Spell-check and test zig project (push) Successful in 46s
This commit is contained in:
49
src/app.zig
49
src/app.zig
@@ -7,6 +7,7 @@ const mergeTaggedUnions = event.mergeTaggedUnions;
|
||||
const isTaggedUnion = event.isTaggedUnion;
|
||||
|
||||
const key = @import("key.zig");
|
||||
const Mouse = @import("mouse.zig").Mouse;
|
||||
const Key = key.Key;
|
||||
const Size = @import("size.zig").Size;
|
||||
const Queue = @import("queue.zig").Queue;
|
||||
@@ -95,6 +96,7 @@ pub fn App(comptime E: type) type {
|
||||
try terminal.saveScreen();
|
||||
try terminal.enterAltScreen();
|
||||
try terminal.hideCursor();
|
||||
try terminal.enableMouseSupport();
|
||||
|
||||
// send initial size afterwards
|
||||
const size = terminal.getTerminalSize();
|
||||
@@ -104,6 +106,7 @@ pub fn App(comptime E: type) type {
|
||||
|
||||
pub fn interrupt(this: *@This()) !void {
|
||||
this.quit_event.set();
|
||||
try terminal.disableMouseSupport();
|
||||
try terminal.exitAltScreen();
|
||||
try terminal.restoreScreen();
|
||||
if (this.thread) |thread| {
|
||||
@@ -115,9 +118,10 @@ pub fn App(comptime E: type) type {
|
||||
pub fn stop(this: *@This()) !void {
|
||||
try this.interrupt();
|
||||
if (this.termios) |*termios| {
|
||||
try terminal.disableRawMode(termios);
|
||||
try terminal.disableMouseSupport();
|
||||
try terminal.showCursor();
|
||||
try terminal.exitAltScreen();
|
||||
try terminal.disableRawMode(termios);
|
||||
try terminal.restoreScreen();
|
||||
}
|
||||
this.termios = null;
|
||||
@@ -171,6 +175,7 @@ pub fn App(comptime E: type) type {
|
||||
// FIX: I still think that there is a race condition (I'm just waiting 'long' enough)
|
||||
this.quit_event.timedWait(20 * std.time.ns_per_ms) catch {
|
||||
const read_bytes = try terminal.read(buf[0..]);
|
||||
// TODO: `break` should not terminate the reading of the user inputs, but instead only the received faulty input!
|
||||
// escape key presses
|
||||
if (buf[0] == 0x1b and read_bytes > 1) {
|
||||
switch (buf[1]) {
|
||||
@@ -267,7 +272,47 @@ pub fn App(comptime E: type) type {
|
||||
},
|
||||
'I' => this.postEvent(.{ .focus = true }),
|
||||
'O' => this.postEvent(.{ .focus = false }),
|
||||
// 'M', 'm' => return parseMouse(sequence), // TODO: parse mouse inputs
|
||||
'M', 'm' => {
|
||||
std.debug.assert(sequence.len >= 4);
|
||||
if (sequence[2] != '<') break;
|
||||
|
||||
const delim1 = std.mem.indexOfScalarPos(u8, sequence, 3, ';') orelse break;
|
||||
const button_mask = std.fmt.parseUnsigned(u16, sequence[3..delim1], 10) catch break;
|
||||
const delim2 = std.mem.indexOfScalarPos(u8, sequence, delim1 + 1, ';') orelse break;
|
||||
const px = std.fmt.parseUnsigned(u16, sequence[delim1 + 1 .. delim2], 10) catch break;
|
||||
const py = std.fmt.parseUnsigned(u16, sequence[delim2 + 1 .. sequence.len - 1], 10) catch break;
|
||||
|
||||
const mouse_bits = packed struct {
|
||||
const motion: u8 = 0b00100000;
|
||||
const buttons: u8 = 0b11000011;
|
||||
const shift: u8 = 0b00000100;
|
||||
const alt: u8 = 0b00001000;
|
||||
const ctrl: u8 = 0b00010000;
|
||||
};
|
||||
|
||||
const button: Mouse.Button = @enumFromInt(button_mask & mouse_bits.buttons);
|
||||
const motion = button_mask & mouse_bits.motion > 0;
|
||||
// const shift = button_mask & mouse_bits.shift > 0;
|
||||
// const alt = button_mask & mouse_bits.alt > 0;
|
||||
// const ctrl = button_mask & mouse_bits.ctrl > 0;
|
||||
|
||||
const mouse = Mouse{
|
||||
.button = button,
|
||||
.col = px -| 1,
|
||||
.row = py -| 1,
|
||||
.kind = blk: {
|
||||
if (motion and button != Mouse.Button.none) {
|
||||
break :blk .drag;
|
||||
}
|
||||
if (motion and button == Mouse.Button.none) {
|
||||
break :blk .motion;
|
||||
}
|
||||
if (sequence[sequence.len - 1] == 'm') break :blk .release;
|
||||
break :blk .press;
|
||||
},
|
||||
};
|
||||
this.postEvent(.{ .mouse = mouse });
|
||||
},
|
||||
'c' => {
|
||||
// Primary DA (CSI ? Pm c)
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user