renderer: receive message with viewport match selections
Doesn't draw yetpull/9687/head
parent
061d157b50
commit
6c8ffb5fc1
|
|
@ -1328,9 +1328,44 @@ fn reportColorScheme(self: *Surface, force: bool) void {
|
|||
}
|
||||
|
||||
fn searchCallback(event: terminal.search.Thread.Event, ud: ?*anyopaque) void {
|
||||
// IMPORTANT: This function is run on the SEARCH THREAD! It is NOT SAFE
|
||||
// to access anything other than values that never change on the surface.
|
||||
// The surface is guaranteed to be valid for the lifetime of the search
|
||||
// thread.
|
||||
const self: *Surface = @ptrCast(@alignCast(ud.?));
|
||||
_ = self;
|
||||
_ = event;
|
||||
self.searchCallback_(event) catch |err| {
|
||||
log.warn("error in search callback err={}", .{err});
|
||||
};
|
||||
}
|
||||
|
||||
fn searchCallback_(
|
||||
self: *Surface,
|
||||
event: terminal.search.Thread.Event,
|
||||
) !void {
|
||||
switch (event) {
|
||||
.viewport_matches => |matches_unowned| {
|
||||
var arena: ArenaAllocator = .init(self.alloc);
|
||||
errdefer arena.deinit();
|
||||
const alloc = arena.allocator();
|
||||
|
||||
const matches = try alloc.dupe(terminal.highlight.Flattened, matches_unowned);
|
||||
for (matches) |*m| m.* = try m.clone(alloc);
|
||||
|
||||
_ = self.renderer_thread.mailbox.push(
|
||||
.{ .search_viewport_matches = .{
|
||||
.arena = arena,
|
||||
.matches = matches,
|
||||
} },
|
||||
.forever,
|
||||
);
|
||||
try self.renderer_thread.wakeup.notify();
|
||||
},
|
||||
|
||||
// Unhandled, so far.
|
||||
.total_matches,
|
||||
.complete,
|
||||
=> {},
|
||||
}
|
||||
}
|
||||
|
||||
/// Call this when modifiers change. This is safe to call even if modifiers
|
||||
|
|
|
|||
|
|
@ -451,6 +451,14 @@ fn drainMailbox(self: *Thread) !void {
|
|||
self.startDrawTimer();
|
||||
},
|
||||
|
||||
.search_viewport_matches => |v| {
|
||||
// Note we don't free the new value because we expect our
|
||||
// allocators to match.
|
||||
if (self.renderer.search_matches) |*m| m.arena.deinit();
|
||||
self.renderer.search_matches = v;
|
||||
self.renderer.search_matches_dirty = true;
|
||||
},
|
||||
|
||||
.inspector => |v| self.flags.has_inspector = v,
|
||||
|
||||
.macos_display_id => |v| {
|
||||
|
|
|
|||
|
|
@ -122,6 +122,16 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
|
|||
scrollbar: terminal.Scrollbar,
|
||||
scrollbar_dirty: bool,
|
||||
|
||||
/// The most recent viewport matches so that we can render search
|
||||
/// matches in the visible frame. This is provided asynchronously
|
||||
/// from the search thread so we have the dirty flag to also note
|
||||
/// if we need to rebuild our cells to include search highlights.
|
||||
///
|
||||
/// Note that the selections MAY BE INVALID (point to PageList nodes
|
||||
/// that do not exist anymore). These must be validated prior to use.
|
||||
search_matches: ?renderer.Message.SearchMatches,
|
||||
search_matches_dirty: bool,
|
||||
|
||||
/// The current set of cells to render. This is rebuilt on every frame
|
||||
/// but we keep this around so that we don't reallocate. Each set of
|
||||
/// cells goes into a separate shader.
|
||||
|
|
@ -672,6 +682,8 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
|
|||
.focused = true,
|
||||
.scrollbar = .zero,
|
||||
.scrollbar_dirty = false,
|
||||
.search_matches = null,
|
||||
.search_matches_dirty = false,
|
||||
|
||||
// Render state
|
||||
.cells = .{},
|
||||
|
|
@ -744,7 +756,7 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
|
|||
|
||||
pub fn deinit(self: *Self) void {
|
||||
self.terminal_state.deinit(self.alloc);
|
||||
|
||||
if (self.search_matches) |*m| m.arena.deinit();
|
||||
self.swap_chain.deinit();
|
||||
|
||||
if (DisplayLink != void) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
const std = @import("std");
|
||||
const assert = @import("../quirks.zig").inlineAssert;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const ArenaAllocator = std.heap.ArenaAllocator;
|
||||
const configpkg = @import("../config.zig");
|
||||
const font = @import("../font/main.zig");
|
||||
const renderer = @import("../renderer.zig");
|
||||
|
|
@ -10,7 +11,7 @@ const terminal = @import("../terminal/main.zig");
|
|||
pub const Message = union(enum) {
|
||||
/// Purposely crash the renderer. This is used for testing and debugging.
|
||||
/// See the "crash" binding action.
|
||||
crash: void,
|
||||
crash,
|
||||
|
||||
/// A change in state in the window focus that this renderer is
|
||||
/// rendering within. This is only sent when a change is detected so
|
||||
|
|
@ -24,7 +25,7 @@ pub const Message = union(enum) {
|
|||
|
||||
/// Reset the cursor blink by immediately showing the cursor then
|
||||
/// restarting the timer.
|
||||
reset_cursor_blink: void,
|
||||
reset_cursor_blink,
|
||||
|
||||
/// Change the font grid. This can happen for any number of reasons
|
||||
/// including a font size change, family change, etc.
|
||||
|
|
@ -52,12 +53,22 @@ pub const Message = union(enum) {
|
|||
impl: *renderer.Renderer.DerivedConfig,
|
||||
},
|
||||
|
||||
/// Matches for the current viewport from the search thread. These happen
|
||||
/// async so they may be off for a frame or two from the actually rendered
|
||||
/// viewport. The renderer must handle this gracefully.
|
||||
search_viewport_matches: SearchMatches,
|
||||
|
||||
/// Activate or deactivate the inspector.
|
||||
inspector: bool,
|
||||
|
||||
/// The macOS display ID has changed for the window.
|
||||
macos_display_id: u32,
|
||||
|
||||
pub const SearchMatches = struct {
|
||||
arena: ArenaAllocator,
|
||||
matches: []const terminal.highlight.Flattened,
|
||||
};
|
||||
|
||||
/// Initialize a change_config message.
|
||||
pub fn initChangeConfig(alloc: Allocator, config: *const configpkg.Config) !Message {
|
||||
const thread_ptr = try alloc.create(renderer.Thread.DerivedConfig);
|
||||
|
|
|
|||
Loading…
Reference in New Issue