Add mouse cursor shape, visibility, and link hover URL support#32
Add mouse cursor shape, visibility, and link hover URL support#32
Conversation
Handle GHOSTTY_ACTION_MOUSE_SHAPE, MOUSE_VISIBILITY, and MOUSE_OVER_LINK actions from libghostty. Cursor shape changes via resetCursorRects/NSCursor mapping (15 shapes with macOS 15+ columnResize/rowResize fallbacks), cursor hide/show via setHiddenUntilMouseMoves, and hovered link URLs surfaced as a dual-pill tooltip overlay in PaneLeafView that toggles sides to avoid the cursor.
📝 WalkthroughWalkthroughAdds hover-URL propagation and tooltip rendering plus cursor-shape support: a new onHoverUrlChange callback is threaded through GhosttyRuntime → GhosttyTerminalView, PaneLeafView consumes it to show a tooltip, and LibghosttySurfaceView maps mouse actions to cursor updates and hover events. Changes
Sequence DiagramsequenceDiagram
participant User
participant Ghostty as Ghostty Surface
participant Runtime as GhosttyRuntime
participant Terminal as GhosttyTerminalView
participant Pane as PaneLeafView
participant UI as Tooltip
User->>Ghostty: Hover mouse over link
Ghostty->>Runtime: Emit MOUSE_OVER_LINK (with URL) / MOUSE_SHAPE / MOUSE_VISIBILITY
Runtime->>Runtime: Map action -> invoke onHoverUrlChange / setCursorShape / toggle visibility
Runtime->>Terminal: onHoverUrlChange(url)
Terminal->>Pane: Deliver onHoverUrlChange(url)
Pane->>Pane: Set hoverUrl / isHoveringURLLeft state
Pane->>UI: Render tooltip overlay
UI->>User: Display hovered URL tooltip
Possibly related PRs
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
📝 Coding Plan
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@Sources/Shellraiser/Features/WorkspaceDetail/PaneLeafView.swift`:
- Around line 310-351: The hit-testing disablement on the ZStack is causing the
tooltip to get stuck because when isHoveringURLLeft == true the entire ZStack
ignores pointer events so the right-side Text's onHover can't get the exit
event; remove or change the .allowsHitTesting(!isHoveringURLLeft) usage in
PaneLeafView (the ZStack that contains hoverUrl and the two HStacks) so hit
testing remains enabled (e.g., remove the modifier or set
allowsHitTesting(true)), or instead apply hit-testing control only to the
non-interactive background layer rather than the whole ZStack; if the sticky
behavior is intentional, add a short doc comment next to isHoveringURLLeft
explaining this design.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: dc8df599-1fa6-475e-a121-215d3975b679
📒 Files selected for processing (4)
Sources/Shellraiser/Features/Terminal/GhosttyTerminalView.swiftSources/Shellraiser/Features/WorkspaceDetail/PaneLeafView.swiftSources/Shellraiser/Infrastructure/Ghostty/GhosttyRuntime.swiftSources/Shellraiser/Infrastructure/Ghostty/LibghosttySurfaceView.swift
Move .allowsHitTesting(false) from ZStack to the right-side HStack only, so the left-side HStack's onHover can still receive exit events when the cursor moves away.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
Sources/Shellraiser/Features/WorkspaceDetail/PaneLeafView.swift (1)
311-351: Refactor duplicated tooltip UI into a small helper view.The left/right tooltip branches duplicate most modifiers. Extracting a focused helper will keep
panelBodyeasier to read and maintain.As per coding guidelines, "Prefer small, composable methods and keep methods focused and readable".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Sources/Shellraiser/Features/WorkspaceDetail/PaneLeafView.swift` around lines 311 - 351, The tooltip branches in PaneLeafView's panelBody duplicate the same Text + padding + background + modifiers for left/right; extract a small reusable View (e.g., TooltipBubble or HoverURLView) that takes hoverUrl: String, cornerRadii: CornerRadii/Bool (or isLeft: Bool), and an optional onHover handler, move the shared Text(...) modifiers and UnevenRoundedRectangle background into that helper, then replace the two HStack/VStack blocks with instances of the new HoverURLView wired to isHoveringURLLeft and .onHover to preserve existing behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@Sources/Shellraiser/Features/WorkspaceDetail/PaneLeafView.swift`:
- Around line 311-351: The tooltip branches in PaneLeafView's panelBody
duplicate the same Text + padding + background + modifiers for left/right;
extract a small reusable View (e.g., TooltipBubble or HoverURLView) that takes
hoverUrl: String, cornerRadii: CornerRadii/Bool (or isLeft: Bool), and an
optional onHover handler, move the shared Text(...) modifiers and
UnevenRoundedRectangle background into that helper, then replace the two
HStack/VStack blocks with instances of the new HoverURLView wired to
isHoveringURLLeft and .onHover to preserve existing behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: eeb75e5e-24de-4330-b5a8-11a5feb7fa3b
📒 Files selected for processing (1)
Sources/Shellraiser/Features/WorkspaceDetail/PaneLeafView.swift
Handle GHOSTTY_ACTION_MOUSE_SHAPE, MOUSE_VISIBILITY, and MOUSE_OVER_LINK actions from libghostty. Cursor shape changes via resetCursorRects/NSCursor mapping (15 shapes with macOS 15+ columnResize/rowResize fallbacks), cursor hide/show via setHiddenUntilMouseMoves, and hovered link URLs surfaced as a dual-pill tooltip overlay in PaneLeafView that toggles sides to avoid the cursor.
Summary by CodeRabbit