commit
1ce2c0487d
@ -324,6 +324,8 @@ impl InvokeUiSession for FlutterHandler {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_connected(&self, _conn_type: ConnType) {}
|
||||||
|
|
||||||
fn msgbox(&self, msgtype: &str, title: &str, text: &str, link: &str, retry: bool) {
|
fn msgbox(&self, msgtype: &str, title: &str, text: &str, link: &str, retry: bool) {
|
||||||
let has_retry = if retry { "true" } else { "" };
|
let has_retry = if retry { "true" } else { "" };
|
||||||
self.push_event(
|
self.push_event(
|
||||||
|
@ -17,8 +17,6 @@ use hbb_common::{
|
|||||||
|
|
||||||
use crate::flutter::{self, SESSIONS};
|
use crate::flutter::{self, SESSIONS};
|
||||||
use crate::ui_interface::{self, *};
|
use crate::ui_interface::{self, *};
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
|
||||||
use crate::keyboard::CUR_SESSION;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
client::file_trait::FileManager,
|
client::file_trait::FileManager,
|
||||||
flutter::{make_fd_to_json, session_add, session_start_},
|
flutter::{make_fd_to_json, session_add, session_start_},
|
||||||
@ -293,7 +291,7 @@ pub fn session_enter_or_leave(id: String, enter: bool) {
|
|||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
if let Some(session) = SESSIONS.read().unwrap().get(&id) {
|
if let Some(session) = SESSIONS.read().unwrap().get(&id) {
|
||||||
if enter {
|
if enter {
|
||||||
*CUR_SESSION.lock().unwrap() = Some(session.clone());
|
crate::keyboard::set_cur_session(session.clone());
|
||||||
session.enter();
|
session.enter();
|
||||||
} else {
|
} else {
|
||||||
session.leave();
|
session.leave();
|
||||||
|
101
src/keyboard.rs
101
src/keyboard.rs
@ -8,29 +8,26 @@ use crate::ui::remote::SciterHandler;
|
|||||||
use crate::ui_session_interface::Session;
|
use crate::ui_session_interface::Session;
|
||||||
use hbb_common::{log, message_proto::*};
|
use hbb_common::{log, message_proto::*};
|
||||||
use rdev::{Event, EventType, Key};
|
use rdev::{Event, EventType, Key};
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::{
|
||||||
use std::sync::atomic::AtomicBool;
|
collections::{HashMap, HashSet},
|
||||||
#[cfg(any(target_os = "windows", target_os = "macos"))]
|
sync::{
|
||||||
use std::sync::atomic::Ordering;
|
atomic::{AtomicBool, Ordering},
|
||||||
use std::sync::{mpsc, Arc, Mutex};
|
Arc, Mutex,
|
||||||
use std::thread;
|
},
|
||||||
use std::time::SystemTime;
|
time::SystemTime,
|
||||||
|
};
|
||||||
|
|
||||||
static mut IS_ALT_GR: bool = false;
|
static mut IS_ALT_GR: bool = false;
|
||||||
pub static KEYBOARD_HOOKED: AtomicBool = AtomicBool::new(false);
|
static KEYBOARD_HOOKED: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
lazy_static::lazy_static! {
|
|
||||||
pub static ref GRAB_SENDER: Arc<Mutex<Option<mpsc::Sender<GrabState>>>> = Default::default();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "flutter")]
|
#[cfg(feature = "flutter")]
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
pub static ref CUR_SESSION: Arc<Mutex<Option<Session<FlutterHandler>>>> = Default::default();
|
static ref CUR_SESSION: Arc<Mutex<Option<Session<FlutterHandler>>>> = Default::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "flutter"))]
|
#[cfg(not(feature = "flutter"))]
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
pub static ref CUR_SESSION: Arc<Mutex<Option<Session<SciterHandler>>>> = Default::default();
|
static ref CUR_SESSION: Arc<Mutex<Option<Session<SciterHandler>>>> = Default::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
@ -47,7 +44,10 @@ lazy_static::lazy_static! {
|
|||||||
m.insert(Key::MetaRight, false);
|
m.insert(Key::MetaRight, false);
|
||||||
Mutex::new(m)
|
Mutex::new(m)
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_cur_session(session: Session<SciterHandler>) {
|
||||||
|
*CUR_SESSION.lock().unwrap() = Some(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod client {
|
pub mod client {
|
||||||
@ -62,20 +62,32 @@ pub mod client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_grab_loop() {
|
pub fn start_grab_loop() {
|
||||||
let (sender, receiver) = mpsc::channel::<GrabState>();
|
super::start_grab_loop();
|
||||||
|
|
||||||
grab_loop(receiver);
|
|
||||||
*GRAB_SENDER.lock().unwrap() = Some(sender);
|
|
||||||
|
|
||||||
change_grab_status(GrabState::Ready);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn change_grab_status(state: GrabState) {
|
pub fn change_grab_status(state: GrabState) {
|
||||||
if GrabState::Wait == state {
|
match state {
|
||||||
release_remote_keys();
|
GrabState::Ready => {}
|
||||||
|
GrabState::Run => {
|
||||||
|
#[cfg(any(target_os = "windows", target_os = "macos"))]
|
||||||
|
KEYBOARD_HOOKED.swap(true, Ordering::SeqCst);
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
rdev::enable_grab().ok();
|
||||||
|
}
|
||||||
|
GrabState::Wait => {
|
||||||
|
release_remote_keys();
|
||||||
|
|
||||||
|
#[cfg(any(target_os = "windows", target_os = "macos"))]
|
||||||
|
KEYBOARD_HOOKED.swap(false, Ordering::SeqCst);
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
rdev::disable_grab().ok();
|
||||||
|
}
|
||||||
|
GrabState::Exit => {
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
rdev::exit_grab_listen().ok();
|
||||||
}
|
}
|
||||||
if let Some(sender) = &*GRAB_SENDER.lock().unwrap() {
|
|
||||||
sender.send(state).ok();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,11 +178,7 @@ pub mod client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn grab_loop(recv: mpsc::Receiver<GrabState>) {
|
pub fn start_grab_loop() {
|
||||||
thread::spawn(move || loop {
|
|
||||||
if let Some(state) = recv.recv().ok() {
|
|
||||||
match state {
|
|
||||||
GrabState::Ready => {
|
|
||||||
#[cfg(any(target_os = "windows", target_os = "macos"))]
|
#[cfg(any(target_os = "windows", target_os = "macos"))]
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
let func = move |event: Event| match event.event_type {
|
let func = move |event: Event| match event.event_type {
|
||||||
@ -206,28 +214,6 @@ pub fn grab_loop(recv: mpsc::Receiver<GrabState>) {
|
|||||||
_ => Some(event),
|
_ => Some(event),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
GrabState::Run => {
|
|
||||||
#[cfg(any(target_os = "windows", target_os = "macos"))]
|
|
||||||
KEYBOARD_HOOKED.swap(true, Ordering::SeqCst);
|
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
rdev::enable_grab().ok();
|
|
||||||
}
|
|
||||||
GrabState::Wait => {
|
|
||||||
#[cfg(any(target_os = "windows", target_os = "macos"))]
|
|
||||||
KEYBOARD_HOOKED.swap(false, Ordering::SeqCst);
|
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
rdev::disable_grab().ok();
|
|
||||||
}
|
|
||||||
GrabState::Exit => {
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
rdev::exit_grab_listen().ok();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_long_press(event: &Event) -> bool {
|
pub fn is_long_press(event: &Event) -> bool {
|
||||||
let keys = MODIFIERS_STATE.lock().unwrap();
|
let keys = MODIFIERS_STATE.lock().unwrap();
|
||||||
@ -246,10 +232,9 @@ pub fn is_long_press(event: &Event) -> bool {
|
|||||||
|
|
||||||
pub fn release_remote_keys() {
|
pub fn release_remote_keys() {
|
||||||
// todo!: client quit suddenly, how to release keys?
|
// todo!: client quit suddenly, how to release keys?
|
||||||
let to_release = TO_RELEASE.lock().unwrap();
|
let to_release = TO_RELEASE.lock().unwrap().clone();
|
||||||
let keys = to_release.iter().map(|&key| key).collect::<Vec<Key>>();
|
TO_RELEASE.lock().unwrap().clear();
|
||||||
drop(to_release);
|
for key in to_release {
|
||||||
for key in keys {
|
|
||||||
let event_type = EventType::KeyRelease(key);
|
let event_type = EventType::KeyRelease(key);
|
||||||
let event = event_type_to_event(event_type);
|
let event = event_type_to_event(event_type);
|
||||||
client::process_event(event);
|
client::process_event(event);
|
||||||
@ -317,17 +302,15 @@ pub fn event_to_key_event(event: &Event) -> KeyEvent {
|
|||||||
let mut key_event = KeyEvent::new();
|
let mut key_event = KeyEvent::new();
|
||||||
update_modifiers_state(event);
|
update_modifiers_state(event);
|
||||||
|
|
||||||
let mut to_release = TO_RELEASE.lock().unwrap();
|
|
||||||
match event.event_type {
|
match event.event_type {
|
||||||
EventType::KeyPress(key) => {
|
EventType::KeyPress(key) => {
|
||||||
to_release.insert(key);
|
TO_RELEASE.lock().unwrap().insert(key);
|
||||||
}
|
}
|
||||||
EventType::KeyRelease(key) => {
|
EventType::KeyRelease(key) => {
|
||||||
to_release.remove(&key);
|
TO_RELEASE.lock().unwrap().remove(&key);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
drop(to_release);
|
|
||||||
|
|
||||||
let keyboard_mode = get_keyboard_mode_enum();
|
let keyboard_mode = get_keyboard_mode_enum();
|
||||||
key_event.mode = keyboard_mode.into();
|
key_event.mode = keyboard_mode.into();
|
||||||
|
@ -124,12 +124,15 @@ pub fn start(args: &mut [String]) {
|
|||||||
let args: Vec<String> = iter.map(|x| x.clone()).collect();
|
let args: Vec<String> = iter.map(|x| x.clone()).collect();
|
||||||
frame.set_title(&id);
|
frame.set_title(&id);
|
||||||
frame.register_behavior("native-remote", move || {
|
frame.register_behavior("native-remote", move || {
|
||||||
Box::new(remote::SciterSession::new(
|
let handler = remote::SciterSession::new(
|
||||||
cmd.clone(),
|
cmd.clone(),
|
||||||
id.clone(),
|
id.clone(),
|
||||||
pass.clone(),
|
pass.clone(),
|
||||||
args.clone(),
|
args.clone(),
|
||||||
))
|
);
|
||||||
|
let inner = handler.inner();
|
||||||
|
crate::keyboard::set_cur_session(inner);
|
||||||
|
Box::new(handler)
|
||||||
});
|
});
|
||||||
page = "remote.html";
|
page = "remote.html";
|
||||||
} else {
|
} else {
|
||||||
|
@ -231,6 +231,17 @@ impl InvokeUiSession for SciterHandler {
|
|||||||
self.call("updatePi", &make_args!(pi_sciter));
|
self.call("updatePi", &make_args!(pi_sciter));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_connected(&self, conn_type: ConnType) {
|
||||||
|
match conn_type {
|
||||||
|
ConnType::RDP => {},
|
||||||
|
ConnType::PORT_FORWARD => {},
|
||||||
|
ConnType::FILE_TRANSFER => {},
|
||||||
|
ConnType::DEFAULT_CONN => {
|
||||||
|
crate::keyboard::client::start_grab_loop();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn msgbox(&self, msgtype: &str, title: &str, text: &str, link: &str, retry: bool) {
|
fn msgbox(&self, msgtype: &str, title: &str, text: &str, link: &str, retry: bool) {
|
||||||
self.call2(
|
self.call2(
|
||||||
"msgbox_retry",
|
"msgbox_retry",
|
||||||
@ -434,6 +445,10 @@ impl SciterSession {
|
|||||||
Self(session)
|
Self(session)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn inner(&self) -> Session<SciterHandler> {
|
||||||
|
self.0.clone()
|
||||||
|
}
|
||||||
|
|
||||||
fn get_custom_image_quality(&mut self) -> Value {
|
fn get_custom_image_quality(&mut self) -> Value {
|
||||||
let mut v = Value::array(0);
|
let mut v = Value::array(0);
|
||||||
for x in self.lc.read().unwrap().custom_image_quality.iter() {
|
for x in self.lc.read().unwrap().custom_image_quality.iter() {
|
||||||
|
@ -5,6 +5,7 @@ use crate::client::{
|
|||||||
QualityStatus, KEY_MAP,
|
QualityStatus, KEY_MAP,
|
||||||
};
|
};
|
||||||
use crate::common::GrabState;
|
use crate::common::GrabState;
|
||||||
|
use crate::keyboard;
|
||||||
use crate::{client::Data, client::Interface};
|
use crate::{client::Data, client::Interface};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use hbb_common::config::{Config, LocalConfig, PeerConfig};
|
use hbb_common::config::{Config, LocalConfig, PeerConfig};
|
||||||
@ -12,12 +13,11 @@ use hbb_common::rendezvous_proto::ConnType;
|
|||||||
use hbb_common::tokio::{self, sync::mpsc};
|
use hbb_common::tokio::{self, sync::mpsc};
|
||||||
use hbb_common::{allow_err, message_proto::*};
|
use hbb_common::{allow_err, message_proto::*};
|
||||||
use hbb_common::{fs, get_version_number, log, Stream};
|
use hbb_common::{fs, get_version_number, log, Stream};
|
||||||
|
use rdev::{Event, EventType::*};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
||||||
use std::sync::{Arc, Mutex, RwLock};
|
use std::sync::{Arc, Mutex, RwLock};
|
||||||
use crate::keyboard;
|
|
||||||
use rdev::{Event, EventType::*};
|
|
||||||
pub static IS_IN: AtomicBool = AtomicBool::new(false);
|
pub static IS_IN: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
@ -580,6 +580,7 @@ pub trait InvokeUiSession: Send + Sync + Clone + 'static + Sized + Default {
|
|||||||
fn set_display(&self, x: i32, y: i32, w: i32, h: i32, cursor_embeded: bool);
|
fn set_display(&self, x: i32, y: i32, w: i32, h: i32, cursor_embeded: bool);
|
||||||
fn switch_display(&self, display: &SwitchDisplay);
|
fn switch_display(&self, display: &SwitchDisplay);
|
||||||
fn set_peer_info(&self, peer_info: &PeerInfo); // flutter
|
fn set_peer_info(&self, peer_info: &PeerInfo); // flutter
|
||||||
|
fn on_connected(&self, conn_type: ConnType);
|
||||||
fn update_privacy_mode(&self);
|
fn update_privacy_mode(&self);
|
||||||
fn set_permission(&self, name: &str, value: bool);
|
fn set_permission(&self, name: &str, value: bool);
|
||||||
fn close_success(&self);
|
fn close_success(&self);
|
||||||
@ -712,6 +713,7 @@ impl<T: InvokeUiSession> Interface for Session<T> {
|
|||||||
"",
|
"",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
self.on_connected(self.lc.read().unwrap().conn_type);
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
let mut path = std::env::temp_dir();
|
let mut path = std::env::temp_dir();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user