1. 完善发送的逻辑,使用状态机和鼠标以及pip_file一同进行管理
2. 自测已可正常发送接收 3. atime的管理使用write还是read去更新需要使用宏来控制。目前已coding完毕等待调试
This commit is contained in:
		@@ -27,3 +27,7 @@ dirs = "4.0"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[profile.test]
 | 
					[profile.test]
 | 
				
			||||||
env = { "RUST_LOG" = "debug" }
 | 
					env = { "RUST_LOG" = "debug" }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[features]
 | 
				
			||||||
 | 
					atime_read = []
 | 
				
			||||||
							
								
								
									
										323
									
								
								src/lib.rs
									
									
									
									
									
								
							
							
						
						
									
										323
									
								
								src/lib.rs
									
									
									
									
									
								
							@@ -129,7 +129,9 @@ pub struct ClipboardSync {
 | 
				
			|||||||
    clip: wclip::Wclip,
 | 
					    clip: wclip::Wclip,
 | 
				
			||||||
    cfg: Config,
 | 
					    cfg: Config,
 | 
				
			||||||
    pipe: MsgSyncPipe,
 | 
					    pipe: MsgSyncPipe,
 | 
				
			||||||
 | 
					    cursor: CursorCtrl,
 | 
				
			||||||
    characters: Character,
 | 
					    characters: Character,
 | 
				
			||||||
 | 
					    recent_msg: String,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const USER_AGENT: &str = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36 Edg/106.0.1370.42";
 | 
					const USER_AGENT: &str = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36 Edg/106.0.1370.42";
 | 
				
			||||||
@@ -157,6 +159,7 @@ pub enum Character {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
struct MsgSyncPipe {
 | 
					struct MsgSyncPipe {
 | 
				
			||||||
    pub pipe_file: String,
 | 
					    pub pipe_file: String,
 | 
				
			||||||
 | 
					    pub status_file: String,
 | 
				
			||||||
    atime: Duration,
 | 
					    atime: Duration,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -167,13 +170,14 @@ struct MsgSyncPipe {
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
impl MsgSyncPipe {
 | 
					impl MsgSyncPipe {
 | 
				
			||||||
    pub fn new(c:&Character) -> Result<MsgSyncPipe, Box<dyn Error>> {
 | 
					    pub fn new(c:&Character) -> Result<MsgSyncPipe, Box<dyn Error>> {
 | 
				
			||||||
        let pipe_file = match c {
 | 
					        let (pipe_file,status_file) = match c {
 | 
				
			||||||
            Character::Producer => Self::get_producer_pipe()?,
 | 
					            Character::Producer => Self::get_producer_pipe()?,
 | 
				
			||||||
            Character::Consumer => Self::get_consumer_pipe()?,
 | 
					            Character::Consumer => Self::get_consumer_pipe()?,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        let atime = Self::get_pipe_atime(&pipe_file);
 | 
					        let atime = Self::get_pipe_atime(&pipe_file);
 | 
				
			||||||
        Ok(MsgSyncPipe {
 | 
					        Ok(MsgSyncPipe {
 | 
				
			||||||
            pipe_file,
 | 
					            pipe_file,
 | 
				
			||||||
 | 
					            status_file,
 | 
				
			||||||
            atime,
 | 
					            atime,
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -188,7 +192,7 @@ impl MsgSyncPipe {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn get_update(&mut self) -> bool {
 | 
					    pub fn is_atime_update(&mut self) -> bool {
 | 
				
			||||||
        let atime = Self::get_pipe_atime(&self.pipe_file);
 | 
					        let atime = Self::get_pipe_atime(&self.pipe_file);
 | 
				
			||||||
        log::trace!("pipe file access time: {:?}", atime);
 | 
					        log::trace!("pipe file access time: {:?}", atime);
 | 
				
			||||||
        if atime > self.atime {
 | 
					        if atime > self.atime {
 | 
				
			||||||
@@ -198,38 +202,82 @@ impl MsgSyncPipe {
 | 
				
			|||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn set_update(&mut self) {
 | 
					    /* 请求发送消息,向status文件写入请求状态 */
 | 
				
			||||||
        // read pipe file to update access time
 | 
					    pub fn request_msg(&mut self) {
 | 
				
			||||||
        // let mut file = File::options().read(true).open(&self.pipe_file).unwrap();
 | 
					        let mut file = File::options().write(true).open(&self.status_file).unwrap();
 | 
				
			||||||
        // let mut buffer = Vec::new();
 | 
					        let _ = file.write("REQUEST".as_bytes());
 | 
				
			||||||
        // log::trace!("try update pipe file access time");
 | 
					 | 
				
			||||||
        // let _ = file.read_to_end(&mut buffer);
 | 
					 | 
				
			||||||
        let mut file = File::options().write(true).open(&self.pipe_file).unwrap();
 | 
					 | 
				
			||||||
        let _ = file.write("sstar_l0l3clip_sync".as_bytes());
 | 
					 | 
				
			||||||
        drop(file);
 | 
					        drop(file);
 | 
				
			||||||
        self.get_update();
 | 
					    }
 | 
				
			||||||
 | 
					    /* 检查对方是否已经发送了消息 */
 | 
				
			||||||
 | 
					    pub fn is_sent_msg(&mut self) -> bool {
 | 
				
			||||||
 | 
					        self.is_atime_update()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    /* 清除发送消息的状态,在知道对方已经发送了消息的时候进行清除 */
 | 
				
			||||||
 | 
					    pub fn clean_request(&mut self) {
 | 
				
			||||||
 | 
					        let mut file = File::options().write(true).open(&self.status_file).unwrap();
 | 
				
			||||||
 | 
					        let _ = file.write("IDLE".as_bytes());
 | 
				
			||||||
 | 
					        drop(file);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    /* sync一下目前的pipe的atime,用来同步一下两边记录的值 */
 | 
				
			||||||
 | 
					    pub fn status_sync(&mut self) -> bool {
 | 
				
			||||||
 | 
					        self.is_atime_update()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn is_request_msg(&mut self) -> bool {
 | 
				
			||||||
 | 
					        let mut file = File::options().read(true).open(&self.status_file).unwrap();
 | 
				
			||||||
 | 
					        let mut buffer = Vec::new();
 | 
				
			||||||
 | 
					        let _ = file.read_to_end(&mut buffer);
 | 
				
			||||||
 | 
					        let status = String::from_utf8(buffer).unwrap();
 | 
				
			||||||
 | 
					        if status == "REQUEST" {
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn reply_msg(&mut self) {
 | 
				
			||||||
 | 
					        // read pipe file to update access time
 | 
				
			||||||
 | 
					        #[cfg(features = "atime_read")]
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            let mut file = File::options().read(true).open(&self.pipe_file).unwrap();
 | 
				
			||||||
 | 
					            let mut buffer = Vec::new();
 | 
				
			||||||
 | 
					            let _ = file.read_to_end(&mut buffer);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        #[cfg(not(features = "atime_read"))]
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            let mut file = File::options().write(true).open(&self.pipe_file).unwrap();
 | 
				
			||||||
 | 
					            let _ = file.write("sstar_l0l3clip_sync".as_bytes());
 | 
				
			||||||
 | 
					            drop(file);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        self.status_sync();
 | 
				
			||||||
        log::trace!("pipe file access time updated: {:?}", self.atime);
 | 
					        log::trace!("pipe file access time updated: {:?}", self.atime);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn get_consumer_pipe() -> Result<String, Box<dyn Error>> {
 | 
					    fn get_consumer_pipe() -> Result<(String, String), Box<dyn Error>> {
 | 
				
			||||||
        let path = match dirs::home_dir() {
 | 
					        let path = match dirs::home_dir() {
 | 
				
			||||||
            Some(path) => path,
 | 
					            Some(path) => path,
 | 
				
			||||||
            None => return Err("can not get user HOME dir".into()),
 | 
					            None => return Err("can not get user HOME dir".into()),
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        let path = path.join(".sstar_l0l3clip_sync");
 | 
					        // 这里希望通过两个文件来实现同步,一个是共享的pipe 标志文件,一个是请求状态文件。
 | 
				
			||||||
 | 
					        // 共享的pipe标志文件用于标识有新的消息需要发送,请求状态文件用于记录当前请求状态。
 | 
				
			||||||
 | 
					        let path = path.join("sstar_l0l3clip_sync");
 | 
				
			||||||
 | 
					        let sync_pipe = path.join("sync_pipe");
 | 
				
			||||||
 | 
					        let req_status = path.join("req_status");
 | 
				
			||||||
        if !path.exists() {
 | 
					        if !path.exists() {
 | 
				
			||||||
            let mut file = fs::OpenOptions::new().create(true).write(true).open(&path)?;
 | 
					            fs::create_dir(&path)?;
 | 
				
			||||||
            let _ = file.write("sstar_l0l3clip_sync".as_bytes());
 | 
					            let mut file = fs::OpenOptions::new().create(true).write(true).open(&sync_pipe)?;
 | 
				
			||||||
 | 
					            let _ = file.write("sync_pipe".as_bytes());
 | 
				
			||||||
 | 
					            let mut file = fs::OpenOptions::new().create(true).write(true).open(&req_status)?;
 | 
				
			||||||
 | 
					            let _ = file.write("IDLE".as_bytes());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Ok(path.to_str().unwrap().to_string())
 | 
					        Ok((sync_pipe.to_str().unwrap().to_string(), req_status.to_str().unwrap().to_string()))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn get_producer_pipe() -> Result<String, Box<dyn Error>> {
 | 
					    fn get_producer_pipe() -> Result<(String,String), Box<dyn Error>> {
 | 
				
			||||||
        let path = match dirs::home_dir() {
 | 
					        let path = match dirs::home_dir() {
 | 
				
			||||||
            Some(path) => path,
 | 
					            Some(path) => path,
 | 
				
			||||||
            None => return Err("can not get home dir".into()),
 | 
					            None => return Err("can not get home dir".into()),
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        let path = path.join(".sstar_l0l3clip_sync").to_str().unwrap().to_string();
 | 
					        let path = path.join("sstar_l0l3clip_sync").to_str().unwrap().to_string();
 | 
				
			||||||
 | 
					        // 切割一下将盘符去掉留下剩下的部分方便匹配
 | 
				
			||||||
        let mut path = path.split(':').into_iter();
 | 
					        let mut path = path.split(':').into_iter();
 | 
				
			||||||
        let _ = path.next(); //ignore driver letter
 | 
					        let _ = path.next(); //ignore driver letter
 | 
				
			||||||
        let sub_path = path.next().unwrap().to_string();
 | 
					        let sub_path = path.next().unwrap().to_string();
 | 
				
			||||||
@@ -237,10 +285,12 @@ impl MsgSyncPipe {
 | 
				
			|||||||
            let sub_path = format!("{}:{}", drive, sub_path);
 | 
					            let sub_path = format!("{}:{}", drive, sub_path);
 | 
				
			||||||
            let sub_path = sub_path.replace("baoyucang", "BYC10");
 | 
					            let sub_path = sub_path.replace("baoyucang", "BYC10");
 | 
				
			||||||
            log::trace!("trying to find pipe file in {}", sub_path);
 | 
					            log::trace!("trying to find pipe file in {}", sub_path);
 | 
				
			||||||
            if Path::new(&sub_path).exists() {
 | 
					            let sync_pipe = Path::new(&sub_path).join("sync_pipe");
 | 
				
			||||||
                return Ok(sub_path);
 | 
					            let req_status = Path::new(&sub_path).join("req_status");
 | 
				
			||||||
 | 
					            if req_status.exists() && sync_pipe.exists(){
 | 
				
			||||||
 | 
					                return Ok((sync_pipe.to_str().unwrap().to_string(), req_status.to_str().unwrap().to_string()))
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        };
 | 
				
			||||||
        return Err("You should mapping l0 c:\\ to l3".into())
 | 
					        return Err("You should mapping l0 c:\\ to l3".into())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -256,6 +306,7 @@ async fn msg_reciver(ctx:Arc<Mutex<ClipboardSync>>) {
 | 
				
			|||||||
        prog_name == vm_exe_name
 | 
					        prog_name == vm_exe_name
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    let mut state_time = time::Instant::now();
 | 
					    let mut state_time = time::Instant::now();
 | 
				
			||||||
 | 
					    ctx.pipe.status_sync();
 | 
				
			||||||
    loop{
 | 
					    loop{
 | 
				
			||||||
        // log::trace!("current state is {:?}", sta);
 | 
					        // log::trace!("current state is {:?}", sta);
 | 
				
			||||||
        match sta{
 | 
					        match sta{
 | 
				
			||||||
@@ -275,7 +326,7 @@ async fn msg_reciver(ctx:Arc<Mutex<ClipboardSync>>) {
 | 
				
			|||||||
                if !on_vm() {
 | 
					                if !on_vm() {
 | 
				
			||||||
                    turn_time = 0;
 | 
					                    turn_time = 0;
 | 
				
			||||||
                    //请求远端发送消息
 | 
					                    //请求远端发送消息
 | 
				
			||||||
                    ctx.pipe.set_update();
 | 
					                    ctx.pipe.request_msg();
 | 
				
			||||||
                    sta = MsgSyncState::WaitingSendMsg;
 | 
					                    sta = MsgSyncState::WaitingSendMsg;
 | 
				
			||||||
                    state_time = time::Instant::now();
 | 
					                    state_time = time::Instant::now();
 | 
				
			||||||
                    log::trace!("waiting for remote send msg...");
 | 
					                    log::trace!("waiting for remote send msg...");
 | 
				
			||||||
@@ -284,10 +335,16 @@ async fn msg_reciver(ctx:Arc<Mutex<ClipboardSync>>) {
 | 
				
			|||||||
            MsgSyncState::WaitingSendMsg => {
 | 
					            MsgSyncState::WaitingSendMsg => {
 | 
				
			||||||
                turn_time = 50;
 | 
					                turn_time = 50;
 | 
				
			||||||
                // 如果这里检测到了对方更新了文件状态,说明其已经发送完毕消息,我们开始时接收。
 | 
					                // 如果这里检测到了对方更新了文件状态,说明其已经发送完毕消息,我们开始时接收。
 | 
				
			||||||
                if ctx.pipe.get_update() {
 | 
					                if ctx.pipe.is_sent_msg() {
 | 
				
			||||||
 | 
					                    ctx.pipe.clean_request();
 | 
				
			||||||
                    sta = MsgSyncState::WaitingRecMsg;
 | 
					                    sta = MsgSyncState::WaitingRecMsg;
 | 
				
			||||||
                    turn_time = 0;
 | 
					                    turn_time = 0;
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
 | 
					                    if on_vm() {
 | 
				
			||||||
 | 
					                        // 如果鼠标移到了VM窗口,那么就切换
 | 
				
			||||||
 | 
					                        sta = MsgSyncState::FocusOnVM;
 | 
				
			||||||
 | 
					                        turn_time = 0;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                    //最多等待1秒钟,如果超过1秒钟还没收到消息,那么就切换到空闲状态
 | 
					                    //最多等待1秒钟,如果超过1秒钟还没收到消息,那么就切换到空闲状态
 | 
				
			||||||
                    if time::Instant::now() - state_time > Duration::new(1, 0) {
 | 
					                    if time::Instant::now() - state_time > Duration::new(1, 0) {
 | 
				
			||||||
                        sta = MsgSyncState::Idle;
 | 
					                        sta = MsgSyncState::Idle;
 | 
				
			||||||
@@ -309,14 +366,38 @@ async fn msg_reciver(ctx:Arc<Mutex<ClipboardSync>>) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 同步获取消息的线程
 | 
					struct CursorCtrl{
 | 
				
			||||||
async fn msg_sender(ctx:Arc<Mutex<ClipboardSync>>) {
 | 
					    pub x: i32,
 | 
				
			||||||
    let mut ctx = ctx.lock().await;
 | 
					    pub y: i32,
 | 
				
			||||||
    let mut sta = MsgSyncState::Idle;
 | 
					    is_edge: bool,
 | 
				
			||||||
    let mut turn_time;
 | 
					    state: CursorState,
 | 
				
			||||||
    fn on_edge() -> bool {
 | 
					}
 | 
				
			||||||
        let (width, height) = sys_res::screen_size();
 | 
					
 | 
				
			||||||
 | 
					#[derive(PartialEq,Copy, Clone)]
 | 
				
			||||||
 | 
					enum CursorState {
 | 
				
			||||||
 | 
					    Standby,
 | 
				
			||||||
 | 
					    StandbyEdge,
 | 
				
			||||||
 | 
					    StandbyCenter,
 | 
				
			||||||
 | 
					    Move2Edge,
 | 
				
			||||||
 | 
					    Move2Center,
 | 
				
			||||||
 | 
					    MovingCenter,
 | 
				
			||||||
 | 
					    MovingEdge,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl CursorCtrl{
 | 
				
			||||||
 | 
					    pub fn new() -> Self {
 | 
				
			||||||
        let (x,y) = sys_res::cursor_pos();
 | 
					        let (x,y) = sys_res::cursor_pos();
 | 
				
			||||||
 | 
					        Self {
 | 
				
			||||||
 | 
					            x,
 | 
				
			||||||
 | 
					            y,
 | 
				
			||||||
 | 
					            is_edge: false,
 | 
				
			||||||
 | 
					            state: CursorState::Standby,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn on_edge(x:i32, y:i32) -> bool {
 | 
				
			||||||
 | 
					        let (width, height) = sys_res::screen_size();
 | 
				
			||||||
 | 
					        // let (x,y) = sys_res::cursor_pos();
 | 
				
			||||||
        let margin = 20;
 | 
					        let margin = 20;
 | 
				
			||||||
        if x < margin ||  y< margin || x > width - margin || y > height - margin {
 | 
					        if x < margin ||  y< margin || x > width - margin || y > height - margin {
 | 
				
			||||||
            return true
 | 
					            return true
 | 
				
			||||||
@@ -324,43 +405,172 @@ async fn msg_sender(ctx:Arc<Mutex<ClipboardSync>>) {
 | 
				
			|||||||
        log::trace!("cursor pos:({},{})", x, y);
 | 
					        log::trace!("cursor pos:({},{})", x, y);
 | 
				
			||||||
        false
 | 
					        false
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn get_sta(&mut self) -> CursorState {
 | 
				
			||||||
 | 
					        let (x,y) = sys_res::cursor_pos();
 | 
				
			||||||
 | 
					        let mut is_moving = false;
 | 
				
			||||||
 | 
					        if x != self.x || y != self.y {
 | 
				
			||||||
 | 
					            is_moving = true;
 | 
				
			||||||
 | 
					            self.is_edge = CursorCtrl::on_edge(x,y);
 | 
				
			||||||
 | 
					            self.x = x;
 | 
				
			||||||
 | 
					            self.y = y;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        self.state = match self.state {
 | 
				
			||||||
 | 
					            CursorState::Standby => {
 | 
				
			||||||
 | 
					                if is_moving {
 | 
				
			||||||
 | 
					                    if self.is_edge {
 | 
				
			||||||
 | 
					                        CursorState::MovingEdge
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        CursorState::MovingCenter
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    if self.is_edge {
 | 
				
			||||||
 | 
					                        CursorState::StandbyEdge
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        CursorState::StandbyCenter
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            CursorState::StandbyEdge => {
 | 
				
			||||||
 | 
					                if is_moving {
 | 
				
			||||||
 | 
					                    if self.is_edge {
 | 
				
			||||||
 | 
					                        CursorState::MovingEdge
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        CursorState::Move2Center
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    CursorState::StandbyEdge
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            CursorState::StandbyCenter => {
 | 
				
			||||||
 | 
					                if is_moving {
 | 
				
			||||||
 | 
					                    if self.is_edge {
 | 
				
			||||||
 | 
					                        CursorState::Move2Edge
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        CursorState::MovingCenter
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    CursorState::StandbyCenter
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            CursorState::Move2Edge => {
 | 
				
			||||||
 | 
					                if is_moving {
 | 
				
			||||||
 | 
					                    if self.is_edge {
 | 
				
			||||||
 | 
					                        CursorState::MovingEdge
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        CursorState::Move2Center
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    CursorState::StandbyEdge
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            CursorState::Move2Center => {
 | 
				
			||||||
 | 
					                if is_moving {
 | 
				
			||||||
 | 
					                    if self.is_edge {
 | 
				
			||||||
 | 
					                        CursorState::Move2Edge
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        CursorState::MovingCenter
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    CursorState::StandbyCenter
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            CursorState::MovingCenter => {
 | 
				
			||||||
 | 
					                if is_moving {
 | 
				
			||||||
 | 
					                    if self.is_edge {
 | 
				
			||||||
 | 
					                        CursorState::Move2Edge
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        CursorState::MovingCenter
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    CursorState::StandbyCenter
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            CursorState::MovingEdge => {
 | 
				
			||||||
 | 
					                if is_moving {
 | 
				
			||||||
 | 
					                    if self.is_edge {
 | 
				
			||||||
 | 
					                        CursorState::MovingEdge
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        CursorState::Move2Center
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    CursorState::StandbyEdge
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        self.state
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 发送消息的线程
 | 
				
			||||||
 | 
					async fn msg_sender(ctx:Arc<Mutex<ClipboardSync>>) {
 | 
				
			||||||
 | 
					    let mut ctx = ctx.lock().await;
 | 
				
			||||||
 | 
					    let mut sta = MsgSyncState::Idle;
 | 
				
			||||||
 | 
					    let mut turn_time;
 | 
				
			||||||
 | 
					    let mut state_time = time::Instant::now();
 | 
				
			||||||
    loop{
 | 
					    loop{
 | 
				
			||||||
        // log::trace!("current state is {:?}", sta);
 | 
					        // log::trace!("current state is {:?}", sta);
 | 
				
			||||||
        match sta{
 | 
					        match sta{
 | 
				
			||||||
            MsgSyncState::Idle => {
 | 
					            MsgSyncState::Idle => {
 | 
				
			||||||
                turn_time = 0;
 | 
					                turn_time = 0;
 | 
				
			||||||
                // 更新下最新的文件状态,保证后续判断准确
 | 
					                // 更新下最新的文件状态,保证后续判断准确
 | 
				
			||||||
                ctx.pipe.get_update(); // refresh pipe file status
 | 
					                ctx.pipe.status_sync(); // refresh pipe file status
 | 
				
			||||||
                sta = MsgSyncState::FocusOnVM;
 | 
					                sta = MsgSyncState::FocusOnVM;
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            MsgSyncState::FocusOnVM => {
 | 
					            MsgSyncState::FocusOnVM => {
 | 
				
			||||||
                turn_time = 100;
 | 
					                let cursor = ctx.cursor.get_sta();
 | 
				
			||||||
                // 当前处于窗口边缘,尝试切换到发送消息的逻辑:等待对方请求发送
 | 
					                match cursor {
 | 
				
			||||||
                if on_edge() {
 | 
					                    CursorState::MovingCenter => {
 | 
				
			||||||
 | 
					                        turn_time = 200;
 | 
				
			||||||
 | 
					                        state_time = time::Instant::now();
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    CursorState::Move2Center => {
 | 
				
			||||||
 | 
					                        turn_time = 200;
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    CursorState::StandbyCenter => {
 | 
				
			||||||
 | 
					                        turn_time = 100;
 | 
				
			||||||
 | 
					                        if state_time.elapsed() > Duration::new(1, 0) {
 | 
				
			||||||
 | 
					                            turn_time = 200;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    CursorState::MovingEdge => {
 | 
				
			||||||
 | 
					                        turn_time = 100;
 | 
				
			||||||
 | 
					                        state_time = time::Instant::now();
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    CursorState::Move2Edge => {
 | 
				
			||||||
 | 
					                        turn_time = 100;
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    // 当前处于窗口边缘,尝试切换到发送消息的逻辑:等待对方请求发送
 | 
				
			||||||
 | 
					                    CursorState::StandbyEdge => {
 | 
				
			||||||
 | 
					                        turn_time = 50;
 | 
				
			||||||
 | 
					                        if state_time.elapsed() > Duration::new(1, 0) {
 | 
				
			||||||
 | 
					                            turn_time = 200;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    _ => {
 | 
				
			||||||
 | 
					                        turn_time = 100;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if ctx.pipe.is_request_msg() {
 | 
				
			||||||
                    sta = MsgSyncState::WaitingSendMsg;
 | 
					                    sta = MsgSyncState::WaitingSendMsg;
 | 
				
			||||||
                    turn_time = 0;
 | 
					                    turn_time = 0;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            MsgSyncState::WaitingSendMsg => {
 | 
					            MsgSyncState::WaitingSendMsg => {
 | 
				
			||||||
                turn_time = 50;
 | 
					                let _ = ctx.clip2msg().await;
 | 
				
			||||||
                // 如果对方需要发送消息那么他会更新atime,这里就尝试发送消息
 | 
					                log::trace!("send msg done");
 | 
				
			||||||
                if ctx.pipe.get_update() {
 | 
					                turn_time = 0;
 | 
				
			||||||
                    let _ = ctx.clip2msg().await;
 | 
					                sta = MsgSyncState::WaitingRecMsg;
 | 
				
			||||||
                    log::trace!("send msg done");
 | 
					                ctx.pipe.reply_msg();
 | 
				
			||||||
                    turn_time = 0;
 | 
					 | 
				
			||||||
                    sta = MsgSyncState::WaitingRecMsg;
 | 
					 | 
				
			||||||
                    ctx.pipe.set_update();//sent ok set update flag
 | 
					 | 
				
			||||||
                // 如果文件没更新说明不需要发送消息,并且鼠标也不在边缘说明重新移回VM窗口内了,可以切换到等待状态
 | 
					 | 
				
			||||||
                } else if !on_edge()  {
 | 
					 | 
				
			||||||
                    turn_time = 0;
 | 
					 | 
				
			||||||
                    sta = MsgSyncState::Idle;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            MsgSyncState::WaitingRecMsg => {
 | 
					            MsgSyncState::WaitingRecMsg => {
 | 
				
			||||||
                turn_time = 0;
 | 
					                turn_time = 0;
 | 
				
			||||||
                sta = MsgSyncState::Idle;
 | 
					                sta = MsgSyncState::Idle;
 | 
				
			||||||
                // 发送消息后鼠标还是保持在边缘说明当前鼠标还是在VM窗口外面,需要等待鼠标移动到VM窗口内,然后再发送消息
 | 
					                // 发送消息后鼠标还是保持在边缘说明当前鼠标还是在VM窗口外面,需要等待鼠标移动到VM窗口内,然后再发送消息
 | 
				
			||||||
                if on_edge()  {
 | 
					                let cursor = ctx.cursor.get_sta();
 | 
				
			||||||
 | 
					                if cursor == CursorState::Standby ||
 | 
				
			||||||
 | 
					                    cursor == CursorState::StandbyEdge  ||
 | 
				
			||||||
 | 
					                    cursor == CursorState::StandbyCenter {
 | 
				
			||||||
                    turn_time = 100;
 | 
					                    turn_time = 100;
 | 
				
			||||||
                    sta = MsgSyncState::WaitingRecMsg;
 | 
					                    sta = MsgSyncState::WaitingRecMsg;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@@ -400,7 +610,9 @@ impl ClipboardSync {
 | 
				
			|||||||
            clip: wclip::Wclip::new(),
 | 
					            clip: wclip::Wclip::new(),
 | 
				
			||||||
            cfg: Config::new(info_file)?,
 | 
					            cfg: Config::new(info_file)?,
 | 
				
			||||||
            pipe: MsgSyncPipe::new(c)?,
 | 
					            pipe: MsgSyncPipe::new(c)?,
 | 
				
			||||||
 | 
					            cursor: CursorCtrl::new(),
 | 
				
			||||||
            characters: c.clone(),
 | 
					            characters: c.clone(),
 | 
				
			||||||
 | 
					            recent_msg: String::new(),
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -666,9 +878,18 @@ impl ClipboardSync {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    pub async fn clip2msg(&mut self) {
 | 
					    pub async fn clip2msg(&mut self) {
 | 
				
			||||||
        let msg = match self.clip.get() {
 | 
					        let msg = match self.clip.get() {
 | 
				
			||||||
            Some(msg) => match self.split_msg(&msg).await {
 | 
					            Some(msg) => {
 | 
				
			||||||
                Ok(msgs) => msgs,
 | 
					                let split = match self.split_msg(&msg).await {
 | 
				
			||||||
                Err(_) => return,
 | 
					                    Ok(msgs) => msgs,
 | 
				
			||||||
 | 
					                    Err(_) => return,
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					                if self.recent_msg != msg {
 | 
				
			||||||
 | 
					                    self.recent_msg = msg;
 | 
				
			||||||
 | 
					                    split
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    log::info!("msg is same as last time, ignore it");
 | 
				
			||||||
 | 
					                    Vec::<String>::new()
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            None => {
 | 
					            None => {
 | 
				
			||||||
                log::info!("clipboard is not string, ignore it");
 | 
					                log::info!("clipboard is not string, ignore it");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,7 +39,7 @@ pub fn get_foredround_window_rect() -> Option<(i32, i32, i32, i32)> {
 | 
				
			|||||||
            println!("GetWindowRect: {:?}", rect);
 | 
					            println!("GetWindowRect: {:?}", rect);
 | 
				
			||||||
            Some((rect.left, rect.top, rect.right, rect.bottom))
 | 
					            Some((rect.left, rect.top, rect.right, rect.bottom))
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            log::error!("cant get foregtound window rect");
 | 
					            log::error!("Cant get foreground window rect");
 | 
				
			||||||
            None
 | 
					            None
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -58,7 +58,7 @@ pub fn get_foredround_window_name() -> String {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        let process_handle = OpenProcess(PROCESS_QUERY_INFORMATION, 0, process_id);
 | 
					        let process_handle = OpenProcess(PROCESS_QUERY_INFORMATION, 0, process_id);
 | 
				
			||||||
        if process_handle.is_null() {
 | 
					        if process_handle.is_null() {
 | 
				
			||||||
            log::error!("Cant open foreground process with {}!", process_id);
 | 
					            log::warn!("process {} cant process handle!", process_id);
 | 
				
			||||||
            return "".to_string();
 | 
					            return "".to_string();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user