From 1a7b9f7465302ed55511b79535208960807cc6f1 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 4 Nov 2022 20:47:01 -0700 Subject: [PATCH] termio: clear selection --- src/Window.zig | 8 +++++++- src/termio/Exec.zig | 11 +++++++++++ src/termio/Thread.zig | 25 +++++++++++++++++++------ src/termio/message.zig | 4 ++-- 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/src/Window.zig b/src/Window.zig index ded771243..3930f21ba 100644 --- a/src/Window.zig +++ b/src/Window.zig @@ -810,7 +810,13 @@ fn charCallback(window: glfw.Window, codepoint: u21) void { return; } - // Anytime is character is created, we have to clear the selection + // Anytime a char is created, we have to clear the selection if there is one. + _ = win.io_thread.mailbox.push(.{ + .clear_selection = {}, + }, .{ .forever = {} }); + + // TODO: the stuff below goes away with IO thread + if (win.terminal.selection != null) { win.terminal.selection = null; win.queueRender() catch |err| diff --git a/src/termio/Exec.zig b/src/termio/Exec.zig index 6abace770..8762cc56f 100644 --- a/src/termio/Exec.zig +++ b/src/termio/Exec.zig @@ -188,6 +188,17 @@ pub fn resize( } } +pub fn clearSelection(self: *Exec) !void { + // We don't need a lock to read because nothing else can possibly write + // as we're looking at this. + if (self.terminal.selection != null) { + // We need to lock so we can write because other things might be reading. + self.renderer_state.mutex.lock(); + defer self.renderer_state.mutex.unlock(); + self.terminal.selection = null; + } +} + const ThreadData = struct { /// Allocator used for the event data alloc: Allocator, diff --git a/src/termio/Thread.zig b/src/termio/Thread.zig index 12949edcb..d0dd76cfc 100644 --- a/src/termio/Thread.zig +++ b/src/termio/Thread.zig @@ -150,15 +150,28 @@ fn drainMailbox(self: *Thread) !void { // This holds the mailbox lock for the duration of the drain. The // expectation is that all our message handlers will be non-blocking // ENOUGH to not mess up throughput on producers. - var drain = self.mailbox.drain(); - defer drain.deinit(); + var redraw: bool = false; + { + var drain = self.mailbox.drain(); + defer drain.deinit(); - while (drain.next()) |message| { - log.debug("mailbox message={}", .{message}); - switch (message) { - .resize => |v| try self.impl.resize(v.grid_size, v.screen_size), + while (drain.next()) |message| { + // If we have a message we always redraw + redraw = true; + + log.debug("mailbox message={}", .{message}); + switch (message) { + .resize => |v| try self.impl.resize(v.grid_size, v.screen_size), + .clear_selection => try self.impl.clearSelection(), + } } } + + // Trigger a redraw after we've drained so we don't waste cyces + // messaging a redraw. + if (redraw) { + try self.impl.renderer_wakeup.send(); + } } fn wakeupCallback(h: *libuv.Async) void { diff --git a/src/termio/message.zig b/src/termio/message.zig index b7f1b6cdc..966e5ccb6 100644 --- a/src/termio/message.zig +++ b/src/termio/message.zig @@ -9,8 +9,8 @@ pub const IO = union(enum) { screen_size: renderer.ScreenSize, }, - // /// Clear the selection - // clear_selection: void, + /// Clear the selection + clear_selection: void, // // /// Scroll the viewport // scroll_viewport: terminal.Terminal.ScrollViewport,