diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index ae3c81c..807d7ea 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -1,10 +1,26 @@ name: Rust -on: [push, pull_request] +on: + push: + branches: + - master + paths: + - '.github/workflows/rust.yml' + - 'src/**.rs' + - 'tests/**.rs' + - 'Cargo.toml' + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + branches: + - '**' + paths: + - '.github/workflows/rust.yml' + - 'src/**.rs' + - 'tests/**.rs' + - 'Cargo.toml' jobs: build: - runs-on: ${{ matrix.os }} strategy: diff --git a/Cargo.toml b/Cargo.toml index 2842556..9e3e58f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clipboard-master" -version = "4.0.0-beta.2" +version = "4.0.0-beta.3" authors = ["Douman "] keywords = ["Windows", "winapi", "clipboard"] description = "Simple utility crate to monitor clipboard changes" diff --git a/src/master/x11.rs b/src/master/x11.rs index 08b1772..54b12ac 100644 --- a/src/master/x11.rs +++ b/src/master/x11.rs @@ -1,15 +1,19 @@ use crate::{CallbackResult, ClipboardHandler}; + use std::io; +use std::sync::mpsc::{self, SyncSender, Receiver, sync_channel}; ///Shutdown channel /// ///On drop requests shutdown to gracefully close clipboard listener as soon as possible. pub struct Shutdown { + sender: SyncSender<()>, } impl Drop for Shutdown { #[inline(always)] fn drop(&mut self) { + let _ = self.sender.send(()); } } @@ -22,14 +26,20 @@ impl Drop for Shutdown { ///- On `windows` it creates dummy window that monitors each clipboard change message. pub struct Master { handler: H, + sender: SyncSender<()>, + recv: Receiver<()> } impl Master { #[inline(always)] ///Creates new instance. pub fn new(handler: H) -> io::Result { + let (sender, recv) = sync_channel(0); + Ok(Self { handler, + sender, + recv, }) } @@ -37,6 +47,7 @@ impl Master { ///Creates shutdown channel. pub fn shutdown_channel(&self) -> Shutdown { Shutdown { + sender: self.sender.clone() } } @@ -55,32 +66,43 @@ impl Master { }; loop { - let res = clipboard.load_wait( + let res = clipboard.load( clipboard.getter.atoms.clipboard, clipboard.getter.atoms.incr, clipboard.getter.atoms.property, + self.handler.sleep_interval(), ); - if let Err(error) = res { - let error = io::Error::new( - io::ErrorKind::Other, - format!("Failed to load clipboard: {:?}", error), - ); + match res { + Ok(_) => { + match self.handler.on_clipboard_change() { + CallbackResult::Next => (), + CallbackResult::Stop => break, + CallbackResult::StopWithError(error) => { + return Err(error); + } + } + }, + Err(x11_clipboard::error::Error::Timeout) => (), + Err(error) => { + let error = io::Error::new( + io::ErrorKind::Other, + format!("Failed to load clipboard: {:?}", error), + ); - match self.handler.on_clipboard_error(error) { - CallbackResult::Next => continue, - CallbackResult::Stop => break, - CallbackResult::StopWithError(error) => { - return Err(error); + match self.handler.on_clipboard_error(error) { + CallbackResult::Next => (), + CallbackResult::Stop => break, + CallbackResult::StopWithError(error) => { + return Err(error); + } } } } - match self.handler.on_clipboard_change() { - CallbackResult::Next => (), - CallbackResult::Stop => break, - CallbackResult::StopWithError(error) => { - return Err(error); - } + match self.recv.try_recv() { + Ok(()) => break, + Err(mpsc::TryRecvError::Empty) => continue, + Err(mpsc::TryRecvError::Disconnected) => break, } }