- a probe or raster-stall failure record now also downgrades sessions
that are already running: main_set_local_option broadcasts the
fallback for failed-* health writes, which also closes the hole where
the watchdog's idempotence guard no-oped after the probe had already
written the record
- probe success requires a frame timing newer than the first push:
'consumed' advances inside the plugin callback before the GL/Metal
upload, so a raster thread hanging in the driver no longer counts as
a pass (and cannot clear a previous failure)
- watchdog failures are tagged with the failing backend
(failed-watchdog-rgba/gpu); the rgba-only probe clears only the rgba
class, so a working pixel-buffer path can no longer re-enable a
broken D3D shared-handle path every launch
- the watchdog pauses while the session's window is hidden (new
session_set_render_visible FFI wired to the window minimize/restore
events): a display registered in a minimized window no longer records
a false global failure; observation now counts pushes within the
window rather than since registration
- probe failure verdicts additionally require a resumed lifecycle,
matching the raster-stall monitor
- linux plugin: deferred-unref grace lengthened to 10s (no raster-side
completion barrier exists; documented as heuristic), ref bumped
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- watchdog: compare the plugin's cumulative consumed counter against a
snapshot taken when arming (re-arm was a no-op before), and judge on
cumulative pushes + elapsed time so sparse damage-driven streams are
still detected
- failure handling is idempotent (one record per breakage) and updates
every render session like main_set_local_option does, not only the
failing one; the fallback toast is not claimed for multi-display
windows the soft path cannot rescue
- probe: skip when the consumed API is missing (old plugin) or a
raster-stall is recorded (compositing could hang the main window);
a fail verdict requires fresh frame timings and a non-minimized
window; a pass never clears failed-raster-stall; toast only when
texture rendering was effectively on; probe pixel is transparent
- raster-stall monitor: judge on frame-timing staleness (a mid-episode
hang was undetectable before), gate on lifecycle/minimized/idle with
a moving quiet anchor, threshold 30s, shared with the camera page;
clear stateGlobal minimized flag on plain window restore
- adopt mismatched frame sizes only in multi-ui-session mode (legacy
mode pairs frames loosely and could ping-pong between displays)
- drop the now-dead closeSession parameter from texture destroy();
trim comments to repo style
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Root cause of #15848 (and the long-standing macOS #6296 / Linux #3343
class): raw native texture pointers are shared across the platform
thread, the engine raster thread and the video thread, with teardown
ordered by a 100 ms sleep - or, when moving a tab to a new window, by
nothing at all. A lost race frees the texture while it is still in use:
the raster thread parks on a destroyed lock (frozen/black view, a
never-presented 'transparent' hole, every later session black) and the
video thread hangs while holding session locks (app half-dead until
restart, still reported as Responding).
- unregister textures with compare-and-clear (new session_unregister_*
FFI): a late clear can no longer wipe a new window's registration
(#8016) and Rust never keeps pushing into a freed texture; the 100 ms
sleeps are gone (the plugins now drain in-flight pushes and defer
object deletion until the raster thread is done)
- guard the async texture create path against destroy racing it (#13596)
- per-display locks: the per-frame plugin call no longer holds
session-level locks, so a stalled plugin or driver call cannot freeze
every window's UI thread
- adopt the frame size after 30 consecutive mismatches instead of
dropping frames forever (silent black screen on a live connection)
- watchdog: frames pushed but never consumed by the engine fall the
session back to software rendering live, record texture-render-health,
and flip the effective default off; toggling the option clears the
record and re-arms validation
- Dart raster-stall monitor records a hung raster thread for the next
launch (rendering cannot be rescued in-process in that state)
- startup probe: render one frame through a 1x1 texture in the main
window each launch; failure disables texture rendering before the
first session goes black, a pass self-heals a stale failure record
Platform defaults are unchanged (macOS off, Win10+ on, Linux on).
Requires flutter_texture_rgba_renderer ad4c37e and
flutter_gpu_texture_renderer 767bb9f (pinned in pubspec).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* avatar
* refactor avatar display: unify rendering and resolve at use time
- Extract buildAvatarWidget() in common.dart to share avatar rendering
logic across desktop settings, desktop CM and mobile CM
- Add resolve_avatar_url() in Rust, exposed via FFI (SyncReturn),
to resolve relative avatar paths (e.g. "/avatar/xxx") to absolute URLs
- Store avatar as-is in local config, only resolve when displaying
(settings page) or sending (LoginRequest)
- Resolve avatar in LoginRequest before sending to remote peer
- Add error handling for network image load failures
- Guard against empty client.name[0] crash
- Show avatar in mobile settings page account tile
Signed-off-by: 21pages <sunboeasy@gmail.com>
* web: implement mainResolveAvatarUrl via js getByName
Signed-off-by: 21pages <sunboeasy@gmail.com>
* increase ipc Data enum size limit to 120 bytes
Signed-off-by: 21pages <sunboeasy@gmail.com>
---------
Signed-off-by: 21pages <sunboeasy@gmail.com>
Co-authored-by: 21pages <sunboeasy@gmail.com>
* 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>
1. Enable the RustDesk client to use WebSocket for either controlling or being controlled.
2. Fix TCP sending `register_pk` frequently
Note:
1. Because hbb_common directly uses `use_ws` to read config directly, rustdesk also directly reads config
Signed-off-by: 21pages <sunboeasy@gmail.com>
1. Web, build.
2. Web and mobile, `onSubmitted` for ID text field.
3. Web, remove unused key 'toggle_option'.
Signed-off-by: fufesou <linlong1266@gmail.com>
* add custom password to unlock settings
* If not set, use admin password; if set, use custom settings password.
* At least 4 characters.
* Set with gui or command line.
Signed-off-by: 21pages <sunboeasy@gmail.com>
* Update cn.rs
---------
Signed-off-by: 21pages <sunboeasy@gmail.com>
Co-authored-by: RustDesk <71636191+rustdesk@users.noreply.github.com>