From d5036cf01f673a2d0069e0daf811f396a9eeb582 Mon Sep 17 00:00:00 2001 From: Abdul Rahman ArM <39548998+invarrow@users.noreply.github.com> Date: Sun, 8 Feb 2026 16:54:09 +0530 Subject: fix(desktop): add native clipboard image paste and fix text paste (#12682) --- packages/app/src/components/prompt-input.tsx | 3 +++ packages/app/src/components/prompt-input/attachments.ts | 11 +++++++++++ packages/app/src/context/platform.tsx | 3 +++ 3 files changed, 17 insertions(+) (limited to 'packages/app/src') diff --git a/packages/app/src/components/prompt-input.tsx b/packages/app/src/components/prompt-input.tsx index 0b303cf55..7f21a36de 100644 --- a/packages/app/src/components/prompt-input.tsx +++ b/packages/app/src/components/prompt-input.tsx @@ -35,6 +35,7 @@ import { Persist, persisted } from "@/utils/persist" import { SessionContextUsage } from "@/components/session-context-usage" import { usePermission } from "@/context/permission" import { useLanguage } from "@/context/language" +import { usePlatform } from "@/context/platform" import { createTextFragment, getCursorPosition, setCursorPosition, setRangeEdge } from "./prompt-input/editor-dom" import { createPromptAttachments, ACCEPTED_FILE_TYPES } from "./prompt-input/attachments" import { navigatePromptHistory, prependHistoryEntry, promptLength } from "./prompt-input/history" @@ -97,6 +98,7 @@ export const PromptInput: Component = (props) => { const command = useCommand() const permission = usePermission() const language = useLanguage() + const platform = usePlatform() let editorRef!: HTMLDivElement let fileInputRef!: HTMLInputElement let scrollRef!: HTMLDivElement @@ -766,6 +768,7 @@ export const PromptInput: Component = (props) => { setCursorPosition(editorRef, promptLength(prompt.current())) }, addPart, + readClipboardImage: platform.readClipboardImage, }) const { abort, handleSubmit } = createPromptSubmit({ diff --git a/packages/app/src/components/prompt-input/attachments.ts b/packages/app/src/components/prompt-input/attachments.ts index 48eda3742..b384bf7d8 100644 --- a/packages/app/src/components/prompt-input/attachments.ts +++ b/packages/app/src/components/prompt-input/attachments.ts @@ -14,6 +14,7 @@ type PromptAttachmentsInput = { setDraggingType: (type: "image" | "@mention" | null) => void focusEditor: () => void addPart: (part: ContentPart) => void + readClipboardImage?: () => Promise } export function createPromptAttachments(input: PromptAttachmentsInput) { @@ -76,6 +77,16 @@ export function createPromptAttachments(input: PromptAttachmentsInput) { } const plainText = clipboardData.getData("text/plain") ?? "" + + // Desktop: Browser clipboard has no images and no text, try platform's native clipboard for images + if (input.readClipboardImage && !plainText) { + const file = await input.readClipboardImage() + if (file) { + await addImageAttachment(file) + return + } + } + if (!plainText) return input.addPart({ type: "text", content: plainText, start: 0, end: 0 }) } diff --git a/packages/app/src/context/platform.tsx b/packages/app/src/context/platform.tsx index 127b9260b..3fca502ba 100644 --- a/packages/app/src/context/platform.tsx +++ b/packages/app/src/context/platform.tsx @@ -65,6 +65,9 @@ export type Platform = { /** Check if an editor app exists (desktop only) */ checkAppExists?(appName: string): Promise + + /** Read image from clipboard (desktop only) */ + readClipboardImage?(): Promise } export const { use: usePlatform, provider: PlatformProvider } = createSimpleContext({ -- cgit v1.2.3