feat: Add new simulate key method
This commit is contained in:
parent
9237ae30dc
commit
e82e0bf697
19
Cargo.lock
generated
19
Cargo.lock
generated
@ -1317,6 +1317,7 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"objc",
|
"objc",
|
||||||
"pkg-config",
|
"pkg-config",
|
||||||
|
"rdev 0.5.1",
|
||||||
"serde 1.0.137",
|
"serde 1.0.137",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
@ -3836,6 +3837,22 @@ dependencies = [
|
|||||||
"x11",
|
"x11",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rdev"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7336f02e29f34e9a7186ccf87051f6a5697536195569012e076e18a4efddcede"
|
||||||
|
dependencies = [
|
||||||
|
"cocoa 0.22.0",
|
||||||
|
"core-foundation 0.7.0",
|
||||||
|
"core-foundation-sys 0.7.0",
|
||||||
|
"core-graphics 0.19.2",
|
||||||
|
"lazy_static",
|
||||||
|
"libc",
|
||||||
|
"winapi 0.3.9",
|
||||||
|
"x11",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rdrand"
|
name = "rdrand"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
@ -4076,7 +4093,7 @@ dependencies = [
|
|||||||
"num_cpus",
|
"num_cpus",
|
||||||
"objc",
|
"objc",
|
||||||
"parity-tokio-ipc",
|
"parity-tokio-ipc",
|
||||||
"rdev",
|
"rdev 0.5.0",
|
||||||
"repng",
|
"repng",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"rpassword 6.0.1",
|
"rpassword 6.0.1",
|
||||||
|
@ -21,7 +21,8 @@ appveyor = { repository = "pythoneer/enigo-85xiy" }
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
serde = { version = "1.0", optional = true }
|
serde = { version = "1.0", optional = true }
|
||||||
serde_derive = { version = "1.0", optional = true }
|
serde_derive = { version = "1.0", optional = true }
|
||||||
log = "0.4"
|
log = "0.4.17"
|
||||||
|
rdev = "0.5.1"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
with_serde = ["serde", "serde_derive"]
|
with_serde = ["serde", "serde_derive"]
|
||||||
|
@ -3,8 +3,8 @@ use libc;
|
|||||||
use crate::{Key, KeyboardControllable, MouseButton, MouseControllable};
|
use crate::{Key, KeyboardControllable, MouseButton, MouseControllable};
|
||||||
|
|
||||||
use self::libc::{c_char, c_int, c_void, useconds_t};
|
use self::libc::{c_char, c_int, c_void, useconds_t};
|
||||||
use std::{borrow::Cow, ffi::CString, io::prelude::*, ptr, sync::mpsc};
|
use rdev::{simulate, EventType, EventType::*, Key as RdevKey, SimulateError};
|
||||||
|
use std::{borrow::Cow, ffi::CString, io::prelude::*, ptr, sync::mpsc, thread, time};
|
||||||
const CURRENT_WINDOW: c_int = 0;
|
const CURRENT_WINDOW: c_int = 0;
|
||||||
const DEFAULT_DELAY: u64 = 12000;
|
const DEFAULT_DELAY: u64 = 12000;
|
||||||
type Window = c_int;
|
type Window = c_int;
|
||||||
@ -103,6 +103,30 @@ impl Enigo {
|
|||||||
pub fn reset(&mut self) {
|
pub fn reset(&mut self) {
|
||||||
self.tx.send((PyMsg::Char('\0'), true)).ok();
|
self.tx.send((PyMsg::Char('\0'), true)).ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn send_rdev(&mut self, key: &Key, is_press: bool) -> bool {
|
||||||
|
log::info!("{:?} {:?}", key, is_press);
|
||||||
|
|
||||||
|
if let Key::Raw(keycode) = key {
|
||||||
|
let event_type = match is_press {
|
||||||
|
// todo: Acccodding to client type
|
||||||
|
true => Box::leak(Box::new(EventType::KeyPress(RdevKey::Unknown(
|
||||||
|
(*keycode).into(),
|
||||||
|
)))),
|
||||||
|
false => Box::leak(Box::new(EventType::KeyRelease(RdevKey::Unknown(
|
||||||
|
(*keycode).into(),
|
||||||
|
)))),
|
||||||
|
};
|
||||||
|
|
||||||
|
match simulate(event_type) {
|
||||||
|
Ok(()) => true,
|
||||||
|
Err(SimulateError) => false,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn send_pynput(&mut self, key: &Key, is_press: bool) -> bool {
|
fn send_pynput(&mut self, key: &Key, is_press: bool) -> bool {
|
||||||
if unsafe { PYNPUT_EXIT || !PYNPUT_REDAY } {
|
if unsafe { PYNPUT_EXIT || !PYNPUT_REDAY } {
|
||||||
@ -111,8 +135,15 @@ impl Enigo {
|
|||||||
if let Key::Layout(c) = key {
|
if let Key::Layout(c) = key {
|
||||||
return self.tx.send((PyMsg::Char(*c), is_press)).is_ok();
|
return self.tx.send((PyMsg::Char(*c), is_press)).is_ok();
|
||||||
}
|
}
|
||||||
if let Key::Raw(_) = key {
|
if let Key::Raw(chr) = key {
|
||||||
return false;
|
fn string_to_static_str(s: String) -> &'static str {
|
||||||
|
Box::leak(s.into_boxed_str())
|
||||||
|
}
|
||||||
|
dbg!(chr.to_string());
|
||||||
|
return self
|
||||||
|
.tx
|
||||||
|
.send((PyMsg::Str(string_to_static_str(chr.to_string())), is_press))
|
||||||
|
.is_ok();
|
||||||
}
|
}
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
let s = match key {
|
let s = match key {
|
||||||
@ -431,6 +462,9 @@ impl KeyboardControllable for Enigo {
|
|||||||
if self.xdo.is_null() {
|
if self.xdo.is_null() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
if self.send_rdev(&key, true) {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
if self.send_pynput(&key, true) {
|
if self.send_pynput(&key, true) {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -449,6 +483,11 @@ impl KeyboardControllable for Enigo {
|
|||||||
if self.xdo.is_null() {
|
if self.xdo.is_null() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// todo
|
||||||
|
let keyboard_mode = 1;
|
||||||
|
if keyboard_mode == 1 && self.send_rdev(&key, false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if self.send_pynput(&key, false) {
|
if self.send_pynput(&key, false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -478,6 +517,21 @@ impl KeyboardControllable for Enigo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn key_sequence_parse(&mut self, sequence: &str)
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
self.key_sequence_parse_try(sequence)
|
||||||
|
.expect("Could not parse sequence");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn key_sequence_parse_try(&mut self, sequence: &str) -> Result<(), crate::dsl::ParseError>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
crate::dsl::eval(self, sequence)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static mut PYNPUT_EXIT: bool = false;
|
static mut PYNPUT_EXIT: bool = false;
|
||||||
@ -492,7 +546,8 @@ fn start_pynput_service(rx: mpsc::Receiver<(PyMsg, bool)>) {
|
|||||||
py = "/usr/lib/rustdesk/pynput_service.py".to_owned();
|
py = "/usr/lib/rustdesk/pynput_service.py".to_owned();
|
||||||
if !std::path::Path::new(&py).exists() {
|
if !std::path::Path::new(&py).exists() {
|
||||||
// enigo libs, not rustdesk root project, so skip using appimage features
|
// enigo libs, not rustdesk root project, so skip using appimage features
|
||||||
py = std::env::var("APPDIR").unwrap_or("".to_string()) + "/usr/lib/rustdesk/pynput_service.py";
|
py = std::env::var("APPDIR").unwrap_or("".to_string())
|
||||||
|
+ "/usr/lib/rustdesk/pynput_service.py";
|
||||||
if !std::path::Path::new(&py).exists() {
|
if !std::path::Path::new(&py).exists() {
|
||||||
log::error!("{} not exists", py);
|
log::error!("{} not exists", py);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user