feat(core): implement preserve_clipboard
This commit is contained in:
parent
dadc71728c
commit
0d226619a9
|
@ -123,6 +123,8 @@ impl<'a> super::engine::dispatch::executor::clipboard_injector::ClipboardParamsP
|
||||||
paste_shortcut_event_delay: 5, // TODO: read from config
|
paste_shortcut_event_delay: 5, // TODO: read from config
|
||||||
paste_shortcut: None, // TODO: read from config
|
paste_shortcut: None, // TODO: read from config
|
||||||
disable_x11_fast_inject: false, // TODO: read from config
|
disable_x11_fast_inject: false, // TODO: read from config
|
||||||
|
restore_clipboard: true, // TODO: read from config
|
||||||
|
restore_clipboard_delay: 300, // TODO: read from config
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ use std::{convert::TryInto, path::PathBuf};
|
||||||
|
|
||||||
use espanso_clipboard::Clipboard;
|
use espanso_clipboard::Clipboard;
|
||||||
use espanso_inject::{keys::Key, InjectionOptions, Injector};
|
use espanso_inject::{keys::Key, InjectionOptions, Injector};
|
||||||
|
use log::error;
|
||||||
|
|
||||||
use crate::engine::{
|
use crate::engine::{
|
||||||
dispatch::HtmlInjector,
|
dispatch::HtmlInjector,
|
||||||
|
@ -36,6 +37,8 @@ pub struct ClipboardParams {
|
||||||
pub paste_shortcut_event_delay: usize,
|
pub paste_shortcut_event_delay: usize,
|
||||||
pub paste_shortcut: Option<String>,
|
pub paste_shortcut: Option<String>,
|
||||||
pub disable_x11_fast_inject: bool,
|
pub disable_x11_fast_inject: bool,
|
||||||
|
pub restore_clipboard: bool,
|
||||||
|
pub restore_clipboard_delay: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ClipboardInjectorAdapter<'a> {
|
pub struct ClipboardInjectorAdapter<'a> {
|
||||||
|
@ -89,6 +92,19 @@ impl<'a> ClipboardInjectorAdapter<'a> {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn restore_clipboard_guard(&self) -> Option<ClipboardRestoreGuard<'a>> {
|
||||||
|
let params = self.params_provider.get();
|
||||||
|
|
||||||
|
if params.restore_clipboard {
|
||||||
|
Some(ClipboardRestoreGuard::lock(
|
||||||
|
self.clipboard,
|
||||||
|
params.restore_clipboard_delay.try_into().unwrap(),
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TextInjector for ClipboardInjectorAdapter<'a> {
|
impl<'a> TextInjector for ClipboardInjectorAdapter<'a> {
|
||||||
|
@ -97,7 +113,8 @@ impl<'a> TextInjector for ClipboardInjectorAdapter<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_text(&self, text: &str) -> anyhow::Result<()> {
|
fn inject_text(&self, text: &str) -> anyhow::Result<()> {
|
||||||
// TODO: handle clipboard restoration
|
let _guard = self.restore_clipboard_guard();
|
||||||
|
|
||||||
self.clipboard.set_text(text)?;
|
self.clipboard.set_text(text)?;
|
||||||
|
|
||||||
self.send_paste_combination()?;
|
self.send_paste_combination()?;
|
||||||
|
@ -108,7 +125,8 @@ impl<'a> TextInjector for ClipboardInjectorAdapter<'a> {
|
||||||
|
|
||||||
impl<'a> HtmlInjector for ClipboardInjectorAdapter<'a> {
|
impl<'a> HtmlInjector for ClipboardInjectorAdapter<'a> {
|
||||||
fn inject_html(&self, html: &str, fallback_text: &str) -> anyhow::Result<()> {
|
fn inject_html(&self, html: &str, fallback_text: &str) -> anyhow::Result<()> {
|
||||||
// TODO: handle clipboard restoration
|
let _guard = self.restore_clipboard_guard();
|
||||||
|
|
||||||
self.clipboard.set_html(html, Some(fallback_text))?;
|
self.clipboard.set_html(html, Some(fallback_text))?;
|
||||||
|
|
||||||
self.send_paste_combination()?;
|
self.send_paste_combination()?;
|
||||||
|
@ -130,7 +148,8 @@ impl<'a> ImageInjector for ClipboardInjectorAdapter<'a> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: handle clipboard restoration
|
let _guard = self.restore_clipboard_guard();
|
||||||
|
|
||||||
self.clipboard.set_image(&path)?;
|
self.clipboard.set_image(&path)?;
|
||||||
|
|
||||||
self.send_paste_combination()?;
|
self.send_paste_combination()?;
|
||||||
|
@ -138,3 +157,38 @@ impl<'a> ImageInjector for ClipboardInjectorAdapter<'a> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ClipboardRestoreGuard<'a> {
|
||||||
|
clipboard: &'a dyn Clipboard,
|
||||||
|
content: Option<String>,
|
||||||
|
restore_delay: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ClipboardRestoreGuard<'a> {
|
||||||
|
pub fn lock(clipboard: &'a dyn Clipboard, restore_delay: u64) -> Self {
|
||||||
|
let clipboard_content = clipboard.get_text();
|
||||||
|
|
||||||
|
Self {
|
||||||
|
clipboard,
|
||||||
|
content: clipboard_content,
|
||||||
|
restore_delay,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Drop for ClipboardRestoreGuard<'a> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if let Some(content) = self.content.take() {
|
||||||
|
// Sometimes an expansion gets overwritten before pasting by the previous content
|
||||||
|
// A delay is needed to mitigate the problem
|
||||||
|
std::thread::sleep(std::time::Duration::from_millis(self.restore_delay));
|
||||||
|
|
||||||
|
if let Err(error) = self.clipboard.set_text(&content) {
|
||||||
|
error!(
|
||||||
|
"unable to restore clipboard content after expansion: {}",
|
||||||
|
error
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user