* 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>
* fix: prevent custom scale dialog from closing when interacting with slider
Wrapped MobileCustomScaleControls in GestureDetector with opaque behavior
to prevent touch events from propagating to parent dialog's clickMaskDismiss
handler. The slider now works correctly without closing the dialog.
Signed-off-by: Alessandro De Blasis <alex@deblasis.net>
* Update flutter/lib/mobile/widgets/custom_scale_widget.dart
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update flutter/lib/mobile/widgets/custom_scale_widget.dart
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update flutter/lib/mobile/widgets/custom_scale_widget.dart
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update flutter/lib/mobile/widgets/custom_scale_widget.dart
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Revert "fix: mobile remove "Scale custom" (#13323)"
This reverts commit 265d08fc3b.
* chore: keep remote_toolbar.dart cleanup (remove dead code)
The dead code removed in 265d08fc3 hasn't been used since Aug 2023.
Only reverting toolbar.dart is needed for the mobile Scale custom fix.
* Update flutter/lib/mobile/pages/remote_page.dart
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* refactor: Implement CustomScaleControlsMixin for shared scaling logic across mobile and desktop widgets
- Introduced a new mixin `CustomScaleControlsMixin` to encapsulate custom scale control logic, allowing for code reuse in both mobile and desktop widgets.
- Refactored `_CustomScaleMenuControlsState` and `_MobileCustomScaleControlsState` to utilize the new mixin, simplifying the scaling logic and reducing code duplication.
- Updated slider handling and state management to leverage the mixin's methods for improved maintainability.
Signed-off-by: Alessandro De Blasis <alex@deblasis.net>
* Update flutter/lib/desktop/widgets/remote_toolbar.dart
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update flutter/lib/mobile/widgets/custom_scale_widget.dart
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update flutter/lib/mobile/pages/remote_page.dart
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* refactor: changed from mixin to abstract class
Signed-off-by: Alessandro De Blasis <alex@deblasis.net>
* Revert "Update flutter/lib/mobile/pages/remote_page.dart"
This reverts commit 7c35897408.
* refactor: remove unnecessary tap event handling in custom scale controls
- Removed the `onTap` handler from the
Signed-off-by: Alessandro De Blasis <alex@deblasis.net>
* refactor: simplify MobileCustomScaleControls usage in remote_page.dart
- Removed unnecessary GestureDetector wrapper around MobileCustomScaleControls for cleaner code.
Signed-off-by: Alessandro De Blasis <alex@deblasis.net>
---------
Signed-off-by: Alessandro De Blasis <alex@deblasis.net>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* fix: Android, keyboard, map mode, workaround
The `KeyEvent.physicalKey.usbHidUsage` are wrong if using Microsoft
SwiftKey keyboard.
`window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM)` is a workaround for this issue.
Signed-off-by: fufesou <linlong1266@gmail.com>
* fix: clear callback on first image
Signed-off-by: fufesou <linlong1266@gmail.com>
* Android disable soft keyboard in remote page if not editing.
Signed-off-by: fufesou <linlong1266@gmail.com>
---------
Signed-off-by: fufesou <linlong1266@gmail.com>
1. Map mode. Check if the KeyEvent's usbHidUsage is correct.
2. Korean input, use listener to handle composing state.
Signed-off-by: fufesou <linlong1266@gmail.com>
* Add option auto record outgoing session
* In the same connection, all displays and all windows share the same
recording state.
todo:
Android check external storage permission
Known issue:
* Sciter old issue, stop the process directly without stop record, the record file can't play.
Signed-off-by: 21pages <sunboeasy@gmail.com>
* fix: TextFormField onChanged event triggered multiple times when Korean input
* logic fix for iOS
* add comments
* move 'onChanged' logic to handleSoftKeyboardInput
1. Merge code of mobile and desktop virtual display menu.
2. Mobile add seperate resolution menu, only support changing
resolutions.
3. Android add proxy setting
Signed-off-by: 21pages <sunboeasy@gmail.com>
* mobile add view mode menu, disable same menus as desktop
* show forbidden cursor when not view mode && no keyboard permission &&
not show remote cursor
* hide keyboard/mouse bottom action when keyboard disabled
* fix not listen keyboard permission change
* mobile missing changing resolution and http proxy setting, will add if
needed.
Signed-off-by: 21pages <sunboeasy@gmail.com>