Skip to content

fix: open latched link on release with press-time chord + defer-clear latch (#71 follow-up) - #78

Merged
austinywang merged 1 commit into
mainfrom
fix-5128-link-open-latched
Jun 5, 2026
Merged

austinywang merged 1 commit into
mainfrom
fix-5128-link-open-latched

Conversation

@austinywang

@austinywang austinywang commented Jun 5, 2026 •

Copy link
Copy Markdown

Two review follow-ups (codex) on the link-under-mouse-reporting work (#71/#74/#75/#76/#77, manaflow-ai/cmux#5128), unifying the link-click decision so the open path and the report-suppression path use the same press-time chord.

  1. Swallowed click (P2). When the ctrl/super modifier was released before the left button, the report was still suppressed (latched at press), but processLinks re-derived linkAtPos from the now-empty live mods — so the link no longer matched and the click was swallowed (link never opened, nothing reached the program). linkAtPos now uses the latched chord while link_click_active is set, and the release path attempts processLinks whenever the click is latched (not only while over_link is still set). The latched click opens its link instead of being dropped.

  2. Stale latch (P3). The unconditional reset was placed after the report block, but the successful-link (if (processed) return true) and prompt-click branches return early and never reached it. The latch is now cleared with a function-level defer, so it resets on every left-release return path. The press remains the only setter.

Net: a single press-time decision drives press/drag/release suppression and link opening, consistently — closing the modifier-timing edge cases. zig fmt/ast-check clean; behavior is integration-level, verified by cmux dogfood.


AI disclosure (per AI_POLICY.md): developed with Claude Code (Claude Opus 4.8); reviewed by a maintainer.


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.


Summary by cubic

Fixes swallowed link clicks when ctrl/super is released before the left mouse button. We latch the press-time chord for the full click and always clear it on release, so latched clicks open reliably. Addresses manaflow-ai/cmux#5128.

  • Bug Fixes
    • Use the press-time modifier chord while link_click_active to resolve linkAtPos, and attempt open on release even if over_link changed.
    • Clear the latch on every left-button release via a function-level defer to avoid stale suppression on early returns.

Written for commit 9f014e9. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Bug Fixes
    • Improved consistency of modifier-key link clicking. Fixed an issue where Ctrl/Cmd-clicking links could fail if hover state changed between mouse press and release events.

…latch

Two review follow-ups (codex) unifying the link-click decision so the open path
and the report-suppression path agree:

- P2 (swallowed click): when the ctrl/super modifier was released before the
  left button, the report was still suppressed (latched), but processLinks
  re-derived linkAtPos from the now-empty live mods, so the link no longer
  matched and the click was swallowed. linkAtPos now uses the latched chord
  while link_click_active is set, and the release path attempts processLinks
  whenever the click is latched (not only while over_link is still set), so the
  latched click opens its link instead of being dropped.

- P3 (stale latch): the unconditional reset was placed after the report block,
  but the successful-link and prompt-click branches return early and never
  reached it. Clear the latch with a function-level defer so it is reset on
  every left-release return path. The press is the only setter.

Part of manaflow-ai/cmux#5128.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 5, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 09e74927-6da4-4d2d-92fe-6fdbd66da717

📥 Commits

Reviewing files that changed from the base of the PR and between dcc611b and 9f014e9.

📒 Files selected for processing (1)
  • src/Surface.zig

📝 Walkthrough

Walkthrough

This PR modifies src/Surface.zig to fix link activation when ctrl/super is held at mouse-button press. It latches the modifier state at press time, ensures cleanup on release via a deferred statement, and makes link resolution use consistent effective modifiers throughout the interaction.

Changes

Link activation latch and dispatch

Layer / File(s) Summary
Press-time latch capture and release-time dispatch
src/Surface.zig
At left-button press, link_click_active is set based on ctrl/super state; a defer ensures cleanup on release. Link-click dispatch now checks over_link or link_click_active to trigger even when the mouse has moved off the link. Prior unconditional reset is removed.
Effective modifier resolution for consistent link matching
src/Surface.zig
linkAtPos computes effective modifiers using the latched ctrl/super while link_click_active is true, otherwise using live mouse modifiers. This keeps OSC8 and link matching consistent with the press-time latch during release handling.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 A latch at press, a defer at rest,
The modifier stays through mouse's zest,
Hover or not, the link knows best—
Ctrl+click consistency passes the test! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and accurately describes the main technical fix: latching link-click decisions at press time and clearing the latch on release using defer, addressing modifier-timing edge cases.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-5128-link-open-latched

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps

greptile-apps Bot commented Jun 5, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes two follow-up issues from the link-under-mouse-reporting work: a swallowed click when the ctrl/super modifier is released before the mouse button, and a stale latch when the early-return paths in mouseButtonCallback bypassed the unconditional reset. The link_click_active latch is now cleared via a defer (guaranteeing reset on all return paths), and processLinks is attempted whenever the latch is active (not only when over_link is set), while linkAtPos synthesizes the press-time chord when the latch is active.

  • Swallowed-click fix: The condition guarding processLinks is widened from over_link to over_link or link_click_active, and linkAtPos substitutes ctrlOrSuper(.{}) for the live (possibly already-released) mods when link_click_active is true — so the latched click still resolves and opens its link instead of being silently dropped.
  • Stale-latch fix: The reset of link_click_active is moved from after the report block (which early returns skip) to a defer registered immediately after the press-time setter, ensuring every left-button-release code path clears the field.

Confidence Score: 4/5

Safe to merge; changes are tightly scoped to the link-click latch lifecycle with no impact on unrelated mouse paths.

Both fixes are logically sound and the defer-based clear correctly covers all return paths. The one subtle edge case worth noting — pressing ctrl+left when not over any link still causes the click to be swallowed (report suppressed, no link opened), but this was pre-existing behaviour unchanged by the PR. The expanded processLinks guard and linkAtPos mod synthesis introduce no new code paths that could produce incorrect results.

No files require special attention; the single changed file src/Surface.zig has clear, well-commented diffs.

Important Files Changed

Filename Overview
src/Surface.zig Two targeted fixes to link-click latch lifecycle: defer-based clear ensures all early-return paths reset link_click_active, and the processLinks guard + linkAtPos mod synthesis handle the modifier-released-before-button edge case cleanly.

Sequence Diagram

sequenceDiagram
    participant User
    participant mouseButtonCallback
    participant processLinks
    participant linkAtPos

    Note over User,linkAtPos: Happy path: modifier held through release
    User->>mouseButtonCallback: left press (ctrl/super held)
    mouseButtonCallback->>mouseButtonCallback: "link_click_active = true"
    User->>mouseButtonCallback: left release (ctrl/super still held)
    mouseButtonCallback->>mouseButtonCallback: defer registered (clears latch on return)
    mouseButtonCallback->>processLinks: over_link OR link_click_active → call
    processLinks->>linkAtPos: linkAtPos(pos)
    linkAtPos->>linkAtPos: "link_click_active=true → use ctrlOrSuper mods"
    linkAtPos-->>processLinks: Link found
    processLinks-->>mouseButtonCallback: "processed=true → return true"
    mouseButtonCallback->>mouseButtonCallback: "defer fires: link_click_active = false"

    Note over User,linkAtPos: Edge case fix: modifier released before button
    User->>mouseButtonCallback: left press (ctrl/super held)
    mouseButtonCallback->>mouseButtonCallback: "link_click_active = true"
    User->>mouseButtonCallback: modifier released (over_link cleared)
    User->>mouseButtonCallback: "left release (modifier gone, over_link=false)"
    mouseButtonCallback->>mouseButtonCallback: defer registered
    mouseButtonCallback->>processLinks: "link_click_active=true → still enters block"
    processLinks->>linkAtPos: linkAtPos(pos)
    linkAtPos->>linkAtPos: "link_click_active=true → synthesize ctrlOrSuper mods"
    linkAtPos-->>processLinks: Link found (mods not from live state)
    processLinks-->>mouseButtonCallback: "processed=true → return true"
    mouseButtonCallback->>mouseButtonCallback: "defer fires: link_click_active = false"
Loading

Reviews (1): Last reviewed commit: "fix: open latched link on release with p..." | Re-trigger Greptile

@austinywang
austinywang merged commit 3853321 into main Jun 5, 2026
153 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant