mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-10-19 16:17:03 +00:00
master
19
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
256dc9bc12 |
docs: scope the -p rule to macOS and Windows
Linux CI runs cargo test --workspace, so a Linux-gated test in another crate already runs there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WS1HTjp6UQuG43KEcQPq1R |
||
|
|
b1761ee676 |
Ci run all dart tests (#16328)
* ci: run every Dart test, not three files The step ran only the three cursor test files, so the other nine files under flutter/test (terminal, file model, autocomplete, ...) never ran on any pull request. With no path the runner takes the whole directory. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EZ49AbZJYfm8NTp5yDPMab * ci: run the Rust tests CI could not reach cargo test --workspace runs with the default features on x86_64 Linux only, so the tests behind `windows`, `not(target_os = "linux")`, `unix-file-copy-paste` and drmtap_dl's `tests` module never ran: the platform, portable-service and audio tests, the clipboard crate's file copy-paste and Windows file-name tests, and the drmtap loader's. The macOS and Windows build jobs now run `cargo test --lib` after the build with the build's own feature set, plus the clipboard crate. The Linux job's list of named test runs gains drmtap_dl and the clipboard feature. AGENTS.md says where tests go and what CI runs. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EZ49AbZJYfm8NTp5yDPMab Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WS1HTjp6UQuG43KEcQPq1R * ci: drop the skips for tests that no longer exist #16539 removed test_get_cursor_pos and test_get_key_state, the only tests these skips matched. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WS1HTjp6UQuG43KEcQPq1R --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
0740063863 |
Keyboard shortcuts (#14933)
* fix web break introduced in
|
||
|
|
4812a9815b |
AGENTS.md: limit corner-case growth and test bloat
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
08affc69c4 |
Fix clipboard range overflow (#16329)
* fix(clipboard): unix file server, bound range reads The Range request fields nPositionLow and cbRequested are UINT32s carried in i32 fields, but were sign-extended to u64. A negative cbRequested became a near-u64::MAX length, `offset + length` wrapped past the clamp, and the server tried to allocate a u64::MAX buffer, aborting the process. Sign-extending nPositionLow also rejected offsets whose low word is >= 2 GiB, breaking reads past 2 GiB in large files. - decode nPositionLow and cbRequested as u32 - clamp with `length > file.size - offset` (offset <= size is checked above) - allocate the read buffer fallibly and return an error instead of aborting Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(enigo): win, scale absolute mouse moves without overflow mouse_move_to multiplied the peer-supplied coordinate by 65535 in i32, which overflows for large values, and divided by the virtual screen size, which panics if the metrics come back as 0. Scale in i64, clamp to i32, and skip the move when the virtual screen size is unavailable. Results for inputs that did not overflow are unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs(agents): avoid unthrottled high-frequency debug logs Debug output is written to the log file, so per-packet / per-event log sites must use trace or hbb_common's throttled_log!. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(clipboard): unix file server, reject range reads over the frame limit A response larger than MAX_FRAME_LENGTH (1 GiB) cannot be encoded for sending, yet the server allocated and read it first, then failed the send. Reject such requests before allocating, so a peer can no longer make the server allocate more than 1 GiB per request. Requests that work today are unaffected. Drop the extra allocation-failure log; the caller already logs the error. Tests cover the wire decoding through read_file_contents (negative cbRequested, nPositionLow past 2 GiB) and the frame-limit rejection. Tests that use the global CLIP_FILES now take a shared lock. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(clipboard): keep file transfers on the file list they started from A file-contents request names a file only by its index, and the side that owns the files resolved it against whatever it held at that moment. On Windows 10+ Explorer's clipboard also offers FileContents, which the owner re-read from the live clipboard for every chunk, so copying another file mid-transfer spliced the new file into the one being pasted (#16332). A second paste, or another connection's paste, replaced the list the same way, and on macOS/Linux sync_files replaced CLIP_FILES on every host copy. Each request now names its list in the existing clip_data_id field: an FNV-1a hash of the file-descriptor PDU, which both sides already hold. Owners keep the last 4 lists they sent and serve a request from the list it names; an unknown id fails instead of reading another file. Peers that send no id read the list last sent to their connection, and a Windows owner stops reading the live clipboard once it has changed since the list was built. Tests cover a host copy and a second paste during a transfer, a list id sent to another connection, and the hash's reference vectors. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(clipboard): unix file server, cap a single range read at 16 MiB A peer could still make the server allocate and read up to the 1 GiB frame limit per request. Cap the data a single range read returns at 16 MiB. The read is clamped to the rest of the file first, and a larger one is refused rather than shortened: a short response reads as end of file to IStream callers on Windows and would silently truncate the copy. macOS requests 4 MiB per range (BLOCK_SIZE) and FUSE reads are smaller. A Windows client forwards the application's IStream::Read size, so only an application reading more than 16 MiB in one call is affected. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(enigo): win, warn (throttled) when a mouse move is skipped A missing virtual screen size is a fault that should show up in a user's log, but mouse_move_to runs per input event. Log it at warn at most once a minute via throttled_log! instead of at trace. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(clipboard): review fixes for the file lists kept per transfer unix owner: - A retired list closes its files and 8 MiB read buffers; they reopen, from offset 0, on the next read. - The new list is built aside and swapped in only on success, so a failed rebuild leaves the current list in place. - A rebuild with an unchanged id keeps its peers on the new list instead of retiring a duplicate, so re-copying a directory no longer pushes out a list that a transfer is still reading. Windows: - One served-list slot per list, recording every connection it was sent to, so pastes of the same list do not use up slots. - A request for an earlier list is served before OleGetClipboard, so a busy clipboard cannot fail it. - An IStream read over 16 MiB is split into requests the unix file server accepts. Reads up to 16 MiB take the unchanged path. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(clipboard): give each copied file list its own id The list id hashed only the descriptors, so two copies with identical names, sizes and times (the same file in two folders) shared an id and a transfer could read the other copy's files. Each owner now writes a random nonce into the first descriptor's clsid, inside the reserved bytes every peer skips; no owner sets FD_CLSID. The paste side hashes what it received, so it needs no change, and older peers ignore the bytes. Re-sending the same paths with the same descriptors keeps the nonce, and the id. Windows owner: - Serve a request from its list before the ownership check when the list is no longer current or the host clipboard now holds files from a peer, so another controller copying onto the host no longer fails in-flight transfers. Only lists sent to that connection are served. - Evict the list sent least recently instead of in insertion order. unix owner: take everything from the crate in one use block. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(clipboard,enigo): bound served-list reads, clamp absolute moves wf_cliprdr: the served-list branch runs before the ownership check, yet it allocated the peer's cbRequested (up to 4 GiB) before looking the list up. Accept only FILECONTENTS_SIZE or a range of at most 16 MiB there, which is all that clients sending an id ever request, and fail anything else before allocating. enigo: clamp the scaled absolute coordinate to 0..=65535, the range MOUSEEVENTF_ABSOLUTE takes, instead of to the i32 range. Coordinates on the virtual desktop give the same result as before; off-desktop ones now land on its edge. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(clipboard): keep a file list while it is being read, throttle read errors A unix paste side fetches every new file list as soon as the host copies, so each copy retires the previous list, and four copies during one long transfer evicted the list it was still reading. A kept list that serves a read now becomes the most recent (unix: back of the retired queue, Windows: last_served), so the next eviction takes a list nobody is reading. A failed file-contents read logged an error per request, and peers can now trigger new ones (an unknown list id, an over-limit range). Log it through throttled_log! instead. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(clipboard): unix, keep retired lists in the order they were sent A peer that sends no list id is served the list last sent to its connection, found by searching the retired queue from the back. That only holds while the queue stays in retirement order, which is the order lists were sent. The previous commit moved a list to the back on every read, so another connection reading an older list could make a peer's next chunk come from that list: a transfer of B continued with A's bytes. Keep the queue in retirement order and track recency in a separate last_used stamp, set on retirement and on each read. A full queue evicts the list with the lowest stamp, so a list still being read is kept. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(clipboard): unix, keep files being read open when their list is retired Retiring a list closed every file handle, so the next read of a file part-way through reopened it by path. If that path had been replaced meanwhile (an editor saving over it), the rest of the transfer came from the replacement: AAAABBBB arrived as AAAADDDD. Close only files that are not being read, such as the preloaded next file; a file part-way through keeps its handle and offset, and so its identity. Tests read two files of one list alternately, retire the list, replace both paths by rename, and check each file continues with its original bytes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(clipboard): cap Windows ranges, expire idle kept lists, check file identity Windows owner: refuse every FILECONTENTS_RANGE over 16 MiB before allocating. Only the served-list branch was capped; requests without an id still allocated whatever the peer asked for, up to 4 GiB. Both owners: a kept (retired / non-current) file list that nobody has read for 5 minutes is dropped, with its open files; its transfer is over or its peer gone. The current list never expires, as before. On Windows, reads of the current list through the existing path now also refresh its kept copy, so a long transfer does not lose its list once a newer one is sent. Windows owner: old-list reads compare the file's size and last-write time with the descriptor that was sent, on the handle they read from, and fail on a mismatch instead of reading whatever file now has that path. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test(clipboard): unix, check list expiry without backdating an Instant an_idle_retired_list_expires backdated a timestamp with Instant::now().checked_sub(TTL + 1s), which is None while the monotonic clock is under about five minutes, as on a freshly booted CI machine; the list then never expired and the test failed. expire_retired now takes the current time, and the test passes a later one instead. Callers pass Instant::now(), so behavior is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(clipboard): drop read-time refresh, idle expiry and rebuild reuse; tighten checks Remove the read-time recency and the 5-minute idle expiry on both owners, and the unix reuse of an unchanged rebuild (has_same_files). They covered corner cases, added state, and each brought regressions of its own. Kept lists are again evicted oldest first (unix) or least recently sent (Windows), 4 at most; a transfer that outlives 4 newer lists fails cleanly. Windows: serve kept lists after the existing ownership check again, so a request carrying a list id no longer bypasses it while the host clipboard holds files from another session. Refuse request types other than size or range before allocating. unix: a retired list's file must still match the size and modified time it was listed with, checked on the handle the read uses; a file replaced at its path before its read now fails instead of being served. Tests: drop the four tests of the removed behavior, add a_retired_list_refuses_a_file_replaced_before_its_read. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs(agents): handle corner cases raised in review with small fixes or docs A refactor added to cover a corner case rarely converges: new counters, timestamps and expiry rules interact with state existing code relies on, and the next review round finds the problems they introduced. Fix a corner case when the fix is a few lines with no new state; otherwise document it as a known limit, and ask before anything larger. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> |
||
|
|
e5d473407e | fix https://github.com/rustdesk/rustdesk/issues/16086 | ||
|
|
b50fde6910 |
add the base crate and repoint the moved modules at it (#16107)
* add the base crate and repoint the moved modules at it `libs/base` (crate `base`) takes the parts of hbb_common that only this app uses: `fs`, `platform`, `keyboard`, `message.proto`, and 145 of the 177 `config::keys` constants. hbb_common keeps what the server names, and the 32 keys it reads itself are re-exported from `base::config::keys` so call sites still see the full set through one path. Sources move verbatim. The only edits inside them are `crate::` prefixes that now have to say `hbb_common::`; `keyboard.rs` and `platform/windows.rs` are byte-identical. The crate stays on edition 2018, the edition the moved code was written under. `log`, `lazy_static` and `anyhow` become direct dependencies so the bare paths in that code resolve exactly as before, and its winapi features are spelled out rather than left to feature unification. Two call sites outside Rust and Cargo had to follow the move: the Android protobuf source dir, which still pointed at hbb_common/protos for message.proto, and the three AGENTS.md entries that named hbb_common for options, protos and file transfer. `scrap`'s `drm` feature now forwards to `base/wayland_probe`. Left pointing at hbb_common it would still have compiled, silently dropping the Wayland socket-probe fallback, so that forward is verified by a build with and without the feature. `config::keys` carries a test asserting its names stay disjoint from the ones hbb_common kept: the glob re-export and the local constants share a namespace, and Rust prefers the local item silently, so a name added to both sides would otherwise let client and server disagree with no diagnostic. Verified: macOS and Linux, debug and release, `--all-targets`; the 177 key constants diffed name-for-name and value-for-value; the generated protobuf types compared before and after; every `#[cfg]` gate on a moved import checked against its original; and every file that was `rustfmt`-clean before this change still is, compared against master file by file. Windows is checked by inspection only -- it cannot be compiled here. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EZ49AbZJYfm8NTp5yDPMab * one `use` per crate, and write the rule down `fs.rs` came out of the move with two ungated `use hbb_common::` statements, because the original single `use crate::{...}` had to give up `message_proto` to the new crate and the rest was left in a second block. Fold it back into one. A scan of the whole tree for the same shape finds nothing else: every other file with more than one top-level `use base::` or `use hbb_common::` is split by a `#[cfg]` that does not cover the whole block, or by `pub use` next to `use`. Those are the cases that cannot merge, so AGENTS.md now states both the rule and the exemption. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EZ49AbZJYfm8NTp5yDPMab --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
9a1c8da143 |
Agents regression surface (#16070)
* AGENTS.md: require a regression-surface check before a change is done The minimal-invasiveness rules say what to prefer; nothing made an agent check the final diff against them, so a feature could still route the old path through its new code while every principle was "followed". This adds the gate: audit every modified existing path, keep feature-off on the old code, report the regression surface, and treat an unnecessarily rewritten legacy path as a review finding whatever the tests say. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EZ49AbZJYfm8NTp5yDPMab * AGENTS.md: a scope check before shared code is touched The minimal-invasiveness rules are principles; this adds the stop condition that makes them mechanical. A fix for one path stays in that path, and an unrelated caller needing a placeholder argument to satisfy a changed signature is the signal that it did not. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EZ49AbZJYfm8NTp5yDPMab --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
d453a19601 |
AGENTS.md: require a regression-surface check before a change is done (#16068)
The minimal-invasiveness rules say what to prefer; nothing made an agent check the final diff against them, so a feature could still route the old path through its new code while every principle was "followed". This adds the gate: audit every modified existing path, keep feature-off on the old code, report the regression surface, and treat an unnecessarily rewritten legacy path as a review finding whatever the tests say. Claude-Session: https://claude.ai/code/session_01EZ49AbZJYfm8NTp5yDPMab Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
cbf9440281 |
Prefer active X11 session display (#15933)
* Prefer active X11 session display * Update linux.rs * fix(linux): keep the logind display only when it is a local one `get_display_from_session` returns the value pam_systemd was handed at session creation, and logind never updates it afterwards. That value is not always a usable local display: it can be qualified with this host (`myhost:0`), name an X forwarding endpoint (`localhost:10.0`), or be a bare `:`. Taking it unconditionally is worse than taking nothing, because a non-empty `self.display` suppresses every fallback below it, `get_display_by_user` and the `:0` default alike. The stripping at the end of `get_display_x11` does not save the last two cases either: it leaves `:` as is and turns `localhost:10.0` into a local looking `:10.0`, either of which is then exported as DISPLAY and leaves the session unreachable, where before this PR the host got a working `:0`. Strip this host so `myhost:0` is still accepted as `:0`, leave `localhost` in place, and require a display number after the colon. Anything else falls through to the existing chain. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TKJxvTT6NQDEcnkWBx5bLA * docs(agents): prefer a little duplication over a restructure The "Be minimally invasive" rules already ask for purely additive diffs, but not in the case where the addition would otherwise reshape an existing function so the two can share code. Repeating a few lines is the better diff there. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TKJxvTT6NQDEcnkWBx5bLA --------- Co-authored-by: RustDesk <71636191+rustdesk@users.noreply.github.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
f1a06f6765 | review rules | ||
|
|
0c00d576dd | improve comment rules | ||
|
|
dfca2c1b8f | update agents.md | ||
|
|
9a81c8a138 |
Drm deb in release workflow (#15776)
* docs(agents): add a comment-length rule Comments were growing to document rejected alternatives, past bugs and measurements. That belongs in the commit message, not the source. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * ci(drm): build the unattended-wayland deb in the release workflow The deb was built by a separate drm-capture workflow on a plain runner, so it diverged from every other Linux deb: different base, different vcpkg/ffmpeg, different toolchain. Move it into flutter-build.yml as build-rustdesk-linux-drm, mirroring build-rustdesk-linux's x86_64 path -- same ubuntu18.04 container, same vcpkg install, same rust and flutter. libdrmtap is built on the runner first and handed to the container via DRMTAP_PREBUILT_DIR, because bionic's meson is too old to build it. The job is ungated, so the --drm packaging path is exercised on every PR; only publishing stays gated on upload-artifact. drm-capture.yml is deleted along with docs/DRM_CAPTURE_SECURITY.md -- the 29 drm unit tests that workflow ran are no longer executed by CI. Three bugs the move exposed: - build.py anchored the libdrmtap paths on abspath(__file__), which is only cwd-independent on Python >= 3.9 (bpo-20443). The packaging container runs 3.6 and chdir's into flutter/, so the ABI-gate cross-check resolved one directory off and every --drm packaging run would have died with FileNotFoundError. Captured as REPO_ROOT at import instead. - DRMTAP_PREBUILT_DIR no longer needs DRMTAP_ALLOW_UNPINNED. A prebuilt dir inside the repo's own third_party/libdrmtap at the pinned sha is the pinned object, not an override, and is now verified as such. - The variant's Depends carried a bare libdrm2. libdrmtap needs drmModeGetFB2, so it is libdrm2 (>= 2.4.95); below that the package installed and could never capture. The loader also logs the dlerror now instead of discarding it, so a soname or glibc mismatch is named rather than surfacing as a generic "libdrmtap not available". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(drm): declare the unattended-wayland deb's real libc6 and libdrm floors libdrmtap is built on the ubuntu-22.04 runner while the rest of the deb comes from the ubuntu18.04 container, so the package has a mixed glibc floor and declared neither half. It installed happily on Ubuntu 20.04 / Debian 11 (glibc 2.31), then dlopen failed on GLIBC_2.34 and capture degraded to the PipeWire portal -- the one thing this variant exists to avoid. Measure the floor off the staged objects and put it in Depends, so apt refuses with a reason instead of handing over a package that can never capture. Measured rather than written down: the number moves whenever either base does, and it lands exactly on RHEL/Rocky 9 (glibc 2.34), where one off-by-one decides whether that whole family can install. drmModeGetFB2 landed in libdrm 2.4.101, not 2.4.95 -- checked against the libdrm tags, xf86drmMode.h first declares it in 2.4.101. The old floor admitted Debian 10 (2.4.97), where the .so is linked -z now and dies on an undefined symbol at dlopen. libdrmtap's own meson.build carries the same wrong number. Upload the deb on always(): the run that fails the drm check is the one whose artifact is most worth downloading. Publish stays gated on success, so an unverified build still cannot reach a release. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
85a5fefab8 |
fix(windows): prevent ghost and duplicate tray icons (#15689) (#15690)
* docs(agents): require minimally invasive, additive-first patches Codify the review feedback from the tray ghost-icon fix: fixes should add self-contained code around existing lines instead of restructuring them, keep platform-specific logic in src/platform/ with fn-local imports, and leave only thin one-line hooks in shared files. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(windows): stop duplicate tray icons from piling up (#15689) `check_process("--tray", ..)` is used to decide whether a tray process needs to be spawned, but it can miss one that is already running: it cannot read the command line of an elevated process from a non-elevated one (the installer spawns the tray elevated), and wmic, used by 32-bit builds since #11638, is gone from newer Windows 11. `connection.rs` runs that check once per incoming connection, so every miss added another tray icon and they kept piling up, which is the same blind spot behind #6692. Hold a named mutex in the session namespace as the authoritative single instance guard, so a redundant tray process exits before creating an icon. `ERROR_ACCESS_DENIED` also counts as "already running", since it means the mutex belongs to a tray we may not touch. Also remove the icon before the tray menu's "Stop service" calls uninstall_service(): on success it ends the process with std::process::exit, which skips the destructor that would call Shell_NotifyIcon(NIM_DELETE), so every click left a ghost icon behind. The icon is shown again if stopping the service failed or was cancelled. Ghost icons from the taskkill in the install/update/service flows are left alone here. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(windows): note that update_me's pid lookup can silently find nothing The pids are matched by command line, which comes back empty for a 32-bit build reading 64-bit processes (hence the `wmic` fallback of #11638, and `wmic` is no longer installed by default since Windows 11 24H2) and for a non-elevated process reading an elevated one. `taskkill` matches by image name and still works, but the session lists are then empty, so the restore guard silently restores nothing and the update leaves the user without a tray icon and main window. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(windows): record the confirmed cause of the duplicate tray icons Process Explorer output in #15689 pinned it down: run_after_run_cmds() spawns the tray in the caller's own context, so installing or toggling the service from a RustDesk that was itself started elevated leaves a high integrity tray behind, which a medium integrity main window cannot inspect afterwards. Record where the detection fails exactly, so the next reader doesn't have to rediscover that the executable path, not the command line, is what comes back empty. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
d6ea170061 |
Id whitelist (#15586)
* id whitelist * hbb_common * Update flutter/lib/common/widgets/dialog.dart Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * support wss:// for web client Signed-off-by: 21pages <sunboeasy@gmail.com> * fix: handle ID copying separately and remove whitelist logs Signed-off-by: 21pages <sunboeasy@gmail.com> * fix en translation Signed-off-by: 21pages <sunboeasy@gmail.com> * fix: check switch-side ID whitelist after login initialization Signed-off-by: 21pages <sunboeasy@gmail.com> * track pending 2FA challenge state Signed-off-by: 21pages <sunboeasy@gmail.com> * support Unicode IDs in whitelist settings Signed-off-by: 21pages <sunboeasy@gmail.com> * refactor: unify client ID resolution Signed-off-by: 21pages <sunboeasy@gmail.com> --------- Signed-off-by: 21pages <sunboeasy@gmail.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: 21pages <sunboeasy@gmail.com> |
||
|
|
0c86d46162 | translate all | ||
|
|
3a1622e8b5 |
refact(AGENTS.md): code rules, tokio (#14911)
* refact(AGENTS.md): code rules, tokio Signed-off-by: fufesou <linlong1266@gmail.com> * Update AGENTS.md * Update AGENTS.md * Update AGENTS.md * Update AGENTS.md --------- Signed-off-by: fufesou <linlong1266@gmail.com> Co-authored-by: RustDesk <71636191+rustdesk@users.noreply.github.com> |
||
|
|
0cf3e8ed40 | improve agent md |