Get char when hot key is pressed
This commit is contained in:
parent
2aae2ca513
commit
ba4945f598
@ -3,11 +3,13 @@ use crate::client::get_key_state;
|
|||||||
use crate::common::GrabState;
|
use crate::common::GrabState;
|
||||||
#[cfg(feature = "flutter")]
|
#[cfg(feature = "flutter")]
|
||||||
use crate::flutter::{CUR_SESSION_ID, SESSIONS};
|
use crate::flutter::{CUR_SESSION_ID, SESSIONS};
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
use crate::platform::windows::get_char_by_vk;
|
||||||
#[cfg(not(any(feature = "flutter", feature = "cli")))]
|
#[cfg(not(any(feature = "flutter", feature = "cli")))]
|
||||||
use crate::ui::CUR_SESSION;
|
use crate::ui::CUR_SESSION;
|
||||||
use hbb_common::message_proto::*;
|
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
use hbb_common::log;
|
use hbb_common::log;
|
||||||
|
use hbb_common::message_proto::*;
|
||||||
use rdev::{Event, EventType, Key};
|
use rdev::{Event, EventType, Key};
|
||||||
#[cfg(any(target_os = "windows", target_os = "macos"))]
|
#[cfg(any(target_os = "windows", target_os = "macos"))]
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
@ -789,8 +791,18 @@ fn try_fill_unicode(event: &Event, key_event: &KeyEvent, events: &mut Vec<KeyEve
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {}
|
None => {
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
if is_hot_key_modifiers_down() && unsafe { !IS_0X021D_DOWN }{
|
||||||
|
if let Some(chr) = get_char_by_vk(event.code as u32) {
|
||||||
|
let mut evt = key_event.clone();
|
||||||
|
evt.set_seq(chr.to_string());
|
||||||
|
events.push(evt);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
@ -857,7 +869,7 @@ pub fn translate_keyboard_mode(peer: &str, event: &Event, key_event: KeyEvent) -
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
if unsafe { IS_0X021D_DOWN } || !is_hot_key_modifiers_down() {
|
if matches!(event.event_type, EventType::KeyPress(_)) {
|
||||||
try_fill_unicode(event, &key_event, &mut events);
|
try_fill_unicode(event, &key_event, &mut events);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ use hbb_common::{
|
|||||||
sleep, timeout, tokio,
|
sleep, timeout, tokio,
|
||||||
};
|
};
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
|
use std::ptr::null_mut;
|
||||||
use std::{
|
use std::{
|
||||||
ffi::OsString,
|
ffi::OsString,
|
||||||
fs, io, mem,
|
fs, io, mem,
|
||||||
@ -26,8 +27,8 @@ use winapi::{
|
|||||||
handleapi::CloseHandle,
|
handleapi::CloseHandle,
|
||||||
minwinbase::STILL_ACTIVE,
|
minwinbase::STILL_ACTIVE,
|
||||||
processthreadsapi::{
|
processthreadsapi::{
|
||||||
GetCurrentProcess, GetCurrentProcessId, GetExitCodeProcess, OpenProcess,
|
GetCurrentProcess, GetCurrentProcessId, GetCurrentThreadId, GetExitCodeProcess,
|
||||||
OpenProcessToken, PROCESS_INFORMATION, STARTUPINFOW,
|
OpenProcess, OpenProcessToken, PROCESS_INFORMATION, STARTUPINFOW,
|
||||||
},
|
},
|
||||||
securitybaseapi::GetTokenInformation,
|
securitybaseapi::GetTokenInformation,
|
||||||
shellapi::ShellExecuteW,
|
shellapi::ShellExecuteW,
|
||||||
@ -2072,6 +2073,51 @@ mod cert {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_char_by_vk(vk: u32) -> Option<char> {
|
||||||
|
let mut buff = [0_u16; BUF_LEN as usize];
|
||||||
|
let buff_ptr = buff.as_mut_ptr();
|
||||||
|
const BUF_LEN: i32 = 32;
|
||||||
|
let len = unsafe {
|
||||||
|
let current_window_thread_id = GetWindowThreadProcessId(GetForegroundWindow(), null_mut());
|
||||||
|
let layout = GetKeyboardLayout(current_window_thread_id);
|
||||||
|
|
||||||
|
// refs: https://github.com/fufesou/rdev/blob/25a99ce71ab42843ad253dd51e6a35e83e87a8a4/src/windows/keyboard.rs#L115
|
||||||
|
let press_state = 129;
|
||||||
|
let mut state: [BYTE; 256] = [0; 256];
|
||||||
|
let shift_left = rdev::get_modifier(rdev::Key::ShiftLeft);
|
||||||
|
let shift_right = rdev::get_modifier(rdev::Key::ShiftRight);
|
||||||
|
if shift_left {
|
||||||
|
state[VK_LSHIFT as usize] = press_state;
|
||||||
|
}
|
||||||
|
if shift_right {
|
||||||
|
state[VK_RSHIFT as usize] = press_state;
|
||||||
|
}
|
||||||
|
if shift_left || shift_right {
|
||||||
|
state[VK_SHIFT as usize] = press_state;
|
||||||
|
}
|
||||||
|
buff = [0; 32];
|
||||||
|
let buff_ptr = buff.as_mut_ptr();
|
||||||
|
ToUnicodeEx(vk, 0x00, &state as _, buff_ptr, BUF_LEN, 0, layout)
|
||||||
|
};
|
||||||
|
if len == 1 {
|
||||||
|
if let Some(chr) = String::from_utf16(&buff[..len as usize])
|
||||||
|
.ok()?
|
||||||
|
.chars()
|
||||||
|
.next()
|
||||||
|
{
|
||||||
|
if chr.is_control() {
|
||||||
|
return None;
|
||||||
|
} else {
|
||||||
|
Some(chr)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -2084,4 +2130,12 @@ mod tests {
|
|||||||
fn test_uninstall_cert() {
|
fn test_uninstall_cert() {
|
||||||
println!("uninstall driver certs: {:?}", cert::uninstall_certs());
|
println!("uninstall driver certs: {:?}", cert::uninstall_certs());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_char_by_vk() {
|
||||||
|
let chr = get_char_by_vk(0x41); // VK_A
|
||||||
|
assert_eq!(chr, Some('a'));
|
||||||
|
let chr = get_char_by_vk(VK_ESCAPE as u32); // VK_ESC
|
||||||
|
assert_eq!(chr, None)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user