parent
90bfa73377
commit
e9a6108559
6 changed files with 65 additions and 4 deletions
|
|
@ -2,6 +2,7 @@ use crate::input::{self, EnigoState};
|
|||
use crate::settings::{get_settings, ClipboardHandling, PasteMethod};
|
||||
use enigo::Enigo;
|
||||
use log::info;
|
||||
use std::time::Duration;
|
||||
use tauri::{AppHandle, Manager};
|
||||
use tauri_plugin_clipboard_manager::ClipboardExt;
|
||||
|
||||
|
|
@ -16,6 +17,7 @@ fn paste_via_clipboard(
|
|||
text: &str,
|
||||
app_handle: &AppHandle,
|
||||
paste_method: &PasteMethod,
|
||||
paste_delay_ms: u64,
|
||||
) -> Result<(), String> {
|
||||
let clipboard = app_handle.clipboard();
|
||||
let clipboard_content = clipboard.read_text().unwrap_or_default();
|
||||
|
|
@ -25,7 +27,7 @@ fn paste_via_clipboard(
|
|||
.write_text(text)
|
||||
.map_err(|e| format!("Failed to write to clipboard: {}", e))?;
|
||||
|
||||
std::thread::sleep(std::time::Duration::from_millis(50));
|
||||
std::thread::sleep(Duration::from_millis(paste_delay_ms));
|
||||
|
||||
// Send paste key combo
|
||||
#[cfg(target_os = "linux")]
|
||||
|
|
@ -364,6 +366,7 @@ fn paste_direct(enigo: &mut Enigo, text: &str) -> Result<(), String> {
|
|||
pub fn paste(text: String, app_handle: AppHandle) -> Result<(), String> {
|
||||
let settings = get_settings(&app_handle);
|
||||
let paste_method = settings.paste_method;
|
||||
let paste_delay_ms = settings.paste_delay_ms;
|
||||
|
||||
// Append trailing space if setting is enabled
|
||||
let text = if settings.append_trailing_space {
|
||||
|
|
@ -372,7 +375,10 @@ pub fn paste(text: String, app_handle: AppHandle) -> Result<(), String> {
|
|||
text
|
||||
};
|
||||
|
||||
info!("Using paste method: {:?}", paste_method);
|
||||
info!(
|
||||
"Using paste method: {:?}, delay: {}ms",
|
||||
paste_method, paste_delay_ms
|
||||
);
|
||||
|
||||
// Get the managed Enigo instance
|
||||
let enigo_state = app_handle
|
||||
|
|
@ -392,7 +398,13 @@ pub fn paste(text: String, app_handle: AppHandle) -> Result<(), String> {
|
|||
paste_direct(&mut enigo, &text)?;
|
||||
}
|
||||
PasteMethod::CtrlV | PasteMethod::CtrlShiftV | PasteMethod::ShiftInsert => {
|
||||
paste_via_clipboard(&mut enigo, &text, &app_handle, &paste_method)?
|
||||
paste_via_clipboard(
|
||||
&mut enigo,
|
||||
&text,
|
||||
&app_handle,
|
||||
&paste_method,
|
||||
paste_delay_ms,
|
||||
)?
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -315,6 +315,8 @@ pub struct AppSettings {
|
|||
pub experimental_enabled: bool,
|
||||
#[serde(default)]
|
||||
pub keyboard_implementation: KeyboardImplementation,
|
||||
#[serde(default = "default_paste_delay_ms")]
|
||||
pub paste_delay_ms: u64,
|
||||
}
|
||||
|
||||
fn default_model() -> String {
|
||||
|
|
@ -364,6 +366,10 @@ fn default_word_correction_threshold() -> f64 {
|
|||
0.18
|
||||
}
|
||||
|
||||
fn default_paste_delay_ms() -> u64 {
|
||||
60
|
||||
}
|
||||
|
||||
fn default_history_limit() -> usize {
|
||||
5
|
||||
}
|
||||
|
|
@ -605,6 +611,7 @@ pub fn get_default_settings() -> AppSettings {
|
|||
app_language: default_app_language(),
|
||||
experimental_enabled: false,
|
||||
keyboard_implementation: KeyboardImplementation::default(),
|
||||
paste_delay_ms: default_paste_delay_ms(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -703,7 +703,7 @@ async isLaptop() : Promise<Result<boolean, string>> {
|
|||
|
||||
/** user-defined types **/
|
||||
|
||||
export type AppSettings = { bindings: Partial<{ [key in string]: ShortcutBinding }>; push_to_talk: boolean; audio_feedback: boolean; audio_feedback_volume?: number; sound_theme?: SoundTheme; start_hidden?: boolean; autostart_enabled?: boolean; update_checks_enabled?: boolean; selected_model?: string; always_on_microphone?: boolean; selected_microphone?: string | null; clamshell_microphone?: string | null; selected_output_device?: string | null; translate_to_english?: boolean; selected_language?: string; overlay_position?: OverlayPosition; debug_mode?: boolean; log_level?: LogLevel; custom_words?: string[]; model_unload_timeout?: ModelUnloadTimeout; word_correction_threshold?: number; history_limit?: number; recording_retention_period?: RecordingRetentionPeriod; paste_method?: PasteMethod; clipboard_handling?: ClipboardHandling; post_process_enabled?: boolean; post_process_provider_id?: string; post_process_providers?: PostProcessProvider[]; post_process_api_keys?: Partial<{ [key in string]: string }>; post_process_models?: Partial<{ [key in string]: string }>; post_process_prompts?: LLMPrompt[]; post_process_selected_prompt_id?: string | null; mute_while_recording?: boolean; append_trailing_space?: boolean; app_language?: string; experimental_enabled?: boolean; keyboard_implementation?: KeyboardImplementation }
|
||||
export type AppSettings = { bindings: Partial<{ [key in string]: ShortcutBinding }>; push_to_talk: boolean; audio_feedback: boolean; audio_feedback_volume?: number; sound_theme?: SoundTheme; start_hidden?: boolean; autostart_enabled?: boolean; update_checks_enabled?: boolean; selected_model?: string; always_on_microphone?: boolean; selected_microphone?: string | null; clamshell_microphone?: string | null; selected_output_device?: string | null; translate_to_english?: boolean; selected_language?: string; overlay_position?: OverlayPosition; debug_mode?: boolean; log_level?: LogLevel; custom_words?: string[]; model_unload_timeout?: ModelUnloadTimeout; word_correction_threshold?: number; history_limit?: number; recording_retention_period?: RecordingRetentionPeriod; paste_method?: PasteMethod; clipboard_handling?: ClipboardHandling; post_process_enabled?: boolean; post_process_provider_id?: string; post_process_providers?: PostProcessProvider[]; post_process_api_keys?: Partial<{ [key in string]: string }>; post_process_models?: Partial<{ [key in string]: string }>; post_process_prompts?: LLMPrompt[]; post_process_selected_prompt_id?: string | null; mute_while_recording?: boolean; append_trailing_space?: boolean; app_language?: string; experimental_enabled?: boolean; keyboard_implementation?: KeyboardImplementation; paste_delay_ms?: number }
|
||||
export type AudioDevice = { index: string; name: string; is_default: boolean }
|
||||
export type BindingResponse = { success: boolean; binding: ShortcutBinding | null; error: string | null }
|
||||
export type ClipboardHandling = "dont_modify" | "copy_to_clipboard"
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { useTranslation } from "react-i18next";
|
|||
import { type } from "@tauri-apps/plugin-os";
|
||||
import { WordCorrectionThreshold } from "./WordCorrectionThreshold";
|
||||
import { LogLevelSelector } from "./LogLevelSelector";
|
||||
import { PasteDelay } from "./PasteDelay";
|
||||
import { SettingsGroup } from "../../ui/SettingsGroup";
|
||||
import { AlwaysOnMicrophone } from "../AlwaysOnMicrophone";
|
||||
import { SoundPicker } from "../SoundPicker";
|
||||
|
|
@ -27,6 +28,7 @@ export const DebugSettings: React.FC = () => {
|
|||
description={t("settings.debug.soundTheme.description")}
|
||||
/>
|
||||
<WordCorrectionThreshold descriptionMode="tooltip" grouped={true} />
|
||||
<PasteDelay descriptionMode="tooltip" grouped={true} />
|
||||
<AlwaysOnMicrophone descriptionMode="tooltip" grouped={true} />
|
||||
<ClamshellMicrophoneSelector descriptionMode="tooltip" grouped={true} />
|
||||
{/* Cancel shortcut is disabled on Linux due to instability with dynamic shortcut registration */}
|
||||
|
|
|
|||
36
src/components/settings/debug/PasteDelay.tsx
Normal file
36
src/components/settings/debug/PasteDelay.tsx
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Slider } from "../../ui/Slider";
|
||||
import { useSettings } from "../../../hooks/useSettings";
|
||||
|
||||
interface PasteDelayProps {
|
||||
descriptionMode?: "tooltip" | "inline";
|
||||
grouped?: boolean;
|
||||
}
|
||||
|
||||
export const PasteDelay: React.FC<PasteDelayProps> = ({
|
||||
descriptionMode = "tooltip",
|
||||
grouped = false,
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { settings, updateSetting } = useSettings();
|
||||
|
||||
const handleDelayChange = (value: number) => {
|
||||
updateSetting("paste_delay_ms", value);
|
||||
};
|
||||
|
||||
return (
|
||||
<Slider
|
||||
value={settings?.paste_delay_ms ?? 60}
|
||||
onChange={handleDelayChange}
|
||||
min={10}
|
||||
max={200}
|
||||
step={10}
|
||||
label={t("settings.debug.pasteDelay.title")}
|
||||
description={t("settings.debug.pasteDelay.description")}
|
||||
descriptionMode={descriptionMode}
|
||||
grouped={grouped}
|
||||
formatValue={(v) => `${v}ms`}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
@ -370,6 +370,10 @@
|
|||
"description": "Choose the keyboard shortcut backend.",
|
||||
"bindingsReset": "Keyboard shortcuts were incompatible and reset to defaults"
|
||||
},
|
||||
"pasteDelay": {
|
||||
"title": "Paste Delay",
|
||||
"description": "Delay before sending paste keystroke (in milliseconds). Increase if wrong text is being pasted."
|
||||
},
|
||||
"paths": {
|
||||
"appData": "App Data:",
|
||||
"models": "Models:",
|
||||
|
|
|
|||
Loading…
Reference in a new issue