mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-03-29 16: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:
@@ -5173,9 +5173,13 @@ impl Retina {
|
||||
|
||||
#[inline]
|
||||
fn on_mouse_event(&mut self, e: &mut MouseEvent, current: usize) {
|
||||
let evt_type = e.mask & 0x7;
|
||||
if evt_type == crate::input::MOUSE_TYPE_WHEEL {
|
||||
// x and y are always 0, +1 or -1
|
||||
let evt_type = e.mask & crate::input::MOUSE_TYPE_MASK;
|
||||
// Delta-based events do not contain absolute coordinates.
|
||||
// Avoid applying Retina coordinate scaling to them.
|
||||
if evt_type == crate::input::MOUSE_TYPE_WHEEL
|
||||
|| evt_type == crate::input::MOUSE_TYPE_TRACKPAD
|
||||
|| evt_type == crate::input::MOUSE_TYPE_MOVE_RELATIVE
|
||||
{
|
||||
return;
|
||||
}
|
||||
let Some(d) = self.displays.get(current) else {
|
||||
@@ -5421,6 +5425,9 @@ mod raii {
|
||||
.unwrap()
|
||||
.on_connection_close(self.0);
|
||||
}
|
||||
// Clear per-connection state to avoid stale behavior if conn ids are reused.
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
clear_relative_mouse_active(self.0);
|
||||
AUTHED_CONNS.lock().unwrap().retain(|c| c.conn_id != self.0);
|
||||
let remote_count = AUTHED_CONNS
|
||||
.lock()
|
||||
|
||||
Reference in New Issue
Block a user