Merge pull request #268 from cc-morning/master
Optimize clipboard change listener
This commit is contained in:
		
						commit
						516904551c
					
				
							
								
								
									
										43
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										43
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @ -352,6 +352,20 @@ dependencies = [ | |||||||
|  "vec_map", |  "vec_map", | ||||||
| ] | ] | ||||||
| 
 | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "clipboard-master" | ||||||
|  | version = "3.1.2" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "1cd1cb2f0df685eb4a61c656faeb6ef391ad776943d3723afb12bdcbceff824d" | ||||||
|  | dependencies = [ | ||||||
|  |  "objc", | ||||||
|  |  "objc-foundation", | ||||||
|  |  "objc_id", | ||||||
|  |  "winapi 0.3.9", | ||||||
|  |  "windows-win", | ||||||
|  |  "x11-clipboard", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
| [[package]] | [[package]] | ||||||
| name = "clipboard-win" | name = "clipboard-win" | ||||||
| version = "4.2.1" | version = "4.2.1" | ||||||
| @ -2860,6 +2874,7 @@ dependencies = [ | |||||||
|  "cc", |  "cc", | ||||||
|  "cfg-if 1.0.0", |  "cfg-if 1.0.0", | ||||||
|  "clap", |  "clap", | ||||||
|  |  "clipboard-master", | ||||||
|  "cocoa", |  "cocoa", | ||||||
|  "core-foundation 0.9.1", |  "core-foundation 0.9.1", | ||||||
|  "core-graphics", |  "core-graphics", | ||||||
| @ -3771,6 +3786,15 @@ dependencies = [ | |||||||
|  "winapi 0.3.9", |  "winapi 0.3.9", | ||||||
| ] | ] | ||||||
| 
 | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "windows-win" | ||||||
|  | version = "2.4.1" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "8d4243ec23afe4e9b4e668b3c0a0e973f1b8265f6a46223cfcbc16fd267480c0" | ||||||
|  | dependencies = [ | ||||||
|  |  "winapi 0.3.9", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
| [[package]] | [[package]] | ||||||
| name = "winreg" | name = "winreg" | ||||||
| version = "0.6.2" | version = "0.6.2" | ||||||
| @ -3814,6 +3838,15 @@ version = "0.2.0" | |||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" | checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" | ||||||
| 
 | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "x11-clipboard" | ||||||
|  | version = "0.5.2" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "b397ace6e980510de59a4fe3d4c758dffab231d6d747ce9fa1aba6b6035d5f32" | ||||||
|  | dependencies = [ | ||||||
|  |  "xcb", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
| [[package]] | [[package]] | ||||||
| name = "x11rb" | name = "x11rb" | ||||||
| version = "0.8.1" | version = "0.8.1" | ||||||
| @ -3826,6 +3859,16 @@ dependencies = [ | |||||||
|  "winapi-wsapoll", |  "winapi-wsapoll", | ||||||
| ] | ] | ||||||
| 
 | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "xcb" | ||||||
|  | version = "0.9.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "62056f63138b39116f82a540c983cc11f1c90cd70b3d492a70c25eaa50bd22a6" | ||||||
|  | dependencies = [ | ||||||
|  |  "libc", | ||||||
|  |  "log", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
| [[package]] | [[package]] | ||||||
| name = "yansi" | name = "yansi" | ||||||
| version = "0.5.0" | version = "0.5.0" | ||||||
|  | |||||||
| @ -51,6 +51,7 @@ mac_address = "1.1" | |||||||
| sciter-rs = { git = "https://github.com/open-trade/rust-sciter", branch = "dyn" } | sciter-rs = { git = "https://github.com/open-trade/rust-sciter", branch = "dyn" } | ||||||
| ctrlc = "3.2" | ctrlc = "3.2" | ||||||
| arboard = "2.0" | arboard = "2.0" | ||||||
|  | clipboard-master = "3" | ||||||
| 
 | 
 | ||||||
| [target.'cfg(target_os = "windows")'.dependencies] | [target.'cfg(target_os = "windows")'.dependencies] | ||||||
| #systray = { git = "https://github.com/open-trade/systray-rs" } | #systray = { git = "https://github.com/open-trade/systray-rs" } | ||||||
|  | |||||||
| @ -1,3 +1,7 @@ | |||||||
|  | use std::sync::mpsc::Sender; | ||||||
|  | 
 | ||||||
|  | use clipboard_master::{CallbackResult, ClipboardHandler, Master}; | ||||||
|  | 
 | ||||||
| use super::*; | use super::*; | ||||||
| pub use crate::common::{ | pub use crate::common::{ | ||||||
|     check_clipboard, ClipboardContext, CLIPBOARD_INTERVAL as INTERVAL, CLIPBOARD_NAME as NAME, |     check_clipboard, ClipboardContext, CLIPBOARD_INTERVAL as INTERVAL, CLIPBOARD_NAME as NAME, | ||||||
| @ -27,12 +31,28 @@ impl super::service::Reset for State { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | struct ClipHandle { | ||||||
|  |     tx: Sender<bool>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl ClipboardHandler for ClipHandle { | ||||||
|  |     fn on_clipboard_change(&mut self) -> CallbackResult { | ||||||
|  |         let _ = self.tx.send(true); | ||||||
|  |         CallbackResult::Next | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| pub fn new() -> GenericService { | pub fn new() -> GenericService { | ||||||
|     let sp = GenericService::new(NAME, true); |     let sp = GenericService::new(NAME, true); | ||||||
|     sp.repeat::<State, _>(INTERVAL, run); |     sp.listen::<State, _, _>(notify, run); | ||||||
|     sp |     sp | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | fn notify(tx: Sender<bool>) -> ResultType<()> { | ||||||
|  |     Master::new(ClipHandle { tx }).run()?; | ||||||
|  |     Ok(()) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| fn run(sp: GenericService, state: &mut State) -> ResultType<()> { | fn run(sp: GenericService, state: &mut State) -> ResultType<()> { | ||||||
|     if let Some(ctx) = state.ctx.as_mut() { |     if let Some(ctx) = state.ctx.as_mut() { | ||||||
|         if let Some(msg) = check_clipboard(ctx, None) { |         if let Some(msg) = check_clipboard(ctx, None) { | ||||||
|  | |||||||
| @ -1,5 +1,6 @@ | |||||||
| use super::*; | use super::*; | ||||||
| use std::{ | use std::{ | ||||||
|  |     sync::{self, mpsc::Sender}, | ||||||
|     thread::{self, JoinHandle}, |     thread::{self, JoinHandle}, | ||||||
|     time, |     time, | ||||||
| }; | }; | ||||||
| @ -153,6 +154,39 @@ impl<T: Subscriber + From<ConnInner>> ServiceTmpl<T> { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     pub fn listen<S, N, F>(&self, notify: N, callback: F) | ||||||
|  |     where | ||||||
|  |         N: 'static + FnMut(Sender<bool>) -> ResultType<()> + Send, | ||||||
|  |         F: 'static + FnMut(Self, &mut S) -> ResultType<()> + Send, | ||||||
|  |         S: 'static + Default + Reset, | ||||||
|  |     { | ||||||
|  |         let mut notify = notify; | ||||||
|  |         let mut callback = callback; | ||||||
|  |         let sp = self.clone(); | ||||||
|  |         let (tx, rx) = sync::mpsc::channel(); | ||||||
|  |         thread::spawn(move || { | ||||||
|  |             let _ = notify(tx); | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         let thread = thread::spawn(move || { | ||||||
|  |             let mut state = S::default(); | ||||||
|  |             while let Ok(changed) = rx.recv() { | ||||||
|  |                 if changed && sp.active() { | ||||||
|  |                     if sp.has_subscribes() { | ||||||
|  |                         if let Err(err) = callback(sp.clone(), &mut state) { | ||||||
|  |                             log::error!("Error of {} service: {}", sp.name(), err); | ||||||
|  |                             #[cfg(windows)] | ||||||
|  |                             crate::platform::windows::try_change_desktop(); | ||||||
|  |                         } | ||||||
|  |                     } else { | ||||||
|  |                         state.reset(); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |         self.0.write().unwrap().handle = Some(thread); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     pub fn repeat<S, F>(&self, interval_ms: u64, callback: F) |     pub fn repeat<S, F>(&self, interval_ms: u64, callback: F) | ||||||
|     where |     where | ||||||
|         F: 'static + FnMut(Self, &mut S) -> ResultType<()> + Send, |         F: 'static + FnMut(Self, &mut S) -> ResultType<()> + Send, | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user