implement cursor reset when data comes in pty

This commit is contained in:
Mitchell Hashimoto
2022-11-05 19:26:42 -07:00
parent aa98e3ca3a
commit 746858cea6
7 changed files with 37 additions and 15 deletions

View File

@ -367,6 +367,7 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo
.config = config,
.renderer_state = &self.renderer_state,
.renderer_wakeup = render_thread.wakeup,
.renderer_mailbox = render_thread.mailbox,
});
errdefer io.deinit();

View File

@ -300,8 +300,8 @@ pub fn setFocus(self: *Metal, focus: bool) !void {
}
/// Called to toggle the blink state of the cursor
pub fn blinkCursor(self: *Metal) void {
self.cursor_visible = !self.cursor_visible;
pub fn blinkCursor(self: *Metal, reset: bool) void {
self.cursor_visible = reset or !self.cursor_visible;
}
/// The primary render callback that is completely thread-safe.

View File

@ -442,8 +442,8 @@ pub fn setFocus(self: *OpenGL, focus: bool) !void {
}
/// Called to toggle the blink state of the cursor
pub fn blinkCursor(self: *OpenGL) void {
self.cursor_visible = !self.cursor_visible;
pub fn blinkCursor(self: *OpenGL, reset: bool) void {
self.cursor_visible = reset or !self.cursor_visible;
}
/// The primary render callback that is completely thread-safe.

View File

@ -15,7 +15,7 @@ const log = std.log.scoped(.renderer_thread);
/// The type used for sending messages to the IO thread. For now this is
/// hardcoded with a capacity. We can make this a comptime parameter in
/// the future if we want it configurable.
const Mailbox = BlockingQueue(renderer.Message, 64);
pub const Mailbox = BlockingQueue(renderer.Message, 64);
/// The main event loop for the application. The user data of this loop
/// is always the allocator used to create the loop. This is a convenience
@ -227,14 +227,22 @@ fn drainMailbox(self: *Thread) !void {
// If we're focused, we immediately show the cursor again
// and then restart the timer.
if (!try self.cursor_h.isActive()) {
self.renderer.blinkCursor(true);
try self.cursor_h.start(
cursorTimerCallback,
0,
self.cursor_h.getRepeat(),
self.cursor_h.getRepeat(),
);
}
}
},
.reset_cursor_blink => {
self.renderer.blinkCursor(true);
if (try self.cursor_h.isActive()) {
_ = try self.cursor_h.again();
}
},
}
}
}
@ -278,7 +286,7 @@ fn cursorTimerCallback(h: *libuv.Timer) void {
return;
};
t.renderer.blinkCursor();
t.renderer.blinkCursor(false);
t.wakeup.send() catch {};
}

View File

@ -8,4 +8,8 @@ pub const Message = union(enum) {
/// rendering within. This is only sent when a change is detected so
/// the renderer is expected to handle all of these.
focus: bool,
/// Reset the cursor blink by immediately showing the cursor then
/// restarting the timer.
reset_cursor_blink: void,
};

View File

@ -40,6 +40,9 @@ renderer_state: *renderer.State,
/// a repaint should happen.
renderer_wakeup: libuv.Async,
/// The mailbox for notifying the renderer of things.
renderer_mailbox: *renderer.Thread.Mailbox,
/// The cached grid size whenever a resize is called.
grid_size: renderer.GridSize,
@ -103,6 +106,7 @@ pub fn init(alloc: Allocator, opts: termio.Options) !Exec {
.terminal_stream = undefined,
.renderer_state = opts.renderer_state,
.renderer_wakeup = opts.renderer_wakeup,
.renderer_mailbox = opts.renderer_mailbox,
.grid_size = opts.grid_size,
.data = null,
};
@ -141,6 +145,7 @@ pub fn threadEnter(self: *Exec, loop: libuv.Loop) !ThreadData {
.read_arena = std.heap.ArenaAllocator.init(alloc),
.renderer_state = self.renderer_state,
.renderer_wakeup = self.renderer_wakeup,
.renderer_mailbox = self.renderer_mailbox,
.data_stream = stream,
.terminal_stream = .{
.handler = .{
@ -238,6 +243,9 @@ const EventData = struct {
/// a repaint should happen.
renderer_wakeup: libuv.Async,
/// The mailbox for notifying the renderer of things.
renderer_mailbox: *renderer.Thread.Mailbox,
/// The data stream is the main IO for the pty.
data_stream: libuv.Tty,
@ -334,18 +342,16 @@ fn ttyRead(t: *libuv.Tty, n: isize, buf: []const u8) void {
return;
};
// Whenever a character is typed, we ensure the cursor is in the
// non-blink state so it is rendered if visible.
_ = ev.renderer_mailbox.push(.{
.reset_cursor_blink = {},
}, .{ .forever = {} });
// We are modifying terminal state from here on out
ev.renderer_state.mutex.lock();
defer ev.renderer_state.mutex.unlock();
// Whenever a character is typed, we ensure the cursor is in the
// non-blink state so it is rendered if visible.
//ev.renderer_state.cursor.blink = false;
// TODO
// if (win.terminal_cursor.timer.isActive() catch false) {
// _ = win.terminal_cursor.timer.again() catch null;
// }
// Schedule a render
ev.queueRender() catch unreachable;

View File

@ -22,3 +22,6 @@ renderer_state: *renderer.State,
/// A handle to wake up the renderer. This hints to the renderer that that
/// a repaint should happen.
renderer_wakeup: libuv.Async,
/// The mailbox for renderer messages.
renderer_mailbox: *renderer.Thread.Mailbox,