修复剪贴板错误
This commit is contained in:
@@ -78,7 +78,7 @@ use process::ProcessRegistryState;
|
|||||||
use file_watcher::FileWatcherState;
|
use file_watcher::FileWatcherState;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
use tauri::Manager;
|
use tauri::Manager;
|
||||||
use tauri::menu::{MenuBuilder, MenuItemBuilder};
|
use tauri::menu::{MenuBuilder, MenuItemBuilder, SubmenuBuilder};
|
||||||
use tauri_plugin_log::{Target, TargetKind};
|
use tauri_plugin_log::{Target, TargetKind};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@@ -95,14 +95,30 @@ fn main() {
|
|||||||
Target::new(TargetKind::Stdout),
|
Target::new(TargetKind::Stdout),
|
||||||
])
|
])
|
||||||
.build())
|
.build())
|
||||||
// Add an app menu with DevTools toggle for packaged builds
|
// App menu: include standard Edit actions so OS hotkeys (Undo/Redo/Cut/Copy/Paste/Select All)
|
||||||
|
// work across all pages, plus a DevTools toggle.
|
||||||
.menu(|app| {
|
.menu(|app| {
|
||||||
let toggle_devtools = MenuItemBuilder::new("Toggle DevTools")
|
let toggle_devtools = MenuItemBuilder::new("Toggle DevTools")
|
||||||
.id("toggle-devtools")
|
.id("toggle-devtools")
|
||||||
.accelerator("CmdOrCtrl+Alt+I")
|
.accelerator("CmdOrCtrl+Alt+I")
|
||||||
.build(app)
|
.build(app)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
// Create a proper "Edit" submenu (macOS expects standard edit actions under Edit)
|
||||||
|
let edit_menu = SubmenuBuilder::new(app, "Edit")
|
||||||
|
.undo()
|
||||||
|
.redo()
|
||||||
|
.separator()
|
||||||
|
.cut()
|
||||||
|
.copy()
|
||||||
|
.paste()
|
||||||
|
.select_all()
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
MenuBuilder::new(app)
|
MenuBuilder::new(app)
|
||||||
|
.item(&edit_menu)
|
||||||
|
.separator()
|
||||||
|
// DevTools toggle
|
||||||
.item(&toggle_devtools)
|
.item(&toggle_devtools)
|
||||||
.build()
|
.build()
|
||||||
})
|
})
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
import React, { useState, useEffect, useCallback, useRef } from "react";
|
import React, { useState, useEffect, useCallback, useRef } from "react";
|
||||||
import { invoke } from "@tauri-apps/api/core";
|
import { invoke } from "@tauri-apps/api/core";
|
||||||
import { listen, type UnlistenFn } from "@tauri-apps/api/event";
|
import { listen, type UnlistenFn } from "@tauri-apps/api/event";
|
||||||
import { writeText, readText } from "@tauri-apps/plugin-clipboard-manager";
|
|
||||||
import {
|
import {
|
||||||
X,
|
X,
|
||||||
Save,
|
Save,
|
||||||
@@ -390,104 +389,11 @@ export const FileEditorEnhanced: React.FC<FileEditorEnhancedProps> = ({
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// 使用简单的复制处理,避免剪贴板权限问题
|
// 使用系统默认的复制快捷键,避免拦截导致权限/聚焦问题
|
||||||
editor.addAction({
|
|
||||||
id: 'custom-copy',
|
|
||||||
label: 'Copy',
|
|
||||||
keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyC],
|
|
||||||
contextMenuGroupId: 'navigation',
|
|
||||||
contextMenuOrder: 1.5,
|
|
||||||
run: async (ed) => {
|
|
||||||
const selection = ed.getSelection();
|
|
||||||
if (selection) {
|
|
||||||
const text = ed.getModel()?.getValueInRange(selection);
|
|
||||||
if (text) {
|
|
||||||
try {
|
|
||||||
// 尝试使用 Tauri 的剪贴板 API
|
|
||||||
await writeText(text).catch(() => {
|
|
||||||
// 如果失败,使用浏览器原生 API
|
|
||||||
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
||||||
navigator.clipboard.writeText(text).catch(console.error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
console.log('[FileEditor] Text copied');
|
|
||||||
} catch (err) {
|
|
||||||
console.error('[FileEditor] Copy failed:', err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
editor.addAction({
|
// 使用系统默认的粘贴快捷键(Cmd/Ctrl+V),避免拦截导致无法粘贴
|
||||||
id: 'custom-paste',
|
|
||||||
label: 'Paste',
|
|
||||||
keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyV],
|
|
||||||
contextMenuGroupId: 'navigation',
|
|
||||||
contextMenuOrder: 1.6,
|
|
||||||
run: async (ed) => {
|
|
||||||
try {
|
|
||||||
let text = '';
|
|
||||||
try {
|
|
||||||
// 尝试使用 Tauri API
|
|
||||||
text = await readText();
|
|
||||||
} catch {
|
|
||||||
// 如果失败,使用浏览器原生 API
|
|
||||||
if (navigator.clipboard && navigator.clipboard.readText) {
|
|
||||||
text = await navigator.clipboard.readText().catch(() => '');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (text) {
|
|
||||||
const selection = ed.getSelection();
|
|
||||||
if (selection) {
|
|
||||||
ed.executeEdits('paste', [{
|
|
||||||
range: selection,
|
|
||||||
text: text,
|
|
||||||
forceMoveMarkers: true
|
|
||||||
}]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.error('[FileEditor] Paste failed:', err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
editor.addAction({
|
// 使用系统默认的剪切快捷键,避免拦截导致不一致行为
|
||||||
id: 'custom-cut',
|
|
||||||
label: 'Cut',
|
|
||||||
keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyX],
|
|
||||||
contextMenuGroupId: 'navigation',
|
|
||||||
contextMenuOrder: 1.4,
|
|
||||||
run: async (ed) => {
|
|
||||||
const selection = ed.getSelection();
|
|
||||||
if (selection) {
|
|
||||||
const text = ed.getModel()?.getValueInRange(selection);
|
|
||||||
if (text) {
|
|
||||||
try {
|
|
||||||
// 尝试复制到剪贴板
|
|
||||||
await writeText(text).catch(() => {
|
|
||||||
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
||||||
navigator.clipboard.writeText(text).catch(console.error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 删除选中的文本
|
|
||||||
ed.executeEdits('cut', [{
|
|
||||||
range: selection,
|
|
||||||
text: '',
|
|
||||||
forceMoveMarkers: true
|
|
||||||
}]);
|
|
||||||
|
|
||||||
console.log('[FileEditor] Text cut');
|
|
||||||
} catch (err) {
|
|
||||||
console.error('[FileEditor] Cut failed:', err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 初始化 Monaco 配置
|
// 初始化 Monaco 配置
|
||||||
initializeMonaco();
|
initializeMonaco();
|
||||||
|
Reference in New Issue
Block a user