From fbb2de24587783bc7ae8c28f1abd7969b93ff61e Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Sun, 17 May 2026 23:06:59 -0700 Subject: [PATCH] Fix Linux primary selection paste inside Orca --- .../src/components/editor/MonacoEditor.tsx | 7 +++++- .../src/hooks/usePrimarySelectionPaste.ts | 22 +++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/renderer/src/components/editor/MonacoEditor.tsx b/src/renderer/src/components/editor/MonacoEditor.tsx index 3e9129f7c27..155132b23a3 100644 --- a/src/renderer/src/components/editor/MonacoEditor.tsx +++ b/src/renderer/src/components/editor/MonacoEditor.tsx @@ -36,6 +36,7 @@ import { isMarkdownComment } from '@/lib/diff-comment-compat' import { useDiffCommentDecorator } from '../diff-comments/useDiffCommentDecorator' import { DiffCommentPopover } from '../diff-comments/DiffCommentPopover' import { getDiffCommentPopoverLeft } from '../diff-comments/diff-comment-popover-position' +import { isLinuxUserAgent } from '../terminal-pane/pane-helpers' type MonacoEditorProps = { filePath: string @@ -640,7 +641,11 @@ export default function MonacoEditor({ addExtraSpaceOnTop: false, autoFindInSelection: 'never', seedSearchStringFromSelection: 'never' - } + }, + // Why: Monaco has its own Linux primary-selection integration; keep + // it aligned with Orca's app-level opt-out instead of relying on the + // global DOM hook, which does not own Monaco's rendered line surface. + selectionClipboard: settings?.primarySelectionMiddleClickPaste ?? isLinuxUserAgent() }} path={filePath} // Why: keepCurrentModel preserves the Monaco text model so undo/redo diff --git a/src/renderer/src/hooks/usePrimarySelectionPaste.ts b/src/renderer/src/hooks/usePrimarySelectionPaste.ts index 97939f66f30..9437c4014d6 100644 --- a/src/renderer/src/hooks/usePrimarySelectionPaste.ts +++ b/src/renderer/src/hooks/usePrimarySelectionPaste.ts @@ -45,7 +45,10 @@ export function usePrimarySelectionPaste(enabled: boolean): void { return target === pendingMiddleTarget || pendingMiddleTarget.contains(target) } - const rememberPendingTarget = (event: MouseEvent): boolean => { + const rememberPendingTarget = ( + event: MouseEvent, + options?: { allowNativeLinuxPaste?: boolean } + ): boolean => { if (event.button !== 1) { return false } @@ -53,6 +56,12 @@ export function usePrimarySelectionPaste(enabled: boolean): void { if (!target) { return false } + if (options?.allowNativeLinuxPaste && isLinuxUserAgent()) { + // Why: Chromium already implements X11 primary paste for editable DOM + // controls. Suppressing that native path can turn a working OS paste + // into a no-op before Orca's async fallback runs. + return false + } pendingMiddleTarget = target pendingMiddleUntil = Date.now() + 750 return true @@ -127,7 +136,7 @@ export function usePrimarySelectionPaste(enabled: boolean): void { } const onMouseDown = (event: MouseEvent): void => { - rememberPendingTarget(event) + rememberPendingTarget(event, { allowNativeLinuxPaste: true }) } const onMouseUp = (event: MouseEvent): void => { @@ -152,9 +161,14 @@ export function usePrimarySelectionPaste(enabled: boolean): void { } const onAuxClick = (event: MouseEvent): void => { - if (event.button === 1 && findEditablePrimarySelectionPasteTarget(event.target)) { - suppressEvent(event) + if (event.button !== 1) { + return } + const target = findEditablePrimarySelectionPasteTarget(event.target) + if (!target || isLinuxUserAgent()) { + return + } + suppressEvent(event) } document.addEventListener('selectionchange', scheduleCapture)