Skip to content

Match Linux terminal copy/paste behavior#15

Open
joshdoe wants to merge 2 commits intojohannesjo:mainfrom
joshdoe:fix/linux-terminal-clipboard
Open

Match Linux terminal copy/paste behavior#15
joshdoe wants to merge 2 commits intojohannesjo:mainfrom
joshdoe:fix/linux-terminal-clipboard

Conversation

@joshdoe
Copy link
Copy Markdown
Contributor

@joshdoe joshdoe commented Mar 9, 2026

Summary

  • align terminal copy/paste behavior on Linux with the expected platform flow
  • left-drag selects, right-click when selection is present clears the selection, right-click with no selection pastes
  • wire the Electron and preload IPC needed for the updated terminal clipboard path
  • update the terminal view to use the platform-specific handling

Route terminal clipboard access through Electron so Linux can use both the normal clipboard and the X11/selection buffer. This avoids relying on browser-only clipboard APIs for behaviors that users expect to match native terminal emulators under Linux and WSL2.

Update TerminalView to follow the Linux workflow you validated in testing: left drag selects, right click copies the current selection and clears it, and a subsequent right click pastes when no selection is active. Keep middle-click paste from the selection buffer and preserve keyboard copy/paste, including Ctrl+Insert and Shift+Insert.
@joshdoe joshdoe marked this pull request as ready for review March 9, 2026 18:54
@johannesjo
Copy link
Copy Markdown
Owner

Thank you very much for this and sorry for the late reply. Somehow I wasn't receiving notifications for PRs opened here. Could you have a look at the conflicts please?

Copy link
Copy Markdown
Owner

@johannesjo johannesjo left a comment

Choose a reason for hiding this comment

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

Code Review

Overall: Well-structured PR that correctly solves a real Linux clipboard limitation. Routing clipboard through Electron IPC is the right call — browser navigator.clipboard can't access the X11 selection buffer. Clean implementation, proper cleanup, good test coverage on the backend.


Important

1. Needs rebase — merge conflict on register.ts line 1
Main now imports Notification from electron (from 587fde6). This PR changes the same line, so it will conflict. Resolved import should be:

import { ipcMain, dialog, shell, app, BrowserWindow, Notification, clipboard } from 'electron';

2. Incomplete test mocks in register.test.ts
After rebase, the electron mock will need Notification. Also missing from mocks: getAllFileDiffs/getAllFileDiffsFromBranch in git.js, and plans.js exports stopAllPlanWatchers but register.ts imports stopPlanWatcher (singular) + readPlanForWorktree.

3. pasteClipboard silently swallows errors

.catch(() => {});

A console.warn would help debug clipboard failures across Linux DEs (GNOME, KDE, Wayland, X11).

4. Unrelated test removal in pty.test.ts
The "bare command found in PATH" test deletion is unrelated to clipboard work — should be a separate commit.

5. ClipboardWrite with target: 'selection' on non-Linux writes nothing

if (target !== 'selection') clipboard.writeText(args.text);  // skipped
if ((target === 'selection' || target === 'both') && process.platform === 'linux') {  // skipped on macOS

Dead path today (frontend only sends 'both' or 'clipboard'), but worth either falling back to the default clipboard or throwing on unsupported platform+target combos.


Minor

  • The requestAnimationFrame in handleContextMenu could use a brief comment explaining why the deferral is needed (letting browser finalize selection after right-click).
  • Missing test cases: ClipboardWrite with explicit 'clipboard' target, ClipboardRead with no target, ClipboardWrite with 'selection' on non-Linux.

@johannesjo
Copy link
Copy Markdown
Owner

Thank you very much! <3

@johannesjo
Copy link
Copy Markdown
Owner

Review — additional findings after rebase consideration

The existing review covers the main blockers well. Two additional issues after comparing the PR's diff against the current main:

1. Image paste regression after rebase (needs attention during conflict resolution)

On current main, the isPaste keyboard handler has a two-stage fallback:

const text = await navigator.clipboard.readText().catch(() => '');
if (text) { enqueueInput(text); return; }
// Fall back to clipboard image → save to temp file and paste path
const filePath = await invoke<string | null>(IPC.SaveClipboardImage);
if (filePath) enqueueInput(filePath);

The PR replaces this entire block with pasteClipboard() (which only reads text via IPC). The PR's diff base is an older version of main that did not have this image fallback. When rebased, whoever resolves the conflict must preserve the IPC.SaveClipboardImage fallback for non-image text paste paths, otherwise Ctrl+Shift+V with an image in the clipboard will silently break on Linux.

Suggested approach after rebase — keep the image fallback in the Linux path:

if (isPaste) {
  pasteClipboard(); // reads from clipboard (text) via IPC
  // still preserve image fallback if text is empty? or accept the drop?
  return false;
}

At minimum this should be an explicit decision, not an accidental omission from a merge conflict.

2. pasteClipboard silently swallows errors — already noted, but the contrast is worth highlighting

copySelectionToClipboard uses fireAndForget (which logs errors to console), while pasteClipboard uses .catch(() => {}) (completely silent). Both should use the same error strategy. On Wayland/KDE, xclip/xdotool access failures are common and hard to debug without at least a console.warn.

Copy link
Copy Markdown
Owner

@johannesjo johannesjo left a comment

Choose a reason for hiding this comment

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

The PR is currently unmergeable due to upstream conflicts. More importantly, after a rebase a regression will be introduced: a SaveClipboardImage fallback was added to the isPaste keyboard handler on main since this branch was cut — the PR's replacement of that block with pasteClipboard() will silently drop it, breaking Ctrl+Shift+V with images in the clipboard on Linux.

Please: (1) rebase onto main, (2) port the image-paste fallback into pasteClipboard(), and (3) address the existing review findings (import conflict, broken test mocks, silent error swallowing, unrelated test deletion). Details in the earlier review comment.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants