renderer: handle normal non-osc8 links with new render state

This commit is contained in:
Mitchell Hashimoto
2025-11-20 05:44:18 -10:00
parent fa26e9a384
commit cd00a8a2ab
3 changed files with 250 additions and 530 deletions

View File

@@ -1069,14 +1069,15 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
// Data we extract out of the critical area.
const Critical = struct {
osc8_links: terminal.RenderState.CellSet,
links: terminal.RenderState.CellSet,
mouse: renderer.State.Mouse,
preedit: ?renderer.State.Preedit,
cursor_style: ?renderer.CursorStyle,
scrollbar: terminal.Scrollbar,
};
// Update all our data as tightly as possible within the mutex.
const critical: Critical = critical: {
var critical: Critical = critical: {
// const start = try std.time.Instant.now();
// const start_micro = std.time.microTimestamp();
// defer {
@@ -1135,7 +1136,7 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
// Get our OSC8 links we're hovering if we have a mouse.
// This requires terminal state because of URLs.
const osc8_links: terminal.RenderState.CellSet = osc8: {
const links: terminal.RenderState.CellSet = osc8: {
// If our mouse isn't hovering, we have no links.
const vp = state.mouse.point orelse break :osc8 .empty;
@@ -1153,18 +1154,31 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
};
break :critical .{
.osc8_links = osc8_links,
.links = links,
.mouse = state.mouse,
.preedit = preedit,
.cursor_style = cursor_style,
.scrollbar = scrollbar,
};
};
// Outside the critical area we can update our links to contain
// our regex results.
self.config.links.renderCellMap(
arena_alloc,
&critical.links,
&self.terminal_state,
state.mouse.point,
state.mouse.mods,
) catch |err| {
log.warn("error searching for regex links err={}", .{err});
};
// Build our GPU cells
try self.rebuildCells(
critical.preedit,
critical.cursor_style,
&critical.osc8_links,
&critical.links,
);
// Notify our shaper we're done for the frame. For some shapers,
@@ -2248,7 +2262,7 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
self: *Self,
preedit: ?renderer.State.Preedit,
cursor_style_: ?renderer.CursorStyle,
osc8_links: *const terminal.RenderState.CellSet,
links: *const terminal.RenderState.CellSet,
) !void {
const state: *terminal.RenderState = &self.terminal_state;
defer state.redraw = false;
@@ -2264,15 +2278,6 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
// std.log.warn("[rebuildCells time] {}\t{}", .{start_micro, end.since(start) / std.time.ns_per_us});
// }
// TODO: renderstate
// Create our match set for the links.
// var link_match_set: link.MatchSet = if (mouse.point) |mouse_pt| try self.config.links.matchSet(
// arena_alloc,
// screen,
// mouse_pt,
// mouse.mods,
// ) else .{};
// Determine our x/y range for preedit. We don't want to render anything
// here because we will render the preedit separately.
const preedit_range: ?struct {
@@ -2647,9 +2652,7 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
// an underline, in which case use a double underline to
// distinguish them.
const underline: terminal.Attribute.Underline = underline: {
// TODO: renderstate regex links
if (osc8_links.contains(.{
if (links.contains(.{
.x = @intCast(x),
.y = @intCast(y),
})) {