refactor: release key of server
This commit is contained in:
		
							parent
							
								
									11c9692278
								
							
						
					
					
						commit
						39f8e2d712
					
				| @ -69,6 +69,7 @@ struct Input { | |||||||
|     y: i32, |     y: i32, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | const KEY_RDEV_START: u64 = 999; | ||||||
| const KEY_CHAR_START: u64 = 9999; | const KEY_CHAR_START: u64 = 9999; | ||||||
| 
 | 
 | ||||||
| #[derive(Clone, Default)] | #[derive(Clone, Default)] | ||||||
| @ -339,7 +340,7 @@ pub fn handle_mouse(evt: &MouseEvent, conn: i32) { | |||||||
| 
 | 
 | ||||||
| pub fn fix_key_down_timeout_loop() { | pub fn fix_key_down_timeout_loop() { | ||||||
|     std::thread::spawn(move || loop { |     std::thread::spawn(move || loop { | ||||||
|         std::thread::sleep(std::time::Duration::from_millis(1_000)); |         std::thread::sleep(std::time::Duration::from_millis(10_000)); | ||||||
|         fix_key_down_timeout(false); |         fix_key_down_timeout(false); | ||||||
|     }); |     }); | ||||||
|     if let Err(err) = ctrlc::set_handler(move || { |     if let Err(err) = ctrlc::set_handler(move || { | ||||||
| @ -360,38 +361,61 @@ pub fn fix_key_down_timeout_at_exit() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[inline] | #[inline] | ||||||
| fn get_layout(key: u32) -> Key { | fn record_key_is_control_key(record_key: u64) -> bool { | ||||||
|     Key::Layout(std::char::from_u32(key).unwrap_or('\0')) |     record_key < KEY_CHAR_START | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn fix_key_down_timeout(force: bool) { | #[inline] | ||||||
|     if KEYS_DOWN.lock().unwrap().is_empty() { | fn record_key_is_chr(record_key: u64) -> bool { | ||||||
|         return; |     KEY_RDEV_START <= record_key && record_key < KEY_CHAR_START | ||||||
|     } | } | ||||||
|     let cloned = (*KEYS_DOWN.lock().unwrap()).clone(); | 
 | ||||||
|     for (key, value) in cloned.into_iter() { | #[inline] | ||||||
|         if force || value.elapsed().as_millis() >= 360_000 { | fn record_key_is_rdev_layout(record_key: u64) -> bool { | ||||||
|             KEYS_DOWN.lock().unwrap().remove(&key); |     KEY_CHAR_START <= record_key | ||||||
|             let key = if key < KEY_CHAR_START { | } | ||||||
|                 if let Some(key) = KEY_MAP.get(&(key as _)) { | 
 | ||||||
|                     Some(*key) | #[inline] | ||||||
|  | fn record_key_to_key(record_key: u64) -> Option<Key> { | ||||||
|  |     if record_key_is_control_key(record_key) { | ||||||
|  |         control_key_value_to_key(record_key as _) | ||||||
|  |     } else if record_key_is_chr(record_key) { | ||||||
|  |         let chr: u32 = (record_key - KEY_CHAR_START) as _; | ||||||
|  |         Some(char_value_to_key(chr)) | ||||||
|     } else { |     } else { | ||||||
|         None |         None | ||||||
|     } |     } | ||||||
|             } else { | } | ||||||
|                 Some(get_layout((key - KEY_CHAR_START) as _)) | 
 | ||||||
|             }; | #[inline] | ||||||
|             if let Some(key) = key { | fn release_record_key(record_key: u64) { | ||||||
|     let func = move || { |     let func = move || { | ||||||
|                     let mut en = ENIGO.lock().unwrap(); |         if record_key_is_rdev_layout(record_key) { | ||||||
|                     en.key_up(key); |             rdev_key_down_or_up(RdevKey::Unknown((record_key - KEY_RDEV_START) as _), false); | ||||||
|  |         } else if let Some(key) = record_key_to_key(record_key) { | ||||||
|  |             ENIGO.lock().unwrap().key_up(key); | ||||||
|             log::debug!("Fixed {:?} timeout", key); |             log::debug!("Fixed {:?} timeout", key); | ||||||
|  |         } | ||||||
|     }; |     }; | ||||||
|  |     
 | ||||||
|     #[cfg(target_os = "macos")] |     #[cfg(target_os = "macos")] | ||||||
|     QUEUE.exec_async(func); |     QUEUE.exec_async(func); | ||||||
|     #[cfg(not(target_os = "macos"))] |     #[cfg(not(target_os = "macos"))] | ||||||
|     func(); |     func(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn fix_key_down_timeout(force: bool) { | ||||||
|  |     let key_down = KEYS_DOWN.lock().unwrap(); | ||||||
|  |     if key_down.is_empty() { | ||||||
|  |         return; | ||||||
|     } |     } | ||||||
|  |     let cloned = (*key_down).clone(); | ||||||
|  |     drop(key_down); | ||||||
|  | 
 | ||||||
|  |     for (record_key, time) in cloned.into_iter() { | ||||||
|  |         if force || time.elapsed().as_millis() >= 360_000 { | ||||||
|  |             record_pressed_key(record_key, false); | ||||||
|  |             release_record_key(record_key); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -685,8 +709,14 @@ fn is_modifier_in_key_event(control_key: ControlKey, key_event: &KeyEvent) -> bo | |||||||
|         .is_some() |         .is_some() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn control_key_to_key(control_key: &EnumOrUnknown<ControlKey>) -> Option<&Key> { | #[inline] | ||||||
|     KEY_MAP.get(&control_key.value()) | fn control_key_value_to_key(value: i32) -> Option<Key> { | ||||||
|  |     KEY_MAP.get(&value).and_then(|k| Some(*k)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[inline] | ||||||
|  | fn char_value_to_key(value: u32) -> Key { | ||||||
|  |     Key::Layout(std::char::from_u32(value).unwrap_or('\0')) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn is_not_same_status(client_locking: bool, remote_locking: bool) -> bool { | fn is_not_same_status(client_locking: bool, remote_locking: bool) -> bool { | ||||||
| @ -772,6 +802,8 @@ fn sync_numlock_capslock_status(key_event: &KeyEvent) { | |||||||
| 
 | 
 | ||||||
| fn map_keyboard_mode(evt: &KeyEvent) { | fn map_keyboard_mode(evt: &KeyEvent) { | ||||||
|     // map mode(1): Send keycode according to the peer platform.
 |     // map mode(1): Send keycode according to the peer platform.
 | ||||||
|  |     record_pressed_key(evt.chr() as u64 + KEY_CHAR_START, evt.down); | ||||||
|  | 
 | ||||||
|     #[cfg(windows)] |     #[cfg(windows)] | ||||||
|     crate::platform::windows::try_change_desktop(); |     crate::platform::windows::try_change_desktop(); | ||||||
| 
 | 
 | ||||||
| @ -798,7 +830,7 @@ fn add_flags_to_enigo(en: &mut Enigo, key_event: &KeyEvent) { | |||||||
|     // When long-pressed the command key, then press and release
 |     // When long-pressed the command key, then press and release
 | ||||||
|     // the Tab key, there should be CGEventFlagCommand in the flag.
 |     // the Tab key, there should be CGEventFlagCommand in the flag.
 | ||||||
|     en.reset_flag(); |     en.reset_flag(); | ||||||
|     for ck in evt.modifiers.iter() { |     for ck in key_event.modifiers.iter() { | ||||||
|         if let Some(key) = KEY_MAP.get(&ck.value()) { |         if let Some(key) = KEY_MAP.get(&ck.value()) { | ||||||
|             en.add_flag(key); |             en.add_flag(key); | ||||||
|         } |         } | ||||||
| @ -818,7 +850,7 @@ fn release_unpressed_modifiers(en: &mut Enigo, key_event: &KeyEvent) { | |||||||
|     fix_modifiers(&key_event.modifiers[..], en, ck_value); |     fix_modifiers(&key_event.modifiers[..], en, ck_value); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn is_altgr_pressed(en: &mut Enigo) -> bool { | fn is_altgr_pressed() -> bool { | ||||||
|     KEYS_DOWN |     KEYS_DOWN | ||||||
|         .lock() |         .lock() | ||||||
|         .unwrap() |         .unwrap() | ||||||
| @ -828,10 +860,10 @@ fn is_altgr_pressed(en: &mut Enigo) -> bool { | |||||||
| 
 | 
 | ||||||
| fn press_modifiers(en: &mut Enigo, key_event: &KeyEvent, to_release: &mut Vec<Key>) { | fn press_modifiers(en: &mut Enigo, key_event: &KeyEvent, to_release: &mut Vec<Key>) { | ||||||
|     for ref ck in key_event.modifiers.iter() { |     for ref ck in key_event.modifiers.iter() { | ||||||
|         if let Some(key) = control_key_to_key(ck) { |         if let Some(key) = control_key_value_to_key(ck.value()) { | ||||||
|             if !is_pressed(key, en) { |             if !is_pressed(&key, en) { | ||||||
|                 #[cfg(target_os = "linux")] |                 #[cfg(target_os = "linux")] | ||||||
|                 if key == &Key::Alt && is_altgr_pressed(en) { |                 if key == Key::Alt && is_altgr_pressed() { | ||||||
|                     continue; |                     continue; | ||||||
|                 } |                 } | ||||||
|                 en.key_down(key.clone()).ok(); |                 en.key_down(key.clone()).ok(); | ||||||
| @ -845,7 +877,7 @@ fn press_modifiers(en: &mut Enigo, key_event: &KeyEvent, to_release: &mut Vec<Ke | |||||||
| 
 | 
 | ||||||
| fn sync_modifiers(en: &mut Enigo, key_event: &KeyEvent, to_release: &mut Vec<Key>) { | fn sync_modifiers(en: &mut Enigo, key_event: &KeyEvent, to_release: &mut Vec<Key>) { | ||||||
|     #[cfg(target_os = "macos")] |     #[cfg(target_os = "macos")] | ||||||
|     add_flag_to_enigo(&mut en, key_event); |     add_flags_to_enigo(en, key_event); | ||||||
| 
 | 
 | ||||||
|     if key_event.down { |     if key_event.down { | ||||||
|         release_unpressed_modifiers(en, key_event); |         release_unpressed_modifiers(en, key_event); | ||||||
| @ -855,44 +887,25 @@ fn sync_modifiers(en: &mut Enigo, key_event: &KeyEvent, to_release: &mut Vec<Key | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn process_control_key(en: &mut Enigo, ck: &EnumOrUnknown<ControlKey>, down: bool) { | fn process_control_key(en: &mut Enigo, ck: &EnumOrUnknown<ControlKey>, down: bool) { | ||||||
|     let mut key_down = KEYS_DOWN.lock().unwrap(); |     if let Some(key) = control_key_value_to_key(ck.value()) { | ||||||
| 
 |  | ||||||
|     if ck.value() == ControlKey::CtrlAltDel.value() { |  | ||||||
|         // have to spawn new thread because send_sas is tokio_main, the caller can not be tokio_main.
 |  | ||||||
|         std::thread::spawn(|| { |  | ||||||
|             allow_err!(send_sas()); |  | ||||||
|         }); |  | ||||||
|     } else if ck.value() == ControlKey::LockScreen.value() { |  | ||||||
|         lock_screen_2(); |  | ||||||
|     } else if let Some(key) = control_key_to_key(ck) { |  | ||||||
|         if down { |         if down { | ||||||
|             en.key_down(key.clone()).ok(); |             en.key_down(key).ok(); | ||||||
|             key_down.insert(ck.value() as _, Instant::now()); |  | ||||||
|         } else { |         } else { | ||||||
|             en.key_up(key.clone()); |             en.key_up(key); | ||||||
|             key_down.remove(&(ck.value() as _)); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[inline] |  | ||||||
| fn chr_to_record_chr(chr: u32) -> u64 { |  | ||||||
|     chr as u64 + KEY_CHAR_START |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[inline] | #[inline] | ||||||
| fn need_to_uppercase(en: &mut Enigo) -> bool { | fn need_to_uppercase(en: &mut Enigo) -> bool { | ||||||
|     get_modifier_state(Key::Shift, en) || get_modifier_state(Key::CapsLock, en) |     get_modifier_state(Key::Shift, en) || get_modifier_state(Key::CapsLock, en) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn process_chr(en: &mut Enigo, chr: u32, down: bool) { | fn process_chr(en: &mut Enigo, chr: u32, down: bool) { | ||||||
|     let mut key_down = KEYS_DOWN.lock().unwrap(); |     let key = char_value_to_key(chr); | ||||||
|     let key = get_layout(chr); |  | ||||||
|     let record_chr = chr_to_record_chr(chr); |  | ||||||
| 
 | 
 | ||||||
|     if down { |     if down { | ||||||
|         if en.key_down(key).is_ok() { |         if en.key_down(key).is_ok() { | ||||||
|             key_down.insert(record_chr, Instant::now()); |  | ||||||
|         } else { |         } else { | ||||||
|             if let Ok(chr) = char::try_from(chr) { |             if let Ok(chr) = char::try_from(chr) { | ||||||
|                 let mut s = chr.to_string(); |                 let mut s = chr.to_string(); | ||||||
| @ -902,10 +915,8 @@ fn process_chr(en: &mut Enigo, chr: u32, down: bool) { | |||||||
|                 en.key_sequence(&s); |                 en.key_sequence(&s); | ||||||
|             }; |             }; | ||||||
|         } |         } | ||||||
|         key_down.insert(record_chr, Instant::now()); |  | ||||||
|     } else { |     } else { | ||||||
|         en.key_up(key); |         en.key_up(key); | ||||||
|         key_down.remove(&record_chr); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -925,10 +936,33 @@ fn release_keys(en: &mut Enigo, to_release: &Vec<Key>) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | fn record_pressed_key(record_key: u64, down: bool) { | ||||||
|  |     let mut key_down = KEYS_DOWN.lock().unwrap(); | ||||||
|  |     if down { | ||||||
|  |         key_down.insert(record_key, Instant::now()); | ||||||
|  |     } else { | ||||||
|  |         key_down.remove(&record_key); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn is_function_key(ck: &EnumOrUnknown<ControlKey>) -> bool { | ||||||
|  |     let mut res = false; | ||||||
|  |     if ck.value() == ControlKey::CtrlAltDel.value() { | ||||||
|  |         // have to spawn new thread because send_sas is tokio_main, the caller can not be tokio_main.
 | ||||||
|  |         std::thread::spawn(|| { | ||||||
|  |             allow_err!(send_sas()); | ||||||
|  |         }); | ||||||
|  |         res = true; | ||||||
|  |     } else if ck.value() == ControlKey::LockScreen.value() { | ||||||
|  |         lock_screen_2(); | ||||||
|  |         res = true; | ||||||
|  |     } | ||||||
|  |     return res; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| fn legacy_keyboard_mode(evt: &KeyEvent) { | fn legacy_keyboard_mode(evt: &KeyEvent) { | ||||||
|     #[cfg(windows)] |     #[cfg(windows)] | ||||||
|     crate::platform::windows::try_change_desktop(); |     crate::platform::windows::try_change_desktop(); | ||||||
|     #[cfg(not(target_os = "macos"))] |  | ||||||
|     let mut to_release: Vec<Key> = Vec::new(); |     let mut to_release: Vec<Key> = Vec::new(); | ||||||
| 
 | 
 | ||||||
|     let mut en = ENIGO.lock().unwrap(); |     let mut en = ENIGO.lock().unwrap(); | ||||||
| @ -936,8 +970,19 @@ fn legacy_keyboard_mode(evt: &KeyEvent) { | |||||||
| 
 | 
 | ||||||
|     let down = evt.down; |     let down = evt.down; | ||||||
|     match evt.union { |     match evt.union { | ||||||
|         Some(key_event::Union::ControlKey(ck)) => process_control_key(&mut en, &ck, down), |         Some(key_event::Union::ControlKey(ck)) => { | ||||||
|         Some(key_event::Union::Chr(chr)) => process_chr(&mut en, chr, down), |             if is_function_key(&ck) { | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |             let record_key = ck.value() as u64; | ||||||
|  |             record_pressed_key(record_key, down); | ||||||
|  |             process_control_key(&mut en, &ck, down) | ||||||
|  |         } | ||||||
|  |         Some(key_event::Union::Chr(chr)) => { | ||||||
|  |             let record_key = chr as u64 + KEY_CHAR_START; | ||||||
|  |             record_pressed_key(record_key, down); | ||||||
|  |             process_chr(&mut en, chr, down) | ||||||
|  |         } | ||||||
|         Some(key_event::Union::Unicode(chr)) => process_unicode(&mut en, chr), |         Some(key_event::Union::Unicode(chr)) => process_unicode(&mut en, chr), | ||||||
|         Some(key_event::Union::Seq(ref seq)) => process_seq(&mut en, seq), |         Some(key_event::Union::Seq(ref seq)) => process_seq(&mut en, seq), | ||||||
|         _ => {} |         _ => {} | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user