Skip to content

Commit c2bc7dd

Browse files
committed
feat(terminal): paste clipboard images as temp file paths
When Cmd+V is pressed and the clipboard contains an image instead of text, save it to a temp PNG file and paste the file path into the terminal. Useful for CLI tools that accept image paths.
1 parent 9ce6abe commit c2bc7dd

4 files changed

Lines changed: 29 additions & 4 deletions

File tree

electron/ipc/channels.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ export enum IPC {
102102
OpenPath = 'open_path',
103103
ReadFileText = 'read_file_text',
104104

105+
// Clipboard
106+
SaveClipboardImage = 'save_clipboard_image',
107+
105108
// Notifications
106109
ShowNotification = 'show_notification',
107110
NotificationClicked = 'notification_clicked',

electron/ipc/register.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { ipcMain, dialog, shell, app, BrowserWindow, Notification } from 'electron';
1+
import { ipcMain, dialog, shell, app, clipboard, BrowserWindow, Notification } from 'electron';
22
import fs from 'fs';
3+
import os from 'os';
34
import { fileURLToPath } from 'url';
45
import { IPC } from './channels.js';
56
import {
@@ -463,6 +464,17 @@ export function registerAllHandlers(win: BrowserWindow): void {
463464
return fs.readFileSync(args.filePath, 'utf8');
464465
});
465466

467+
// --- Clipboard ---
468+
ipcMain.handle(IPC.SaveClipboardImage, () => {
469+
const img = clipboard.readImage();
470+
if (img.isEmpty()) return null;
471+
const buf = img.toPNG();
472+
const tmpDir = os.tmpdir();
473+
const filePath = path.join(tmpDir, `clipboard-${Date.now()}.png`);
474+
fs.writeFileSync(filePath, buf);
475+
return filePath;
476+
});
477+
466478
// --- System ---
467479
ipcMain.handle(IPC.GetSystemFonts, () => getSystemMonospaceFonts());
468480

electron/preload.cjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ const ALLOWED_CHANNELS = new Set([
9393
// File links
9494
'open_path',
9595
'read_file_text',
96+
// Clipboard
97+
'save_clipboard_image',
9698
// Notifications
9799
'show_notification',
98100
'notification_clicked',

src/components/TerminalView.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,9 +191,17 @@ export function TerminalView(props: TerminalViewProps) {
191191

192192
if (isPaste) {
193193
e.preventDefault();
194-
navigator.clipboard.readText().then((text) => {
195-
if (text) enqueueInput(text);
196-
});
194+
(async () => {
195+
// Try text first (readText throws if clipboard has no text)
196+
const text = await navigator.clipboard.readText().catch(() => '');
197+
if (text) {
198+
enqueueInput(text);
199+
return;
200+
}
201+
// Fall back to clipboard image → save to temp file and paste path
202+
const filePath = await invoke<string | null>(IPC.SaveClipboardImage);
203+
if (filePath) enqueueInput(filePath);
204+
})();
197205
return false;
198206
}
199207

0 commit comments

Comments
 (0)