Feat: Follow remote cursor and window focus | Auto display switch (#7717)

* feat: auto switch display on follow remote cursor

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* feat: auto switch display on follow remote window focus

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* fix build and remove unused imports

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* fix build

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* fix build

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* fix linux get_focused_window_id

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* lock show remote cursor when follow remote cursor is enabled

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* fix config

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* prevent auto display switch on show all display and displays as individual windows

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* fix options

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* fix options

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* remove unused function

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* remove unwraps and improve iterations

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* set updateCursorPos to false to avoid interrupting remote cursor

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* update lang

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* fix web build

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* update checks for options and enable in view mode

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* use focused display index for window focus service

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* use window center for windows display focused

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* remove unused imports

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* fix build

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* use libxdo instead of xdotool

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* fix multi monitor check

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* enable show cursor when follow cursor is default

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* remove show_all_displays,use runtime state instead

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* fix show cursor lock state on default

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* remove view mode with follow options

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* fix build

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* use separate message for follow current display

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* fix options

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* sciter support for follow remote cursor and window

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* add check for ui session handlers count

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* use cached displays and remove peer info write

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* No follow options when show all displays

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* No follow options when multi ui session

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* turn off follow options when not used|prevent msgs

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* use window center for switch in linux

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* use subbed display count to prevent switch msgs

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* fix build

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* fix web build

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* move subbed displays count

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* fix build

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* add noperms for window focus

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* add subscribe for window focus

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* remove window_focus message and unsub on multi ui

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* add multi ui session field

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

---------

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>
Co-authored-by: RustDesk <71636191+rustdesk@users.noreply.github.com>
This commit is contained in:
Sahil Yeole
2024-04-25 10:56:02 +05:30
committed by GitHub
parent 43a0a4f8e0
commit 3811f41076
66 changed files with 597 additions and 26 deletions

View File

@@ -11,7 +11,7 @@ use hbb_common::{
config::Config,
libc::{c_char, c_int, c_long, c_void},
log,
message_proto::Resolution,
message_proto::{DisplayInfo, Resolution},
regex::{Captures, Regex},
};
use std::{
@@ -53,6 +53,20 @@ extern "C" {
screen_num: *mut c_int,
) -> c_int;
fn xdo_new(display: *const c_char) -> Xdo;
fn xdo_get_active_window(xdo: Xdo, window: *mut *mut c_void) -> c_int;
fn xdo_get_window_location(
xdo: Xdo,
window: *mut c_void,
x: *mut c_int,
y: *mut c_int,
screen_num: *mut c_int,
) -> c_int;
fn xdo_get_window_size(
xdo: Xdo,
window: *mut c_void,
width: *mut c_int,
height: *mut c_int,
) -> c_int;
}
#[link(name = "X11")]
@@ -119,6 +133,50 @@ pub fn get_cursor_pos() -> Option<(i32, i32)> {
pub fn reset_input_cache() {}
pub fn get_focused_display(displays: Vec<DisplayInfo>) -> Option<usize> {
let mut res = None;
XDO.with(|xdo| {
if let Ok(xdo) = xdo.try_borrow_mut() {
if xdo.is_null() {
return;
}
let mut x: c_int = 0;
let mut y: c_int = 0;
let mut width: c_int = 0;
let mut height: c_int = 0;
let mut window: *mut c_void = std::ptr::null_mut();
unsafe {
if xdo_get_active_window(*xdo, &mut window) != 0 {
return;
}
if xdo_get_window_location(
*xdo,
window,
&mut x as _,
&mut y as _,
std::ptr::null_mut(),
) != 0
{
return;
}
if xdo_get_window_size(*xdo, window, &mut width as _, &mut height as _) != 0 {
return;
}
let center_x = x + width / 2;
let center_y = y + height / 2;
res = displays.iter().position(|d| {
center_x >= d.x
&& center_x < d.x + d.width
&& center_y >= d.y
&& center_y < d.y + d.height
});
}
}
});
res
}
pub fn get_cursor() -> ResultType<Option<u64>> {
let mut res = None;
DISPLAY.with(|conn| {
@@ -1228,7 +1286,7 @@ mod desktop {
if !home.is_empty() {
assert_eq!(d.home, home);
} else {
//
//
}
}
}

View File

@@ -17,8 +17,13 @@ use core_graphics::{
display::{kCGNullWindowID, kCGWindowListOptionOnScreenOnly, CGWindowListCopyWindowInfo},
window::{kCGWindowName, kCGWindowOwnerPID},
};
use hbb_common::sysinfo::{Pid, Process, ProcessRefreshKind, System};
use hbb_common::{anyhow::anyhow, bail, log, message_proto::Resolution};
use hbb_common::{
allow_err,
anyhow::anyhow,
bail, log,
message_proto::{DisplayInfo, Resolution},
sysinfo::{Pid, Process, ProcessRefreshKind, System},
};
use include_dir::{include_dir, Dir};
use objc::{class, msg_send, sel, sel_impl};
use scrap::{libc::c_void, quartz::ffi::*};
@@ -302,6 +307,20 @@ pub fn get_cursor_pos() -> Option<(i32, i32)> {
*/
}
pub fn get_focused_display(displays: Vec<DisplayInfo>) -> Option<usize> {
unsafe {
let main_screen: id = msg_send![class!(NSScreen), mainScreen];
let screen: id = msg_send![main_screen, deviceDescription];
let id: id =
msg_send![screen, objectForKey: NSString::alloc(nil).init_str("NSScreenNumber")];
let display_name: u32 = msg_send![id, unsignedIntValue];
displays
.iter()
.position(|d| d.name == display_name.to_string())
}
}
pub fn get_cursor() -> ResultType<Option<u64>> {
unsafe {
let seed = CGSCurrentCursorSeed();

View File

@@ -12,7 +12,7 @@ use hbb_common::{
bail,
config::{self, Config},
log,
message_proto::{Resolution, WindowsSession},
message_proto::{DisplayInfo, Resolution, WindowsSession},
sleep, timeout, tokio,
};
use std::process::{Command, Stdio};
@@ -65,6 +65,24 @@ use windows_service::{
use winreg::enums::*;
use winreg::RegKey;
pub fn get_focused_display(displays: Vec<DisplayInfo>) -> Option<usize> {
unsafe {
let hWnd = GetForegroundWindow();
let mut rect: RECT = mem::zeroed();
if GetWindowRect(hWnd, &mut rect as *mut RECT) == 0 {
return None;
}
displays.iter().position(|display| {
let center_x = rect.left + (rect.right - rect.left) / 2;
let center_y = rect.top + (rect.bottom - rect.top) / 2;
center_x >= display.x
&& center_x <= display.x + display.width
&& center_y >= display.y
&& center_y <= display.y + display.height
})
}
}
pub fn get_cursor_pos() -> Option<(i32, i32)> {
unsafe {
#[allow(invalid_value)]