diff --git a/src/Surface.zig b/src/Surface.zig index 286de2625..7df990ad4 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -2825,10 +2825,7 @@ pub fn cursorPosCallback( if (try self.linkAtPos(pos)) |_| { self.renderer_state.mouse.point = pos_vp; self.mouse.over_link = true; - // Mark the new link's row as dirty. - if (self.renderer_state.terminal.screen.pages.pin(.{ .viewport = pos_vp })) |pin| { - pin.markDirty(); - } + self.renderer_state.terminal.screen.dirty.hyperlink_hover = true; try self.rt_surface.setMouseShape(.pointer); try self.queueRender(); } else if (over_link) { diff --git a/src/renderer/Metal.zig b/src/renderer/Metal.zig index fc5ad382c..e459d36ab 100644 --- a/src/renderer/Metal.zig +++ b/src/renderer/Metal.zig @@ -2005,7 +2005,7 @@ fn rebuildCells( if (self.updateCell( screen, cell, - if (link_match_set.orderedContains(screen, cell)) + if (link_match_set.contains(screen, cell)) .single else null, diff --git a/src/renderer/link.zig b/src/renderer/link.zig index 417fcfcf9..67c1b0d28 100644 --- a/src/renderer/link.zig +++ b/src/renderer/link.zig @@ -274,6 +274,21 @@ pub const MatchSet = struct { alloc.free(self.matches); } + /// Checks if the matchset contains the given pin. This is slower than + /// orderedContains but is stateless and more flexible since it doesn't + /// require the points to be in order. + pub fn contains( + self: *MatchSet, + screen: *const Screen, + pin: terminal.Pin, + ) bool { + for (self.matches) |sel| { + if (sel.contains(screen, pin)) return true; + } + + return false; + } + /// Checks if the matchset contains the given pt. The points must be /// given in left-to-right top-to-bottom order. This is a stateful /// operation and giving a point out of order can cause invalid diff --git a/src/terminal/Screen.zig b/src/terminal/Screen.zig index 885412768..593fcc86e 100644 --- a/src/terminal/Screen.zig +++ b/src/terminal/Screen.zig @@ -72,6 +72,10 @@ pub const Dirty = packed struct { /// Set when the selection is set or unset, regardless of if the /// selection is changed or not. selection: bool = false, + + /// When an OSC8 hyperlink is hovered, we set the full screen as dirty + /// because links can span multiple lines. + hyperlink_hover: bool = false, }; /// The cursor position.