1. 完善发送的逻辑,使用状态机和鼠标以及pip_file一同进行管理
2. 自测已可正常发送接收 3. atime的管理使用write还是read去更新需要使用宏来控制。目前已coding完毕等待调试
This commit is contained in:
		@@ -27,3 +27,7 @@ dirs = "4.0"
 | 
			
		||||
 | 
			
		||||
[profile.test]
 | 
			
		||||
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,
 | 
			
		||||
    cfg: Config,
 | 
			
		||||
    pipe: MsgSyncPipe,
 | 
			
		||||
    cursor: CursorCtrl,
 | 
			
		||||
    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";
 | 
			
		||||
@@ -157,6 +159,7 @@ pub enum Character {
 | 
			
		||||
}
 | 
			
		||||
struct MsgSyncPipe {
 | 
			
		||||
    pub pipe_file: String,
 | 
			
		||||
    pub status_file: String,
 | 
			
		||||
    atime: Duration,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -167,13 +170,14 @@ struct MsgSyncPipe {
 | 
			
		||||
 */
 | 
			
		||||
impl MsgSyncPipe {
 | 
			
		||||
    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::Consumer => Self::get_consumer_pipe()?,
 | 
			
		||||
        };
 | 
			
		||||
        let atime = Self::get_pipe_atime(&pipe_file);
 | 
			
		||||
        Ok(MsgSyncPipe {
 | 
			
		||||
            pipe_file,
 | 
			
		||||
            status_file,
 | 
			
		||||
            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);
 | 
			
		||||
        log::trace!("pipe file access time: {:?}", atime);
 | 
			
		||||
        if atime > self.atime {
 | 
			
		||||
@@ -198,38 +202,82 @@ impl MsgSyncPipe {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn set_update(&mut self) {
 | 
			
		||||
        // read pipe file to update access time
 | 
			
		||||
        // let mut file = File::options().read(true).open(&self.pipe_file).unwrap();
 | 
			
		||||
        // let mut buffer = Vec::new();
 | 
			
		||||
        // 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());
 | 
			
		||||
    /* 请求发送消息,向status文件写入请求状态 */
 | 
			
		||||
    pub fn request_msg(&mut self) {
 | 
			
		||||
        let mut file = File::options().write(true).open(&self.status_file).unwrap();
 | 
			
		||||
        let _ = file.write("REQUEST".as_bytes());
 | 
			
		||||
        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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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() {
 | 
			
		||||
            Some(path) => path,
 | 
			
		||||
            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() {
 | 
			
		||||
            let mut file = fs::OpenOptions::new().create(true).write(true).open(&path)?;
 | 
			
		||||
            let _ = file.write("sstar_l0l3clip_sync".as_bytes());
 | 
			
		||||
            fs::create_dir(&path)?;
 | 
			
		||||
            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() {
 | 
			
		||||
            Some(path) => path,
 | 
			
		||||
            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 _ = path.next(); //ignore driver letter
 | 
			
		||||
        let sub_path = path.next().unwrap().to_string();
 | 
			
		||||
@@ -237,10 +285,12 @@ impl MsgSyncPipe {
 | 
			
		||||
            let sub_path = format!("{}:{}", drive, sub_path);
 | 
			
		||||
            let sub_path = sub_path.replace("baoyucang", "BYC10");
 | 
			
		||||
            log::trace!("trying to find pipe file in {}", sub_path);
 | 
			
		||||
            if Path::new(&sub_path).exists() {
 | 
			
		||||
                return Ok(sub_path);
 | 
			
		||||
            let sync_pipe = Path::new(&sub_path).join("sync_pipe");
 | 
			
		||||
            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())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -256,6 +306,7 @@ async fn msg_reciver(ctx:Arc<Mutex<ClipboardSync>>) {
 | 
			
		||||
        prog_name == vm_exe_name
 | 
			
		||||
    }
 | 
			
		||||
    let mut state_time = time::Instant::now();
 | 
			
		||||
    ctx.pipe.status_sync();
 | 
			
		||||
    loop{
 | 
			
		||||
        // log::trace!("current state is {:?}", sta);
 | 
			
		||||
        match sta{
 | 
			
		||||
@@ -275,7 +326,7 @@ async fn msg_reciver(ctx:Arc<Mutex<ClipboardSync>>) {
 | 
			
		||||
                if !on_vm() {
 | 
			
		||||
                    turn_time = 0;
 | 
			
		||||
                    //请求远端发送消息
 | 
			
		||||
                    ctx.pipe.set_update();
 | 
			
		||||
                    ctx.pipe.request_msg();
 | 
			
		||||
                    sta = MsgSyncState::WaitingSendMsg;
 | 
			
		||||
                    state_time = time::Instant::now();
 | 
			
		||||
                    log::trace!("waiting for remote send msg...");
 | 
			
		||||
@@ -284,10 +335,16 @@ async fn msg_reciver(ctx:Arc<Mutex<ClipboardSync>>) {
 | 
			
		||||
            MsgSyncState::WaitingSendMsg => {
 | 
			
		||||
                turn_time = 50;
 | 
			
		||||
                // 如果这里检测到了对方更新了文件状态,说明其已经发送完毕消息,我们开始时接收。
 | 
			
		||||
                if ctx.pipe.get_update() {
 | 
			
		||||
                if ctx.pipe.is_sent_msg() {
 | 
			
		||||
                    ctx.pipe.clean_request();
 | 
			
		||||
                    sta = MsgSyncState::WaitingRecMsg;
 | 
			
		||||
                    turn_time = 0;
 | 
			
		||||
                } else {
 | 
			
		||||
                    if on_vm() {
 | 
			
		||||
                        // 如果鼠标移到了VM窗口,那么就切换
 | 
			
		||||
                        sta = MsgSyncState::FocusOnVM;
 | 
			
		||||
                        turn_time = 0;
 | 
			
		||||
                    }
 | 
			
		||||
                    //最多等待1秒钟,如果超过1秒钟还没收到消息,那么就切换到空闲状态
 | 
			
		||||
                    if time::Instant::now() - state_time > Duration::new(1, 0) {
 | 
			
		||||
                        sta = MsgSyncState::Idle;
 | 
			
		||||
@@ -309,14 +366,38 @@ async fn msg_reciver(ctx:Arc<Mutex<ClipboardSync>>) {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 同步获取消息的线程
 | 
			
		||||
async fn msg_sender(ctx:Arc<Mutex<ClipboardSync>>) {
 | 
			
		||||
    let mut ctx = ctx.lock().await;
 | 
			
		||||
    let mut sta = MsgSyncState::Idle;
 | 
			
		||||
    let mut turn_time;
 | 
			
		||||
    fn on_edge() -> bool {
 | 
			
		||||
        let (width, height) = sys_res::screen_size();
 | 
			
		||||
struct CursorCtrl{
 | 
			
		||||
    pub x: i32,
 | 
			
		||||
    pub y: i32,
 | 
			
		||||
    is_edge: bool,
 | 
			
		||||
    state: CursorState,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[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();
 | 
			
		||||
        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;
 | 
			
		||||
        if x < margin ||  y< margin || x > width - margin || y > height - margin {
 | 
			
		||||
            return true
 | 
			
		||||
@@ -324,43 +405,172 @@ async fn msg_sender(ctx:Arc<Mutex<ClipboardSync>>) {
 | 
			
		||||
        log::trace!("cursor pos:({},{})", x, y);
 | 
			
		||||
        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{
 | 
			
		||||
        // log::trace!("current state is {:?}", sta);
 | 
			
		||||
        match sta{
 | 
			
		||||
            MsgSyncState::Idle => {
 | 
			
		||||
                turn_time = 0;
 | 
			
		||||
                // 更新下最新的文件状态,保证后续判断准确
 | 
			
		||||
                ctx.pipe.get_update(); // refresh pipe file status
 | 
			
		||||
                ctx.pipe.status_sync(); // refresh pipe file status
 | 
			
		||||
                sta = MsgSyncState::FocusOnVM;
 | 
			
		||||
            },
 | 
			
		||||
            MsgSyncState::FocusOnVM => {
 | 
			
		||||
                turn_time = 100;
 | 
			
		||||
                // 当前处于窗口边缘,尝试切换到发送消息的逻辑:等待对方请求发送
 | 
			
		||||
                if on_edge() {
 | 
			
		||||
                let cursor = ctx.cursor.get_sta();
 | 
			
		||||
                match cursor {
 | 
			
		||||
                    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;
 | 
			
		||||
                    turn_time = 0;
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            MsgSyncState::WaitingSendMsg => {
 | 
			
		||||
                turn_time = 50;
 | 
			
		||||
                // 如果对方需要发送消息那么他会更新atime,这里就尝试发送消息
 | 
			
		||||
                if ctx.pipe.get_update() {
 | 
			
		||||
                    let _ = ctx.clip2msg().await;
 | 
			
		||||
                    log::trace!("send msg done");
 | 
			
		||||
                    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;
 | 
			
		||||
                }
 | 
			
		||||
                let _ = ctx.clip2msg().await;
 | 
			
		||||
                log::trace!("send msg done");
 | 
			
		||||
                turn_time = 0;
 | 
			
		||||
                sta = MsgSyncState::WaitingRecMsg;
 | 
			
		||||
                ctx.pipe.reply_msg();
 | 
			
		||||
            },
 | 
			
		||||
            MsgSyncState::WaitingRecMsg => {
 | 
			
		||||
                turn_time = 0;
 | 
			
		||||
                sta = MsgSyncState::Idle;
 | 
			
		||||
                // 发送消息后鼠标还是保持在边缘说明当前鼠标还是在VM窗口外面,需要等待鼠标移动到VM窗口内,然后再发送消息
 | 
			
		||||
                if on_edge()  {
 | 
			
		||||
                let cursor = ctx.cursor.get_sta();
 | 
			
		||||
                if cursor == CursorState::Standby ||
 | 
			
		||||
                    cursor == CursorState::StandbyEdge  ||
 | 
			
		||||
                    cursor == CursorState::StandbyCenter {
 | 
			
		||||
                    turn_time = 100;
 | 
			
		||||
                    sta = MsgSyncState::WaitingRecMsg;
 | 
			
		||||
                }
 | 
			
		||||
@@ -400,7 +610,9 @@ impl ClipboardSync {
 | 
			
		||||
            clip: wclip::Wclip::new(),
 | 
			
		||||
            cfg: Config::new(info_file)?,
 | 
			
		||||
            pipe: MsgSyncPipe::new(c)?,
 | 
			
		||||
            cursor: CursorCtrl::new(),
 | 
			
		||||
            characters: c.clone(),
 | 
			
		||||
            recent_msg: String::new(),
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -666,9 +878,18 @@ impl ClipboardSync {
 | 
			
		||||
    }
 | 
			
		||||
    pub async fn clip2msg(&mut self) {
 | 
			
		||||
        let msg = match self.clip.get() {
 | 
			
		||||
            Some(msg) => match self.split_msg(&msg).await {
 | 
			
		||||
                Ok(msgs) => msgs,
 | 
			
		||||
                Err(_) => return,
 | 
			
		||||
            Some(msg) => {
 | 
			
		||||
                let split = match self.split_msg(&msg).await {
 | 
			
		||||
                    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 => {
 | 
			
		||||
                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);
 | 
			
		||||
            Some((rect.left, rect.top, rect.right, rect.bottom))
 | 
			
		||||
        } else {
 | 
			
		||||
            log::error!("cant get foregtound window rect");
 | 
			
		||||
            log::error!("Cant get foreground window rect");
 | 
			
		||||
            None
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -58,7 +58,7 @@ pub fn get_foredround_window_name() -> String {
 | 
			
		||||
 | 
			
		||||
        let process_handle = OpenProcess(PROCESS_QUERY_INFORMATION, 0, process_id);
 | 
			
		||||
        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();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user