Skip to content

Commit 62d6986

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 bc8a127 commit 62d6986

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
@@ -98,6 +98,9 @@ export enum IPC {
9898
// System
9999
GetSystemFonts = 'get_system_fonts',
100100

101+
// Clipboard
102+
SaveClipboardImage = 'save_clipboard_image',
103+
101104
// Notifications
102105
ShowNotification = 'show_notification',
103106
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 {
@@ -452,6 +453,17 @@ export function registerAllHandlers(win: BrowserWindow): void {
452453
cancelAskAboutCode(args.requestId);
453454
});
454455

456+
// --- Clipboard ---
457+
ipcMain.handle(IPC.SaveClipboardImage, () => {
458+
const img = clipboard.readImage();
459+
if (img.isEmpty()) return null;
460+
const buf = img.toPNG();
461+
const tmpDir = os.tmpdir();
462+
const filePath = path.join(tmpDir, `clipboard-${Date.now()}.png`);
463+
fs.writeFileSync(filePath, buf);
464+
return filePath;
465+
});
466+
455467
// --- System ---
456468
ipcMain.handle(IPC.GetSystemFonts, () => getSystemMonospaceFonts());
457469

electron/preload.cjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ const ALLOWED_CHANNELS = new Set([
9090
'cancel_ask_about_code',
9191
// System
9292
'get_system_fonts',
93+
// Clipboard
94+
'save_clipboard_image',
9395
// Notifications
9496
'show_notification',
9597
'notification_clicked',

src/components/TerminalView.tsx

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

139139
if (isPaste) {
140140
e.preventDefault();
141-
navigator.clipboard.readText().then((text) => {
142-
if (text) enqueueInput(text);
143-
});
141+
(async () => {
142+
// Try text first (readText throws if clipboard has no text)
143+
const text = await navigator.clipboard.readText().catch(() => '');
144+
if (text) {
145+
enqueueInput(text);
146+
return;
147+
}
148+
// Fall back to clipboard image → save to temp file and paste path
149+
const filePath = await invoke<string | null>(IPC.SaveClipboardImage);
150+
if (filePath) enqueueInput(filePath);
151+
})();
144152
return false;
145153
}
146154

0 commit comments

Comments
 (0)