feat: show my cursor (#12745)
Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
@@ -126,9 +126,18 @@ pub struct ConnInner {
|
||||
tx_video: Option<Sender>,
|
||||
}
|
||||
|
||||
struct InputMouse {
|
||||
msg: MouseEvent,
|
||||
conn_id: i32,
|
||||
username: String,
|
||||
argb: u32,
|
||||
simulate: bool,
|
||||
show_cursor: bool,
|
||||
}
|
||||
|
||||
enum MessageInput {
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
Mouse((MouseEvent, i32)),
|
||||
Mouse(InputMouse),
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
Key((KeyEvent, bool)),
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
@@ -225,6 +234,9 @@ pub struct Connection {
|
||||
// by peer
|
||||
disable_keyboard: bool,
|
||||
// by peer
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
show_my_cursor: bool,
|
||||
// by peer
|
||||
disable_clipboard: bool,
|
||||
// by peer
|
||||
disable_audio: bool,
|
||||
@@ -240,6 +252,7 @@ pub struct Connection {
|
||||
server_audit_conn: String,
|
||||
server_audit_file: String,
|
||||
lr: LoginRequest,
|
||||
peer_argb: u32,
|
||||
session_last_recv_time: Option<Arc<Mutex<Instant>>>,
|
||||
chat_unanswered: bool,
|
||||
file_transferred: bool,
|
||||
@@ -403,11 +416,14 @@ impl Connection {
|
||||
enable_file_transfer: false,
|
||||
disable_clipboard: false,
|
||||
disable_keyboard: false,
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
show_my_cursor: false,
|
||||
tx_input,
|
||||
video_ack_required: false,
|
||||
server_audit_conn: "".to_owned(),
|
||||
server_audit_file: "".to_owned(),
|
||||
lr: Default::default(),
|
||||
peer_argb: 0u32,
|
||||
session_last_recv_time: None,
|
||||
chat_unanswered: false,
|
||||
file_transferred: false,
|
||||
@@ -938,8 +954,15 @@ impl Connection {
|
||||
loop {
|
||||
match receiver.recv_timeout(std::time::Duration::from_millis(500)) {
|
||||
Ok(v) => match v {
|
||||
MessageInput::Mouse((msg, id)) => {
|
||||
handle_mouse(&msg, id);
|
||||
MessageInput::Mouse(mouse_input) => {
|
||||
handle_mouse(
|
||||
&mouse_input.msg,
|
||||
mouse_input.conn_id,
|
||||
mouse_input.username,
|
||||
mouse_input.argb,
|
||||
mouse_input.simulate,
|
||||
mouse_input.show_cursor,
|
||||
);
|
||||
}
|
||||
MessageInput::Key((mut msg, press)) => {
|
||||
// Set the press state to false, use `down` only in `handle_key()`.
|
||||
@@ -1784,8 +1807,25 @@ impl Connection {
|
||||
|
||||
#[inline]
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
fn input_mouse(&self, msg: MouseEvent, conn_id: i32) {
|
||||
self.tx_input.send(MessageInput::Mouse((msg, conn_id))).ok();
|
||||
fn input_mouse(
|
||||
&self,
|
||||
msg: MouseEvent,
|
||||
conn_id: i32,
|
||||
username: String,
|
||||
argb: u32,
|
||||
simulate: bool,
|
||||
show_cursor: bool,
|
||||
) {
|
||||
self.tx_input
|
||||
.send(MessageInput::Mouse(InputMouse {
|
||||
msg,
|
||||
conn_id,
|
||||
username,
|
||||
argb,
|
||||
simulate,
|
||||
show_cursor,
|
||||
}))
|
||||
.ok();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -1900,6 +1940,7 @@ impl Connection {
|
||||
|
||||
async fn handle_login_request_without_validation(&mut self, lr: &LoginRequest) {
|
||||
self.lr = lr.clone();
|
||||
self.peer_argb = crate::str2color(&format!("{}{}", &lr.my_id, &lr.my_platform), 0xff);
|
||||
if let Some(o) = lr.option.as_ref() {
|
||||
self.options_in_login = Some(o.clone());
|
||||
}
|
||||
@@ -2279,7 +2320,23 @@ impl Connection {
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
self.retina.on_mouse_event(&mut me, self.display_idx);
|
||||
self.input_mouse(me, self.inner.id());
|
||||
self.input_mouse(
|
||||
me,
|
||||
self.inner.id(),
|
||||
self.lr.my_name.clone(),
|
||||
self.peer_argb,
|
||||
true,
|
||||
self.show_my_cursor,
|
||||
);
|
||||
} else if self.show_my_cursor {
|
||||
self.input_mouse(
|
||||
me,
|
||||
self.inner.id(),
|
||||
self.lr.my_name.clone(),
|
||||
self.peer_argb,
|
||||
false,
|
||||
true,
|
||||
);
|
||||
}
|
||||
self.update_auto_disconnect_timer();
|
||||
}
|
||||
@@ -3640,6 +3697,18 @@ impl Connection {
|
||||
self.update_terminal_persistence(q == BoolOption::Yes).await;
|
||||
}
|
||||
}
|
||||
#[cfg(target_os = "windows")]
|
||||
if let Ok(q) = o.show_my_cursor.enum_value() {
|
||||
if q != BoolOption::NotSet {
|
||||
use crate::whiteboard;
|
||||
self.show_my_cursor = q == BoolOption::Yes;
|
||||
if q == BoolOption::Yes {
|
||||
whiteboard::register_whiteboard(whiteboard::get_key_cursor(self.inner.id));
|
||||
} else {
|
||||
whiteboard::unregister_whiteboard(whiteboard::get_key_cursor(self.inner.id));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn turn_on_privacy(&mut self, impl_key: String) {
|
||||
@@ -4792,6 +4861,11 @@ mod raii {
|
||||
scrap::wayland::pipewire::try_close_session();
|
||||
}
|
||||
Self::check_wake_lock();
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
use crate::whiteboard;
|
||||
whiteboard::unregister_whiteboard(whiteboard::get_key_cursor(self.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
use super::rdp_input::client::{RdpInputKeyboard, RdpInputMouse};
|
||||
use super::*;
|
||||
use crate::input::*;
|
||||
#[cfg(target_os = "windows")]
|
||||
use crate::whiteboard;
|
||||
#[cfg(target_os = "macos")]
|
||||
use dispatch::Queue;
|
||||
use enigo::{Enigo, Key, KeyboardControllable, MouseButton, MouseControllable};
|
||||
@@ -698,18 +700,25 @@ fn get_modifier_state(key: Key, en: &mut Enigo) -> bool {
|
||||
}
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
pub fn handle_mouse(evt: &MouseEvent, conn: i32) {
|
||||
pub fn handle_mouse(
|
||||
evt: &MouseEvent,
|
||||
conn: i32,
|
||||
username: String,
|
||||
argb: u32,
|
||||
simulate: bool,
|
||||
show_cursor: bool,
|
||||
) {
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
// having GUI (--server has tray, it is GUI too), run main GUI thread, otherwise crash
|
||||
let evt = evt.clone();
|
||||
QUEUE.exec_async(move || handle_mouse_(&evt, conn));
|
||||
QUEUE.exec_async(move || handle_mouse_(&evt, conn, username, argb, simulate, show_cursor));
|
||||
return;
|
||||
}
|
||||
#[cfg(windows)]
|
||||
crate::portable_service::client::handle_mouse(evt, conn);
|
||||
crate::portable_service::client::handle_mouse(evt, conn, username, argb, simulate, show_cursor);
|
||||
#[cfg(not(windows))]
|
||||
handle_mouse_(evt, conn);
|
||||
handle_mouse_(evt, conn, username, argb, simulate, show_cursor);
|
||||
}
|
||||
|
||||
// to-do: merge handle_mouse and handle_pointer
|
||||
@@ -979,7 +988,24 @@ pub fn handle_pointer_(evt: &PointerDeviceEvent, conn: i32) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_mouse_(evt: &MouseEvent, conn: i32) {
|
||||
pub fn handle_mouse_(
|
||||
evt: &MouseEvent,
|
||||
conn: i32,
|
||||
username: String,
|
||||
argb: u32,
|
||||
simulate: bool,
|
||||
_show_cursor: bool,
|
||||
) {
|
||||
if simulate {
|
||||
handle_mouse_simulation_(evt, conn);
|
||||
}
|
||||
#[cfg(target_os = "windows")]
|
||||
if _show_cursor {
|
||||
handle_mouse_show_cursor_(evt, conn, username, argb);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_mouse_simulation_(evt: &MouseEvent, conn: i32) {
|
||||
if !active_mouse_(conn) {
|
||||
return;
|
||||
}
|
||||
@@ -1122,6 +1148,41 @@ pub fn handle_mouse_(evt: &MouseEvent, conn: i32) {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub fn handle_mouse_show_cursor_(evt: &MouseEvent, conn: i32, username: String, argb: u32) {
|
||||
let buttons = evt.mask >> 3;
|
||||
let evt_type = evt.mask & 0x7;
|
||||
match evt_type {
|
||||
MOUSE_TYPE_MOVE => {
|
||||
whiteboard::update_whiteboard(
|
||||
whiteboard::get_key_cursor(conn),
|
||||
whiteboard::CustomEvent::Cursor(whiteboard::Cursor {
|
||||
x: evt.x as _,
|
||||
y: evt.y as _,
|
||||
argb,
|
||||
btns: 0,
|
||||
text: username,
|
||||
}),
|
||||
);
|
||||
}
|
||||
MOUSE_TYPE_UP => {
|
||||
if buttons == MOUSE_BUTTON_LEFT {
|
||||
whiteboard::update_whiteboard(
|
||||
whiteboard::get_key_cursor(conn),
|
||||
whiteboard::CustomEvent::Cursor(whiteboard::Cursor {
|
||||
x: evt.x as _,
|
||||
y: evt.y as _,
|
||||
argb,
|
||||
btns: buttons,
|
||||
text: username,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
fn handle_scale(scale: i32) {
|
||||
let mut en = ENIGO.lock().unwrap();
|
||||
|
||||
@@ -476,9 +476,9 @@ pub mod server {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Mouse((v, conn)) => {
|
||||
Mouse((v, conn, username, argb, simulate, show_cursor)) => {
|
||||
if let Ok(evt) = MouseEvent::parse_from_bytes(&v) {
|
||||
crate::input_service::handle_mouse_(&evt, conn);
|
||||
crate::input_service::handle_mouse_(&evt, conn, username, argb, simulate, show_cursor);
|
||||
}
|
||||
}
|
||||
Pointer((v, conn)) => {
|
||||
@@ -875,11 +875,23 @@ pub mod client {
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_mouse_(evt: &MouseEvent, conn: i32) -> ResultType<()> {
|
||||
fn handle_mouse_(
|
||||
evt: &MouseEvent,
|
||||
conn: i32,
|
||||
username: String,
|
||||
argb: u32,
|
||||
simulate: bool,
|
||||
show_cursor: bool,
|
||||
) -> ResultType<()> {
|
||||
let mut v = vec![];
|
||||
evt.write_to_vec(&mut v)?;
|
||||
ipc_send(Data::DataPortableService(DataPortableService::Mouse((
|
||||
v, conn,
|
||||
v,
|
||||
conn,
|
||||
username,
|
||||
argb,
|
||||
simulate,
|
||||
show_cursor,
|
||||
))))
|
||||
}
|
||||
|
||||
@@ -927,12 +939,19 @@ pub mod client {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_mouse(evt: &MouseEvent, conn: i32) {
|
||||
pub fn handle_mouse(
|
||||
evt: &MouseEvent,
|
||||
conn: i32,
|
||||
username: String,
|
||||
argb: u32,
|
||||
simulate: bool,
|
||||
show_cursor: bool,
|
||||
) {
|
||||
if RUNNING.lock().unwrap().clone() {
|
||||
crate::input_service::update_latest_input_cursor_time(conn);
|
||||
handle_mouse_(evt, conn).ok();
|
||||
handle_mouse_(evt, conn, username, argb, simulate, show_cursor).ok();
|
||||
} else {
|
||||
crate::input_service::handle_mouse_(evt, conn);
|
||||
crate::input_service::handle_mouse_(evt, conn, username, argb, simulate, show_cursor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user