mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-03-17 10:11:01 +03:00
feat: Add relative mouse mode (#13928)
* feat: Add relative mouse mode - Add "Relative Mouse Mode" toggle in desktop toolbar and bind to InputModel - Implement relative mouse movement path: Flutter pointer deltas -> `type: move_relative` -> new `MOUSE_TYPE_MOVE_RELATIVE` in Rust - In server input service, simulate relative movement via Enigo and keep latest cursor position in sync - Track pointer-lock center in Flutter (local widget + screen coordinates) and re-center OS cursor after each relative move - Update pointer-lock center on window move/resize/restore/maximize and when remote display geometry changes - Hide local cursor when relative mouse mode is active (both Flutter cursor and OS cursor), restore on leave/disable - On Windows, clip OS cursor to the window rect while in relative mode and release clip when leaving/turning off - Implement platform helpers: `get_cursor_pos`, `set_cursor_pos`, `show_cursor`, `clip_cursor` (no-op clip/hide on Linux for now) - Add keyboard shortcut Ctrl+Alt+Shift+M to toggle relative mode (enabled by default, works on all platforms) - Remove `enable-relative-mouse-shortcut` config option - shortcut is now always available when keyboard permission is granted - Handle window blur/focus/minimize events to properly release/restore cursor constraints - Add MOUSE_TYPE_MASK constant and unit tests for mouse event constants Note: Relative mouse mode state is NOT persisted to config (session-only). Note: On Linux, show_cursor and clip_cursor are no-ops; cursor hiding is handled by Flutter side. Signed-off-by: fufesou <linlong1266@gmail.com> * feat(mouse): relative mouse mode, exit hint Signed-off-by: fufesou <linlong1266@gmail.com> * refact(relative mouse): shortcut Signed-off-by: fufesou <linlong1266@gmail.com> --------- Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
use crate::{
|
||||
common::{get_supported_keyboard_modes, is_keyboard_mode_supported},
|
||||
input::{MOUSE_BUTTON_LEFT, MOUSE_TYPE_DOWN, MOUSE_TYPE_UP, MOUSE_TYPE_WHEEL},
|
||||
input::{
|
||||
MOUSE_BUTTON_LEFT, MOUSE_BUTTON_RIGHT, MOUSE_TYPE_DOWN, MOUSE_TYPE_MASK,
|
||||
MOUSE_TYPE_TRACKPAD, MOUSE_TYPE_UP, MOUSE_TYPE_WHEEL,
|
||||
},
|
||||
ui_interface::use_texture_render,
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
@@ -1222,7 +1225,9 @@ impl<T: InvokeUiSession> Session<T> {
|
||||
}
|
||||
}
|
||||
|
||||
let (x, y) = if mask == MOUSE_TYPE_WHEEL || mask == MOUSE_TYPE_TRACKPAD {
|
||||
// Compute event type once using MOUSE_TYPE_MASK for reuse
|
||||
let event_type = mask & MOUSE_TYPE_MASK;
|
||||
let (x, y) = if event_type == MOUSE_TYPE_WHEEL || event_type == MOUSE_TYPE_TRACKPAD {
|
||||
self.get_scroll_xy((x, y))
|
||||
} else {
|
||||
(x, y)
|
||||
@@ -1231,8 +1236,6 @@ impl<T: InvokeUiSession> Session<T> {
|
||||
// #[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
let (alt, ctrl, shift, command) =
|
||||
keyboard::client::get_modifiers_state(alt, ctrl, shift, command);
|
||||
|
||||
use crate::input::*;
|
||||
let is_left = (mask & (MOUSE_BUTTON_LEFT << 3)) > 0;
|
||||
let is_right = (mask & (MOUSE_BUTTON_RIGHT << 3)) > 0;
|
||||
if is_left ^ is_right {
|
||||
@@ -1252,9 +1255,8 @@ impl<T: InvokeUiSession> Session<T> {
|
||||
// to-do: how about ctrl + left from win to macos
|
||||
if cfg!(target_os = "macos") {
|
||||
let buttons = mask >> 3;
|
||||
let evt_type = mask & 0x7;
|
||||
if buttons == MOUSE_BUTTON_LEFT
|
||||
&& evt_type == MOUSE_TYPE_DOWN
|
||||
&& event_type == MOUSE_TYPE_DOWN
|
||||
&& ctrl
|
||||
&& self.peer_platform() != "Mac OS"
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user