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

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

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-svgxxashxx-svg commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

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.
Fixespingdotgg#3698
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot 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-actionsgithub-actionsBot 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

@cursorcursorBot 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 threadapps/desktop/src/preload.ts
Comment threadapps/desktop/src/preload.ts
@macroscopeapp

macroscopeappBot 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

functionwaitForPointerRelease(): 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.

@juliusmarminge

Copy link
Copy Markdown
Member

Closing as superseded: the underlying issue #3698 was fixed by merged PR #3877. The remaining review concern here makes this version unnecessary.

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

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR 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)

2 participants

@xxashxx-svg@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

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

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

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-svgxxashxx-svg commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

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.
Fixespingdotgg#3698
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot 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-actionsgithub-actionsBot 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

@cursorcursorBot 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 threadapps/desktop/src/preload.ts
Comment threadapps/desktop/src/preload.ts
@macroscopeapp

macroscopeappBot 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

functionwaitForPointerRelease(): 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.

@juliusmarminge

Copy link
Copy Markdown
Member

Closing as superseded: the underlying issue #3698 was fixed by merged PR #3877. The remaining review concern here makes this version unnecessary.

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

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR 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)

2 participants

@xxashxx-svg@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

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

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

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-svgxxashxx-svg commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

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.
Fixespingdotgg#3698
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot 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-actionsgithub-actionsBot 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

@cursorcursorBot 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 threadapps/desktop/src/preload.ts
Comment threadapps/desktop/src/preload.ts
@macroscopeapp

macroscopeappBot 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

functionwaitForPointerRelease(): 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.

@juliusmarminge

Copy link
Copy Markdown
Member

Closing as superseded: the underlying issue #3698 was fixed by merged PR #3877. The remaining review concern here makes this version unnecessary.

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

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR 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)

2 participants

@xxashxx-svg@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

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

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

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-svgxxashxx-svg commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

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.
Fixespingdotgg#3698
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot 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-actionsgithub-actionsBot 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

@cursorcursorBot 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 threadapps/desktop/src/preload.ts
Comment threadapps/desktop/src/preload.ts
@macroscopeapp

macroscopeappBot 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

functionwaitForPointerRelease(): 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.

@juliusmarminge

Copy link
Copy Markdown
Member

Closing as superseded: the underlying issue #3698 was fixed by merged PR #3877. The remaining review concern here makes this version unnecessary.

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

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR 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)

2 participants

@xxashxx-svg@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

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

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

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-svgxxashxx-svg commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

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.
Fixespingdotgg#3698
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot 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-actionsgithub-actionsBot 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

@cursorcursorBot 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 threadapps/desktop/src/preload.ts
Comment threadapps/desktop/src/preload.ts
@macroscopeapp

macroscopeappBot 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

functionwaitForPointerRelease(): 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.

@juliusmarminge

Copy link
Copy Markdown
Member

Closing as superseded: the underlying issue #3698 was fixed by merged PR #3877. The remaining review concern here makes this version unnecessary.

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

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR 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)

2 participants

@xxashxx-svg@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

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

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

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-svgxxashxx-svg commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

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.
Fixespingdotgg#3698
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot 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-actionsgithub-actionsBot 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

@cursorcursorBot 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 threadapps/desktop/src/preload.ts
Comment threadapps/desktop/src/preload.ts
@macroscopeapp

macroscopeappBot 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

functionwaitForPointerRelease(): 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.

@juliusmarminge

Copy link
Copy Markdown
Member

Closing as superseded: the underlying issue #3698 was fixed by merged PR #3877. The remaining review concern here makes this version unnecessary.

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

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR 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)

2 participants

@xxashxx-svg@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

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

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

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-svgxxashxx-svg commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

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.
Fixespingdotgg#3698
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot 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-actionsgithub-actionsBot 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

@cursorcursorBot 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 threadapps/desktop/src/preload.ts
Comment threadapps/desktop/src/preload.ts
@macroscopeapp

macroscopeappBot 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

functionwaitForPointerRelease(): 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.

@juliusmarminge

Copy link
Copy Markdown
Member

Closing as superseded: the underlying issue #3698 was fixed by merged PR #3877. The remaining review concern here makes this version unnecessary.

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

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR 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)

2 participants

@xxashxx-svg@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

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

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

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-svgxxashxx-svg commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

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.
Fixespingdotgg#3698
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot 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-actionsgithub-actionsBot 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

@cursorcursorBot 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 threadapps/desktop/src/preload.ts
Comment threadapps/desktop/src/preload.ts
@macroscopeapp

macroscopeappBot 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

functionwaitForPointerRelease(): 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.

@juliusmarminge

Copy link
Copy Markdown
Member

Closing as superseded: the underlying issue #3698 was fixed by merged PR #3877. The remaining review concern here makes this version unnecessary.

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

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR 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)

2 participants

@xxashxx-svg@juliusmarminge