Skip to content

fix(desktop): stop Linux context menus from activating an item on open#3868

Open
xxashxx-svg wants to merge 2 commits into
pingdotgg:mainfrom
xxashxx-svg:fix/linux-context-menu-press-release
Open

fix(desktop): stop Linux context menus from activating an item on open#3868
xxashxx-svg wants to merge 2 commits into
pingdotgg:mainfrom
xxashxx-svg:fix/linux-context-menu-press-release

Conversation

@xxashxx-svg

@xxashxx-svg xxashxx-svg commented Jul 10, 2026

Copy link
Copy Markdown

Fixes #3698

What

On Linux, right-clicking a project/thread in the sidebar makes the context menu flash open and instantly close, with a random menu item activated as if clicked (regression of #285 — still present in v0.0.28 despite the #3025 fix).

Why it happens

Two facts combine:

  1. The desktop app never runs the code Polish web context menu fallback and sidebar icon actions #3025 fixed. localApi.ts routes context menus through window.desktopBridge.showContextMenu → IPC → the native Electron menu (ElectronMenu.ts) whenever the bridge exists — which on desktop is always. The canDismissFromPointer guard added by Polish web context menu fallback and sidebar icon actions #3025 lives in contextMenuFallback.ts, the browser-only fallback, so it could never fix the desktop bug.
  2. On Linux, Chromium fires contextmenu on right-button press (Windows fires it on release). So the native menu pops up — positioned directly under the cursor — while the button is still physically held. The menu takes the pointer grab, and the tail of the same right-click gesture (the button release) lands on whatever item happens to sit under the cursor and activates it. This also explains the reported workaround: holding the right button and dragging away before releasing means the release lands outside the menu.

Change

In the desktop preload, desktopBridge.showContextMenu now waits (Linux only) for the pointer buttons to be released before invoking the context-menu IPC — i.e. the menu opens on release, exactly matching the Windows event semantics that don't exhibit the bug. Button state is tracked with capture-phase pointer listeners; pointercancel and window blur settle the wait so it can't hang. Menus opened with no button held (keyboard, normal-click "…" buttons — where click fires after release) are unaffected, as are Windows and macOS entirely.

The process.platform check uses the repo's established oxlint-disable pattern for standalone non-Effect scripts (same as apps/desktop/scripts/*).

Verification

  • vp check and vp run typecheck pass.
  • I don't have a Linux desktop environment to hand, so this is verified by analysis rather than by reproducing on Ubuntu — the event-order reasoning above matches the reporter's symptoms and workaround exactly, but a maintainer with a Linux box may want to sanity-check before merging. Happy to adjust if testing surfaces anything.

🤖 Generated with Claude Code


Note

Low Risk
Scoped to Linux preload pointer gating around context-menu IPC; other platforms and no-button menu paths are unchanged.

Overview
Fixes #3698: on Linux, native context menus opened while the right button was still down, so the release could activate a random item under the cursor.

desktopBridge.showContextMenu in the desktop preload is now async and, on Linux only, waits for pointer buttons to clear before calling the context-menu IPC. Global capture-phase listeners track pointerButtonsHeld; waitForPointerRelease proceeds immediately when no buttons are held (keyboard / “…” menus), waits for release of the buttons that were down at request time, or returns null on pointercancel / window blur so the menu does not open mid-gesture or at stale coordinates. Windows and macOS are unchanged.

Reviewed by Cursor Bugbot for commit d82d568. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Fix Linux context menus activating an item on open by waiting for pointer release

On Linux, right-clicking to open a context menu could immediately trigger an item because the menu appeared while the pointer button was still held. This fix delays the desktopBridge.showContextMenu IPC call until all held pointer buttons are released. If the gesture is cancelled or the window loses focus before release, the menu is not opened and the method returns null. Other platforms are unaffected.

Macroscope summarized d82d568.

On Linux, Chromium fires contextmenu on right-button PRESS (Windows fires
it on release), so the native menu pops up while the button is still
physically held. The menu takes the pointer grab, and the tail end of the
opening right-click — the button release — lands on whatever item sits
under the cursor and activates it. The menu flashes and a random item
runs, which also explains the known workaround (hold the right button and
drag away before releasing).

The earlier fix (pingdotgg#3025) hardened contextMenuFallback.ts, but the desktop
app never uses that path — window.desktopBridge routes context menus to
the native Electron menu, so the regression survived.

Gate the desktopBridge.showContextMenu IPC on pointer release (Linux
only): track button state in the preload and defer opening the menu until
the press that triggered it is released, matching Windows semantics.
Menus opened with no button held (keyboard, click-triggered) are
unaffected, as are Windows and macOS.

Fixes pingdotgg#3698

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 01b03ae5-21bb-4905-8260-9a21b3928c9f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Jul 10, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 94840df. Configure here.

Comment thread apps/desktop/src/preload.ts
Comment thread apps/desktop/src/preload.ts
@macroscopeapp

macroscopeapp Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

1 blocking correctness issue found. There is an unresolved review comment identifying a potential hang issue where context menus could be permanently blocked if the mouse button is released outside the window. This substantive concern warrants human review before merging.

You can customize Macroscope's approvability policy. Learn more.

… context menu gate

Two review findings from Bugbot on the pointer-release gate:

- Waiting for event.buttons === 0 meant a second held button (e.g. left
  held while right-clicking) kept the menu waiting until every button was
  released. Track the buttons held at request time and settle once those
  are up, ignoring buttons pressed mid-gesture.
- blur/pointercancel previously settled the wait and opened the menu,
  which could pop it mid-hold (re-triggering the original bug) or at
  stale coordinates after focus loss. Treat those as gesture
  cancellation: resolve null without opening the menu, matching the
  bridge's existing 'no selection' contract.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium

function waitForPointerRelease(): Promise<boolean> {

showContextMenu can hang indefinitely when a right-click drag releases the mouse button outside the window. Without implicit pointer capture, the window may never receive pointerup, pointercancel, or blur for that gesture, so pointerButtonsHeld stays nonzero and waitForPointerRelease never resolves. Every subsequent context-menu call is then permanently gated until an unrelated blur or pointercancel resets the state. Consider adding a timeout fallback in waitForPointerRelease so the menu can still open if the release is not observed within a reasonable window.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/desktop/src/preload.ts around line 51:

`showContextMenu` can hang indefinitely when a right-click drag releases the mouse button outside the window. Without implicit pointer capture, the window may never receive `pointerup`, `pointercancel`, or `blur` for that gesture, so `pointerButtonsHeld` stays nonzero and `waitForPointerRelease` never resolves. Every subsequent context-menu call is then permanently gated until an unrelated `blur` or `pointercancel` resets the state. Consider adding a timeout fallback in `waitForPointerRelease` so the menu can still open if the release is not observed within a reasonable window.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Sidebar context menu auto-selects a random item on right-click (regression of #285)

1 participant