Merge pull request #3949 from fufesou/fix/legacy_mode_win_layout_code
legacy mode, win, fix layout code simulation
This commit is contained in:
		
						commit
						30e42d8820
					
				| @ -247,6 +247,40 @@ impl KeyboardControllable for Enigo { | ||||
|     } | ||||
| 
 | ||||
|     fn key_down(&mut self, key: Key) -> crate::ResultType { | ||||
|         match &key { | ||||
|             Key::Layout(c) => { | ||||
|                 // to-do: dup code
 | ||||
|                 // https://github.com/rustdesk/rustdesk/blob/1bc0dd791ed8344997024dc46626bd2ca7df73d2/src/server/input_service.rs#L1348
 | ||||
|                 let code = self.get_layoutdependent_keycode(*c); | ||||
|                 if code as u16 != 0xFFFF { | ||||
|                     let vk = code & 0x00FF; | ||||
|                     let flag = code >> 8; | ||||
|                     let modifiers = [Key::Shift, Key::Control, Key::Alt]; | ||||
|                     let mod_len = modifiers.len(); | ||||
|                     for pos in 0..mod_len { | ||||
|                         if flag & (0x0001 << pos) != 0 { | ||||
|                             self.key_down(modifiers[pos])?; | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     let res = keybd_event(0, vk, 0); | ||||
|                     let err = if res == 0 { get_error() } else { "".to_owned() }; | ||||
| 
 | ||||
|                     for pos in 0..mod_len { | ||||
|                         let rpos = mod_len - 1 - pos; | ||||
|                         if flag & (0x0001 << rpos) != 0 { | ||||
|                             self.key_up(modifiers[pos]); | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     if !err.is_empty() { | ||||
|                         return Err(err.into()); | ||||
|                     } | ||||
|                 } else { | ||||
|                     return Err(format!("Failed to get keycode of {}", c).into()); | ||||
|                 } | ||||
|             } | ||||
|             _ => { | ||||
|                 let code = self.key_to_keycode(key); | ||||
|                 if code == 0 || code == 65535 { | ||||
|                     return Err("".into()); | ||||
| @ -258,6 +292,8 @@ impl KeyboardControllable for Enigo { | ||||
|                         return Err(err.into()); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         Ok(()) | ||||
|     } | ||||
| 
 | ||||
| @ -411,15 +447,15 @@ impl Enigo { | ||||
|             Key::RightAlt => EVK_RMENU, | ||||
| 
 | ||||
|             Key::Raw(raw_keycode) => raw_keycode, | ||||
|             Key::Layout(c) => self.get_layoutdependent_keycode(c.to_string()), | ||||
|             Key::Super | Key::Command | Key::Windows | Key::Meta => EVK_LWIN, | ||||
|             Key::Layout(..) => { | ||||
|                 // unreachable
 | ||||
|                 0 | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn get_layoutdependent_keycode(&self, string: String) -> u16 { | ||||
|         // get the first char from the string ignore the rest
 | ||||
|         // ensure its not a multybyte char
 | ||||
|         if let Some(chr) = string.chars().nth(0) { | ||||
|     fn get_layoutdependent_keycode(&self, chr: char) -> u16 { | ||||
|         // NOTE VkKeyScanW uses the current keyboard LAYOUT
 | ||||
|         // to specify a LAYOUT use VkKeyScanExW and GetKeyboardLayout
 | ||||
|         // or load one with LoadKeyboardLayoutW
 | ||||
| @ -433,8 +469,5 @@ impl Enigo { | ||||
|         } else { | ||||
|             keycode_and_shiftstate as _ | ||||
|         } | ||||
|         } else { | ||||
|             0 | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -4,11 +4,15 @@ pub mod linux; | ||||
| #[cfg(target_os = "macos")] | ||||
| pub mod macos; | ||||
| 
 | ||||
| #[cfg(not(debug_assertions))] | ||||
| use crate::{config::Config, log}; | ||||
| #[cfg(not(debug_assertions))] | ||||
| use std::process::exit; | ||||
| 
 | ||||
| #[cfg(not(debug_assertions))] | ||||
| static mut GLOBAL_CALLBACK: Option<Box<dyn Fn()>> = None; | ||||
| 
 | ||||
| #[cfg(not(debug_assertions))] | ||||
| extern "C" fn breakdown_signal_handler(sig: i32) { | ||||
|     let mut stack = vec![]; | ||||
|     backtrace::trace(|frame| { | ||||
| @ -61,13 +65,13 @@ extern "C" fn breakdown_signal_handler(sig: i32) { | ||||
|     exit(0); | ||||
| } | ||||
| 
 | ||||
| pub fn register_breakdown_handler<T>(_callback: T) | ||||
| #[cfg(not(debug_assertions))] | ||||
| pub fn register_breakdown_handler<T>(callback: T) | ||||
| where | ||||
|     T: Fn() + 'static, | ||||
| { | ||||
|     #[cfg(not(debug_assertions))] | ||||
|     unsafe { | ||||
|         GLOBAL_CALLBACK = Some(Box::new(_callback)); | ||||
|         GLOBAL_CALLBACK = Some(Box::new(callback)); | ||||
|         libc::signal(libc::SIGSEGV, breakdown_signal_handler as _); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,5 +1,6 @@ | ||||
| use crate::platform::breakdown_callback; | ||||
| use hbb_common::log; | ||||
| #[cfg(not(debug_assertions))] | ||||
| #[cfg(not(any(target_os = "android", target_os = "ios")))] | ||||
| use hbb_common::platform::register_breakdown_handler; | ||||
| 
 | ||||
| @ -39,6 +40,7 @@ pub fn core_main() -> Option<Vec<String>> { | ||||
|         } | ||||
|         i += 1; | ||||
|     } | ||||
|     #[cfg(not(debug_assertions))] | ||||
|     #[cfg(not(any(target_os = "android", target_os = "ios")))] | ||||
|     register_breakdown_handler(breakdown_callback); | ||||
|     #[cfg(target_os = "linux")] | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user