mirror of
https://github.com/NotAShelf/stash.git
synced 2026-04-13 14:33:47 +00:00
commands/watch: make it trait-based; move out of main
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I6a6a6964c16396f2013e7f8a5c1a6c0c3bb2aeaa
This commit is contained in:
parent
d9b0908ada
commit
9d40dde63a
3 changed files with 112 additions and 78 deletions
|
|
@ -3,4 +3,5 @@ pub mod delete;
|
|||
pub mod list;
|
||||
pub mod query;
|
||||
pub mod store;
|
||||
pub mod watch;
|
||||
pub mod wipe;
|
||||
|
|
|
|||
79
src/commands/watch.rs
Normal file
79
src/commands/watch.rs
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
use crate::db::{ClipboardDb, Entry, SqliteClipboardDb};
|
||||
use smol::Timer;
|
||||
use std::io::Read;
|
||||
use std::time::Duration;
|
||||
use wl_clipboard_rs::paste::{ClipboardType, Seat, get_contents};
|
||||
|
||||
pub trait WatchCommand {
|
||||
fn watch(&self, max_dedupe_search: u64, max_items: u64);
|
||||
}
|
||||
|
||||
impl WatchCommand for SqliteClipboardDb {
|
||||
fn watch(&self, max_dedupe_search: u64, max_items: u64) {
|
||||
smol::block_on(async {
|
||||
log::info!("Starting clipboard watch daemon");
|
||||
|
||||
// Preallocate buffer for clipboard contents
|
||||
let mut last_contents: Option<Vec<u8>> = None;
|
||||
let mut buf = Vec::with_capacity(4096); // reasonable default, hopefully
|
||||
|
||||
// Initialize with current clipboard to avoid duplicating on startup
|
||||
if let Ok((mut reader, _)) = get_contents(
|
||||
ClipboardType::Regular,
|
||||
Seat::Unspecified,
|
||||
wl_clipboard_rs::paste::MimeType::Any,
|
||||
) {
|
||||
buf.clear();
|
||||
if reader.read_to_end(&mut buf).is_ok() && !buf.is_empty() {
|
||||
last_contents = Some(buf.clone());
|
||||
}
|
||||
}
|
||||
|
||||
loop {
|
||||
match get_contents(
|
||||
ClipboardType::Regular,
|
||||
Seat::Unspecified,
|
||||
wl_clipboard_rs::paste::MimeType::Any,
|
||||
) {
|
||||
Ok((mut reader, mime_type)) => {
|
||||
buf.clear();
|
||||
if let Err(e) = reader.read_to_end(&mut buf) {
|
||||
log::error!("Failed to read clipboard contents: {e}");
|
||||
Timer::after(Duration::from_millis(500)).await;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Only store if changed and not empty
|
||||
if !buf.is_empty() && (last_contents.as_ref() != Some(&buf)) {
|
||||
last_contents = Some(std::mem::take(&mut buf));
|
||||
let mime = Some(mime_type.to_string());
|
||||
let entry = Entry {
|
||||
contents: last_contents.as_ref().unwrap().clone(),
|
||||
mime,
|
||||
};
|
||||
let id = self.next_sequence();
|
||||
match self.store_entry(
|
||||
&entry.contents[..],
|
||||
max_dedupe_search,
|
||||
max_items,
|
||||
) {
|
||||
Ok(_) => log::info!("Stored new clipboard entry (id: {id})"),
|
||||
Err(e) => log::error!("Failed to store clipboard entry: {e}"),
|
||||
}
|
||||
|
||||
// Drop clipboard contents after storing
|
||||
last_contents = None;
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
let error_msg = e.to_string();
|
||||
if !error_msg.contains("empty") {
|
||||
log::error!("Failed to get clipboard contents: {e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
Timer::after(Duration::from_millis(500)).await;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue