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", | ||||
| ] | ||||
| 
 | ||||
| [[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]] | ||||
| name = "clipboard-win" | ||||
| version = "4.2.1" | ||||
| @ -2860,6 +2874,7 @@ dependencies = [ | ||||
|  "cc", | ||||
|  "cfg-if 1.0.0", | ||||
|  "clap", | ||||
|  "clipboard-master", | ||||
|  "cocoa", | ||||
|  "core-foundation 0.9.1", | ||||
|  "core-graphics", | ||||
| @ -3771,6 +3786,15 @@ dependencies = [ | ||||
|  "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]] | ||||
| name = "winreg" | ||||
| version = "0.6.2" | ||||
| @ -3814,6 +3838,15 @@ version = "0.2.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| 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]] | ||||
| name = "x11rb" | ||||
| version = "0.8.1" | ||||
| @ -3826,6 +3859,16 @@ dependencies = [ | ||||
|  "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]] | ||||
| name = "yansi" | ||||
| version = "0.5.0" | ||||
|  | ||||
| @ -51,6 +51,7 @@ mac_address = "1.1" | ||||
| sciter-rs = { git = "https://github.com/open-trade/rust-sciter", branch = "dyn" } | ||||
| ctrlc = "3.2" | ||||
| arboard = "2.0" | ||||
| clipboard-master = "3" | ||||
| 
 | ||||
| [target.'cfg(target_os = "windows")'.dependencies] | ||||
| #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::*; | ||||
| pub use crate::common::{ | ||||
|     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 { | ||||
|     let sp = GenericService::new(NAME, true); | ||||
|     sp.repeat::<State, _>(INTERVAL, run); | ||||
|     sp.listen::<State, _, _>(notify, run); | ||||
|     sp | ||||
| } | ||||
| 
 | ||||
| fn notify(tx: Sender<bool>) -> ResultType<()> { | ||||
|     Master::new(ClipHandle { tx }).run()?; | ||||
|     Ok(()) | ||||
| } | ||||
| 
 | ||||
| fn run(sp: GenericService, state: &mut State) -> ResultType<()> { | ||||
|     if let Some(ctx) = state.ctx.as_mut() { | ||||
|         if let Some(msg) = check_clipboard(ctx, None) { | ||||
|  | ||||
| @ -1,5 +1,6 @@ | ||||
| use super::*; | ||||
| use std::{ | ||||
|     sync::{self, mpsc::Sender}, | ||||
|     thread::{self, JoinHandle}, | ||||
|     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) | ||||
|     where | ||||
|         F: 'static + FnMut(Self, &mut S) -> ResultType<()> + Send, | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user