дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 19:25:54 +02:00
Project Paste could reuse an earlier file copy after another app replaced the OS clipboard, and Cut files stayed dimmed. The tree now tracks the hand-off to the OS clipboard and rechecks it on window focus and just before Paste. A local Copy or Cut is cleared once the OS holds a different or empty file list; failed writes and clipboard read errors keep it. The native adapters now distinguish read failures from empty lists. In remote windows, Copy and Cut write newline-joined server paths as plain text, tree Paste keeps the server source, and a later OS file list replaces the remote copy and imports those client files. A plain-text replacement stays undetectable there without a clipboard read that may prompt. Verified on macOS, locally and against a remote host. The Windows clipboard code was not run.
54 рядки
1.5 KiB
TypeScript
54 рядки
1.5 KiB
TypeScript
/**
|
|
* The OS clipboard's file list: what Explorer copies, and what the project view
|
|
* puts there so Explorer can paste it back. The format is native (Windows
|
|
* `CF_HDROP`), so the backend owns it; a plain browser has nothing to exchange
|
|
* and every call degrades to "no files".
|
|
*/
|
|
import { call, commands, isTauri } from "@/platform/ipc";
|
|
|
|
export interface OsClipboard {
|
|
/** Files Explorer copied; empty when the clipboard holds none. */
|
|
files(): Promise<string[]>;
|
|
/** Whether the clipboard holds files: cheap, for the Paste item's enabled state. */
|
|
hasFiles(): Promise<boolean>;
|
|
/** True only when the OS accepted the file list; false for unsupported hosts. */
|
|
setFiles(paths: string[]): Promise<boolean>;
|
|
}
|
|
|
|
const native: OsClipboard = {
|
|
async files() {
|
|
if (!isTauri()) return [];
|
|
return call(commands.clipboardFileList());
|
|
},
|
|
|
|
async hasFiles() {
|
|
if (!isTauri()) return false;
|
|
try {
|
|
return await commands.clipboardHasFiles();
|
|
} catch {
|
|
return false;
|
|
}
|
|
},
|
|
|
|
async setFiles(paths) {
|
|
if (!isTauri() || !paths.length) return false;
|
|
try {
|
|
return await call(commands.clipboardSetFileList(paths));
|
|
} catch {
|
|
// The internal clipboard still works; a failed hand-off is not an error.
|
|
return false;
|
|
}
|
|
},
|
|
};
|
|
|
|
let current = native;
|
|
|
|
export function osClipboard(): OsClipboard {
|
|
return current;
|
|
}
|
|
|
|
/** Tests: force a clipboard implementation. */
|
|
export function setOsClipboardForTests(clipboard: OsClipboard | null) {
|
|
current = clipboard ?? native;
|
|
}
|