Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
127 commits
Select commit Hold shift + click to select a range
c051e89
feat: add rustqs linux build workflow (from DeskForge)
bashrusakh Jun 25, 2026
11cf556
feat: add rustqs android build workflow (from DeskForge)
bashrusakh Jun 25, 2026
3f13307
fix(ci): android/linux min-test — system deps, vcpkg, ndk_arm64, Node…
Jun 25, 2026
f241579
fix(ci): bump actions/checkout@v7, github-script@v9 in windows min-test
Jun 25, 2026
4ed364a
fix(ci): add JAVA_HOME, gradle config, debug signing, jniLibs copy to…
Jun 26, 2026
171445b
fix(ci): package .deb/.rpm instead of tar.gz for linux min-test
Jun 26, 2026
77fa885
fix(ci): build both .deb and .rpm packages for linux min-test
Jun 26, 2026
8596700
fix(ci): rustqs-linux min-test build hardening
Jun 26, 2026
db03e45
merge rustqs/min-test into master
Jun 26, 2026
7c284ff
fix(ci): correct subosito/flutter-action SHA pin (typo: ae6d -> ae4d)
Jun 26, 2026
de0a9cc
fix(ci): use 'rpm' package (Ubuntu) instead of 'rpm-build' (Fedora)
Jun 26, 2026
ba7fc86
fix(ci): defensive apt cache refresh + remove debug noise
Jun 26, 2026
213b6da
Merge branch 'rustdesk:master' into master
bashrusakh Jun 26, 2026
a84d15f
feat: update rustqs-windows-min-test.yml
bashrusakh Jun 26, 2026
03ce171
feat: update rustqs-linux.yml
bashrusakh Jun 26, 2026
27639c9
feat: update rustqs-android.yml
bashrusakh Jun 26, 2026
92308c3
feat: update bridge.yml
bashrusakh Jun 26, 2026
4a54029
fix(update): msi, norestart (#15440)
fufesou Jun 27, 2026
ed15f35
fix: revert bridge.yml to upstream pattern (remove inputs.version, ch…
Jun 27, 2026
be3ebc0
feat: pass version from dispatch to VERSION env, add version input
Jun 27, 2026
2ee580d
Update translation for outdated installation message (#15427)
maisondasilva Jun 28, 2026
10d5250
Update flutter-build.yml (#15454)
twprh Jun 28, 2026
4b1ef9e
fix(android): sync input service state with Flutter (#15419)
yuqianglianshou Jun 29, 2026
0497814
Add authentication details to connection audit (#15456)
21pages Jun 29, 2026
435f6ec
update copyright
rustdesk Jun 30, 2026
b3bd188
update hbb_common
rustdesk Jun 30, 2026
9d1ab3f
fix the AOM tile-control argument type
rustdesk Jul 1, 2026
dce221b
fix(clipboard): make CLIPRDR format-map growth checked (#15493)
fufesou Jul 2, 2026
a2b7946
fix: auto-close terminal tab/window when shell exits (#15448)
alonginwind Jul 2, 2026
9fdb841
fix: parse exit code of flutter web (#15501)
fufesou Jul 3, 2026
cf1de4d
Feature: Restore the last viewed monitor on auto reconnect (#15441)
StealUrKill Jul 5, 2026
493b14b
Fix/session scope permission audit (#15469)
fufesou Jul 5, 2026
37141af
refact: remove feature cli (#15524)
fufesou Jul 6, 2026
28930c0
fix: non-E2EE show dialog (#15514)
fufesou Jul 6, 2026
6c57829
bump to 1.4.9
rustdesk Jul 6, 2026
e214997
harden wf_cliprdr.c (#15515)
rustdesk Jul 7, 2026
005a8b4
Update Korean (#15525)
VenusGirl Jul 8, 2026
acb9f63
Update it.rs (#15531)
bovirus Jul 8, 2026
8314335
fix: update download, force tls (#15529)
fufesou Jul 9, 2026
29e1852
fix: ci: macos: allow signed but not notarized dmg (#15530)
foresee-io Jul 9, 2026
480e9e8
Fix default Android API version mismatch between vcpkg and rest of bu…
basilgello Jul 10, 2026
12b5cc7
Revert "fix: ci: macos: allow signed but not notarized dmg (#15530)" …
rustdesk Jul 10, 2026
685a89a
target Android 15
rustdesk Jul 10, 2026
137298e
revert back
rustdesk Jul 10, 2026
865fe71
Update Portuguese translations for clarity (#15534)
maisondasilva Jul 11, 2026
94a2a2b
fix https://github.com/rustdesk/rustdesk/issues/15566
rustdesk Jul 11, 2026
fa418ca
Translate 'Continue' to 'Continuar' in ptbr.rs (#15567)
maisondasilva Jul 13, 2026
bdb38c4
fix: check valid id (#15535)
fufesou Jul 14, 2026
cf2b28f
fix linux llvm22 build (#15565)
peeweep Jul 15, 2026
5abf4e9
Fix disabled installation bypass (#15598)
21pages Jul 16, 2026
96e2a33
restrict switch sides to remote desktop sessions (#15610)
21pages Jul 17, 2026
61f0944
Fix Adjust Window sizing across DPI (#15592)
21pages Jul 18, 2026
082a5a2
Revert "Fix Adjust Window sizing across DPI (#15592)" (#15620)
rustdesk Jul 18, 2026
5f015c9
Translate Continue into Simplified Chinese (#15621)
cuishuang Jul 18, 2026
c01300b
fix(ipc): never adopt an empty id from the main IPC (#15626)
VibeCodyH Jul 20, 2026
20ab5ab
fix(deploy): don't wipe local id when --deploy gets an empty --id (#1…
VibeCodyH Jul 20, 2026
7696b0e
fix(linux): forward forced display server to user server (#15627)
gateslu Jul 20, 2026
5b4d6ba
fix: wrap BackingScaleFactor in autoreleasepool to stop NSDictionary …
Kuksgauzen Jul 20, 2026
1c2dd71
Translate 'Continue' to 'Kontynuuj' in Polish (#15641)
phatterit Jul 21, 2026
929e989
feat(macos): silent auto-update with security hardening (#15550)
bmmh1 Jul 22, 2026
beaa754
fix stale primary display selection (#15460)
21pages Jul 23, 2026
b4af821
fix: refresh wayland uinput range on compositor layout change (#15628)
VibeCodyH Jul 24, 2026
ad9dac1
fix(keyboard): jis, macos, muhenkan henkan (#15669)
fufesou Jul 25, 2026
cefff78
feat(recording): add visibility and service storage options (#15662)
21pages Jul 25, 2026
57456f0
feat(terminal): add Ctrl and Alt toggles to mobile terminal keyboard …
dongrencd Jul 25, 2026
b1fad7b
fix: validate RGBA clipboard dimensions (#15672)
FrederickStempfle Jul 26, 2026
5882346
fix: validate remote audio channel count (#15673)
FrederickStempfle Jul 26, 2026
eefd22b
fix(macos): prevent remote keyboard focus leaks (#15629)
fufesou Jul 26, 2026
d6ea170
Id whitelist (#15586)
rustdesk Jul 27, 2026
dabdbf7
improve id wildcast
rustdesk Jul 27, 2026
4dd8e20
improve id whitelist login failures
rustdesk Jul 28, 2026
d412d19
aligned_u8_vec
rustdesk Jul 28, 2026
85a5fef
fix(windows): prevent ghost and duplicate tray icons (#15689) (#15690)
rustdesk Jul 29, 2026
a6708f4
fix https://github.com/rustdesk/rustdesk/issues/15703
rustdesk Jul 29, 2026
12f2de5
chore(flutter): point window_manager at the post-revert main (#15709)
rustdesk Jul 29, 2026
72c052c
docs: fix double space in CODE_OF_CONDUCT.md (#15714)
lunar-me Jul 30, 2026
8545b5e
docs: fix 'gressful' misspelling to 'graceful' in libs/clipboard/READ…
lunar-me Jul 30, 2026
3442648
docs: fix 'lowlevel' spelling to 'low-level' in libs/clipboard/README…
lunar-me Jul 30, 2026
9aeb54c
Fix flutter white window forceredraw (#15717)
rustdesk Jul 30, 2026
e63df74
fix(linux): make quit_cm actually quit the connection manager (#15718)
rustdesk Jul 30, 2026
c6c53f0
chore(flutter): bump desktop_multi_window to fix the Windows /WX build
rustdesk Jul 30, 2026
5aeb4cf
add zstd to reqwest
rustdesk Jul 30, 2026
006b973
fix(linux): load librustdesk.so relative to the executable (#15719)
rustdesk Jul 30, 2026
e0254d9
fix ci
rustdesk Jul 30, 2026
807e05e
refact(oidc): login with api domain (#15710)
fufesou Jul 30, 2026
b19f1ef
Add SBOM (Software Bill of Materials) for the EU Cyber Resilience Act…
danielmarschall Aug 3, 2026
6c69faa
Update de.rs (#15733)
Mr-Update Aug 3, 2026
a5018a0
chore(ios): remove unused GoogleService-Info.plist (#15752)
rustdesk Aug 3, 2026
ffe20bb
Login options error feedback (#15727)
rustdesk Aug 4, 2026
2f8822e
Update nl.rs (#15754)
Stephan-P Aug 4, 2026
d752823
swtich_code for hbbs (#15615)
rustdesk Aug 4, 2026
e6dd925
fix(android): close outgoing sessions when the task is swiped away (#…
rustdesk Aug 4, 2026
a84bad4
refact(oidc): manually open the browser (#15706)
fufesou Aug 4, 2026
4389687
fix(wayland): subscribe to portal Response before making the request …
xPrimeTime Aug 4, 2026
6f1eb16
fix(clipboard): validate files (#15693)
fufesou Aug 4, 2026
3cf32e7
fix(wayland): scale portal pointer coordinates on niri (#15683)
Fadouse Aug 4, 2026
402ed07
fix: Harden Windows installer temp command scripts (#15634)
fufesou Aug 4, 2026
ef3a575
Update Dutch translation (#15767)
RijckAlex Aug 5, 2026
7eb9150
Audit retry nonce (#15759)
rustdesk Aug 6, 2026
cc85685
fix(linux): stop losing every inhibitor when the ScreenSaver name is …
fxd0h Aug 6, 2026
f5ab01f
fix(clipboard): win, populate file formats (#15692)
fufesou Aug 6, 2026
ddad479
feat(linux): DRM/KMS direct capture for Wayland — no portal consent r…
fxd0h Aug 6, 2026
9a81c8a
Drm deb in release workflow (#15776)
rustdesk Aug 7, 2026
429c8c6
Translate sign-in message to Portuguese (#15770)
maisondasilva Aug 7, 2026
6fd96dd
Update Greek translations for various terms (#15782)
panos78 Aug 7, 2026
4234b99
WebClient: 3.44 webcodecs offline (#15722)
rustdesk Aug 7, 2026
d057fe1
docs: fix singular contribution in docs/CONTRIBUTING.md (#15789)
lunar-me Aug 8, 2026
11190fa
docs: fix comma splice gui tutorial in README.md (#15787)
lunar-me Aug 8, 2026
1f440f5
Merge origin/master into upd
Aug 8, 2026
944de55
Merge pull request #3 from bashrusakh/upd
bashrusakh Aug 8, 2026
2915076
fix(linux): bound the xrandr call in the wayland primary-display look…
fxd0h Aug 9, 2026
7c23fd3
Revert "fix(linux): bound the xrandr call in the wayland primary-disp…
rustdesk Aug 9, 2026
594e638
harden login request retry
rustdesk Aug 10, 2026
d407db9
fix(client): allow switch-sides back-connection in incoming-only mode…
rustdesk Aug 10, 2026
947cb3f
propagates the hash-handler continuation result through both connecti…
rustdesk Aug 10, 2026
ff07ff7
fix(terminal): send SGR mouse wheel reports with the button codes app…
rustdesk Aug 11, 2026
23256e6
fix(i18n): complete Traditional Chinese sign-in strings (#15829)
nrps9909 Aug 11, 2026
1d09760
fix(terminal): keep selection aligned after clearing scrollback (#15831)
fufesou Aug 11, 2026
6382204
fix: upgrade fuser to 0.16.0 (GHSA-cvmj-47v9-35m9) (#15834)
anupamme Aug 12, 2026
10bcf97
Revert "fix: upgrade fuser to 0.16.0 (GHSA-cvmj-47v9-35m9) (#15834)" …
rustdesk Aug 12, 2026
dfca2c1
update agents.md
rustdesk Aug 12, 2026
c4fd7d6
refact: fuser 0.16.0, cargo 1.75.0 (#15844)
fufesou Aug 12, 2026
d829d14
fix(linux): serve the Wayland login screen the DRM backend was built …
fxd0h Aug 13, 2026
d1da05c
refact: remove feature plugin-framework (#15854)
fufesou Aug 14, 2026
7aa98d4
Refact/plugin removal leftovers (#15864)
rustdesk Aug 14, 2026
f298a7d
Merge branch 'rustdesk:master' into master
bashrusakh Aug 16, 2026
bdcfcb2
workflow: sync active branch with fork master
Aug 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 108 additions & 7 deletions .github/patches/apply_flutter_3.44_source_patches.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,109 @@
# therefore CRLF-safe.
set -euo pipefail

readonly NO_MATCHES=0
readonly SINGLE_MATCH=1
readonly THEME_MATCHES=2

has_exact_count() {
local -r expected_count="$1"
local -r pattern="$2"
local -r file="$3"
local actual_count
[[ -r "$file" ]] || return 1
actual_count="$(grep -cF "$pattern" "$file" || true)"
[[ "$actual_count" -eq "$expected_count" ]]
}

# The target background-color line must directly follow DialogThemeData in the selected range.
has_dialog_background_in_theme_range() {
local -r start_pattern="$1"
local -r end_pattern="$2"
local -r target_pattern="$3"
local -r file="$4"
awk -v start_pattern="$start_pattern" \
-v end_pattern="$end_pattern" \
-v target_pattern="$target_pattern" '
index($0, start_pattern) {
in_theme = 1
next
}
in_theme && index($0, end_pattern) {
exit
}
in_theme && index($0, "dialogTheme: DialogThemeData(") {
if (getline > 0) {
line = $0
sub(/\r$/, "", line)
sub(/^[[:space:]]+/, "", line)
matched = line == target_pattern
}
exit
}
END {
exit matched ? 0 : 1
}
' "$file"
}

validate_patch_inputs() {
if [[ ! -f flutter/lib/common.dart || ! -r flutter/lib/common.dart ]]; then
echo "Flutter 3.44 source patch input is missing or unreadable: flutter/lib/common.dart" >&2
return 1
fi
if [[ ! -f flutter/pubspec.yaml || ! -r flutter/pubspec.yaml ]]; then
echo "Flutter 3.44 source patch input is missing or unreadable: flutter/pubspec.yaml" >&2
return 1
fi
}

is_complete_patch_state() {
has_exact_count "$THEME_MATCHES" 'dialogTheme: DialogThemeData(' flutter/lib/common.dart &&
has_exact_count "$THEME_MATCHES" 'tabBarTheme: const TabBarThemeData(' flutter/lib/common.dart &&
has_exact_count "$SINGLE_MATCH" 'backgroundColor: Colors.white,' flutter/lib/common.dart &&
has_exact_count "$SINGLE_MATCH" 'backgroundColor: Color(0xFF18191E),' flutter/lib/common.dart &&
has_exact_count "$SINGLE_MATCH" 'extended_text: 15.0.2' flutter/pubspec.yaml &&
has_exact_count "$SINGLE_MATCH" 'google_fonts: ^8.1.0' flutter/pubspec.yaml &&
has_exact_count "$NO_MATCHES" 'dialogTheme: DialogTheme(' flutter/lib/common.dart &&
has_exact_count "$NO_MATCHES" 'tabBarTheme: const TabBarTheme(' flutter/lib/common.dart &&
has_exact_count "$NO_MATCHES" 'extended_text: 14.0.0' flutter/pubspec.yaml &&
has_exact_count "$NO_MATCHES" 'google_fonts: ^6.2.1' flutter/pubspec.yaml &&
has_dialog_background_in_theme_range 'static ThemeData lightTheme = ThemeData(' \
'static ThemeData darkTheme = ThemeData(' 'backgroundColor: Colors.white,' \
flutter/lib/common.dart &&
has_dialog_background_in_theme_range 'static ThemeData darkTheme = ThemeData(' \
'scrollbarTheme: scrollbarThemeDark,' 'backgroundColor: Color(0xFF18191E),' \
flutter/lib/common.dart
}

is_unpatched_state() {
has_exact_count "$THEME_MATCHES" 'dialogTheme: DialogTheme(' flutter/lib/common.dart &&
has_exact_count "$THEME_MATCHES" 'tabBarTheme: const TabBarTheme(' flutter/lib/common.dart &&
has_exact_count "$SINGLE_MATCH" 'extended_text: 14.0.0' flutter/pubspec.yaml &&
has_exact_count "$SINGLE_MATCH" 'google_fonts: ^6.2.1' flutter/pubspec.yaml &&
has_exact_count "$NO_MATCHES" 'dialogTheme: DialogThemeData(' flutter/lib/common.dart &&
has_exact_count "$NO_MATCHES" 'tabBarTheme: const TabBarThemeData(' flutter/lib/common.dart &&
has_exact_count "$NO_MATCHES" 'backgroundColor: Colors.white,' flutter/lib/common.dart &&
has_exact_count "$NO_MATCHES" 'backgroundColor: Color(0xFF18191E),' flutter/lib/common.dart &&
has_exact_count "$NO_MATCHES" 'extended_text: 15.0.2' flutter/pubspec.yaml &&
has_exact_count "$NO_MATCHES" 'google_fonts: ^8.1.0' flutter/pubspec.yaml
}

if ! validate_patch_inputs; then
exit 1
fi

if is_complete_patch_state; then
echo "Flutter 3.44 source patches already applied."
git --no-pager diff -- flutter/lib/common.dart flutter/pubspec.yaml
exit 0
fi

if ! is_unpatched_state; then
echo "Flutter 3.44 source patches are partially applied or their anchors have drifted." >&2
exit 1
fi

# ThemeData API renames (Flutter 3.27+):
sed -i 's/dialogTheme: DialogTheme(/dialogTheme: DialogThemeData(/g' flutter/lib/common.dart
sed -i 's/tabBarTheme: const TabBarTheme(/tabBarTheme: const TabBarThemeData(/g' flutter/lib/common.dart
Expand All @@ -28,12 +131,10 @@ sed -i '/static ThemeData darkTheme = ThemeData(/,/scrollbarTheme: scrollbarThem
sed -i 's/extended_text: 14.0.0/extended_text: 15.0.2/' flutter/pubspec.yaml
sed -i 's/google_fonts: \^6.2.1/google_fonts: ^8.1.0/' flutter/pubspec.yaml

# Fail loudly if any expected string drifted, so we never silently build unpatched:
grep -qF 'dialogTheme: DialogThemeData(' flutter/lib/common.dart
grep -qF 'tabBarTheme: const TabBarThemeData(' flutter/lib/common.dart
grep -qF 'backgroundColor: Colors.white,' flutter/lib/common.dart
grep -qF 'backgroundColor: Color(0xFF18191E),' flutter/lib/common.dart
grep -qF 'extended_text: 15.0.2' flutter/pubspec.yaml
grep -qF 'google_fonts: ^8.1.0' flutter/pubspec.yaml
# Fail loudly if any expected substitution did not produce the complete state.
if ! is_complete_patch_state; then
echo "Flutter 3.44 source patches did not produce the expected state." >&2
exit 1
fi

git --no-pager diff -- flutter/lib/common.dart flutter/pubspec.yaml
51 changes: 51 additions & 0 deletions .github/patches/apply_flutter_3.44_web_patches.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/usr/bin/env bash
# Prepares a web build on Flutter 3.44.x. Companion to
# apply_flutter_3.44_source_patches.sh (which it runs first): the web target
# additionally needs qr_code_scanner's web implementation patched for the
# dart:ui platformViewRegistry removal, and flutter/web/fonts refreshed with
# the font paths the 3.44 engine requests for offline/air-gapped support
# (rustdesk-server-pro#996; see flutter/web/fonts/sync_fonts.py).
#
# Run from the repository root with Flutter 3.44.x on PATH, then build:
# bash .github/patches/apply_flutter_3.44_web_patches.sh
# (cd flutter && flutter build web --release) # or ./web/js/flutter_build.py
#
# Idempotent. To undo the source changes locally:
# git checkout -- flutter/lib/common.dart flutter/pubspec.yaml flutter/pubspec.lock
set -euo pipefail

flutter --version | grep -q "Flutter 3\.44\." || {
echo "Flutter 3.44.x must be on PATH; found:" >&2
flutter --version | grep "^Flutter" >&2 || true
exit 1
}

# Shared 3.44 source/pubspec patches own their complete-state validation.
bash .github/patches/apply_flutter_3.44_source_patches.sh

# Populate the pub cache with the 3.44 dependency resolution.
(cd flutter && flutter pub get)

# qr_code_scanner 1.0.1 (unmaintained) reads platformViewRegistry from
# dart:ui, which Flutter 3.44 removed; point it at dart:ui_web instead. The
# patched file also compiles on Flutter 3.24 (dart:ui_web exists there), so
# mutating the shared pub cache is safe for other local builds.
QR_WEB="${PUB_CACHE:-$HOME/.pub-cache}/hosted/pub.dev/qr_code_scanner-1.0.1/lib/src/web/flutter_qr_web.dart"
if ! grep -qF "dart:ui_web" "$QR_WEB"; then
sed -i.bak "s|import 'dart:ui' as ui;|import 'dart:ui' as ui; import 'dart:ui_web' as ui_web;|" "$QR_WEB"
rm -f "$QR_WEB.bak"
fi
if grep -qF "ui.platformViewRegistry" "$QR_WEB"; then
sed -i.bak "s|ui\.platformViewRegistry|ui_web.platformViewRegistry|g" "$QR_WEB"
rm -f "$QR_WEB.bak"
fi

# Mirror the fonts this engine version requests into flutter/web/fonts.
python3 flutter/web/fonts/sync_fonts.py

# Fail loudly if any expected state is missing:
grep -qF "import 'dart:ui' as ui; import 'dart:ui_web' as ui_web;" "$QR_WEB"
grep -qF "ui_web.platformViewRegistry" "$QR_WEB"
grep -qF 'google_fonts: ^8.1.0' flutter/pubspec.yaml

echo "Flutter 3.44 web patches applied."
7 changes: 3 additions & 4 deletions .github/scripts/write_artifact_manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,13 +291,12 @@ def main() -> None:
raise SystemExit("manifest production requires platform, app name, and version")
output = output_root(args.output)
names = expected_names(args.platform, args.app_name, args.version)
private_path = output / PRIVATE_FILENAME
if private_path.exists() or private_path.is_symlink():
raise SystemExit("public manifest output must not contain custom_.txt")
validate_output_tree(output, set(names))
paths = [safe_output_file(output, name) for name in names]
private_filenames: list[str] = []
private_path = output / PRIVATE_FILENAME
if private_path.exists() or private_path.is_symlink():
safe_output_file(output, PRIVATE_FILENAME)
private_filenames.append(PRIVATE_FILENAME)
file_records: list[dict[str, str | int]] = []
for name, path in zip(names, paths, strict=True):
before = path.lstat()
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/bridge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
target: x86_64-unknown-linux-gnu,
os: ubuntu-22.04,
extra-build-args: "",
flutter-version: "3.44.0",
flutter-version: "3.44.8",
artifact-name: "bridge-artifact-flutter-3.44",
}
steps:
Expand Down
5 changes: 1 addition & 4 deletions .github/workflows/rustqs-android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ name: rustqs android min test
# Android custom_.txt is packaged as a Flutter asset and handed to the native
# server from MainService before the server thread starts.
#
# Путь в форке: .github/workflows/rustqs-android.yml на ветке rustqs/min-test.
# Путь в форке: .github/workflows/rustqs-android.yml на ветке rustqs/workflows.
# ============================================================================

on:
Expand Down Expand Up @@ -681,9 +681,6 @@ jobs:
set -euo pipefail
MANIFEST_PUBLICATION_TIMESTAMP=$(date -u '+%Y-%m-%dT%H:%M:%SZ')
export MANIFEST_PUBLICATION_TIMESTAMP
if [ -f flutter/assets/custom_.txt ]; then
cp -- flutter/assets/custom_.txt output/custom_.txt
fi
test -f "${MANIFEST_HELPER_PATH:-}" || { echo "::error::preserved manifest helper is unavailable"; exit 1; }
python3 "$MANIFEST_HELPER_PATH" \
--platform "$MANIFEST_PLATFORM" --app-name "$RQS_APP_NAME" --version "$RQS_VERSION" \
Expand Down
7 changes: 2 additions & 5 deletions .github/workflows/rustqs-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ name: rustqs linux min test
# Контракт: единственный build path — authenticated DFP1 enc_payload от API.
# Direct/manual runs without a valid payload fail closed before checkout/build.
#
# Путь в форке: .github/workflows/rustqs-linux.yml на ветке rustqs/min-test.
# Путь в форке: .github/workflows/rustqs-linux.yml на ветке rustqs/workflows.
# ============================================================================

on:
Expand Down Expand Up @@ -489,7 +489,7 @@ jobs:
git apply flutter_3.24.4_dropdown_menu_enableFilter.diff

# Historical two-stage build shape: first cargo lib with the required features,
# then build.py for the Flutter UI and packages. The old upstream flutter-build.yml
# then build.py for the Flutter UI and packages. The former upstream workflow
# reference is not the active workflow source.
- name: Build rustdesk (Flutter Linux)
run: |
Expand Down Expand Up @@ -560,9 +560,6 @@ jobs:
set -euo pipefail
MANIFEST_PUBLICATION_TIMESTAMP=$(date -u '+%Y-%m-%dT%H:%M:%SZ')
export MANIFEST_PUBLICATION_TIMESTAMP
if [ -f flutter/build/linux/x64/release/bundle/custom_.txt ]; then
cp -- flutter/build/linux/x64/release/bundle/custom_.txt output/custom_.txt
fi
test -f "${MANIFEST_HELPER_PATH:-}" || { echo "::error::preserved manifest helper is unavailable"; exit 1; }
python3 "$MANIFEST_HELPER_PATH" \
--platform "$MANIFEST_PLATFORM" --app-name "$RQS_APP_NAME" --version "$RQS_VERSION" \
Expand Down
6 changes: 2 additions & 4 deletions .github/workflows/rustqs-windows.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: rustqs windows min test
# Workflow сборки rustqs.exe (Flutter Windows) в форке rustdesk.
# Historical source note: the steps were adapted from build-for-windows-flutter@1.4.7.
# The current fork source/ref is 1.4.8; active dispatch uses authenticated DFP1 only.
# The current fork source/ref is 1.4.9; active dispatch uses authenticated DFP1 only.
# (L1 config.rs server+key, L2 allowCustom+custom_.txt, L3 brand+rename exe).
#
# Единственный build path: enc_payload — authenticated DFP1 AES-CBC + HMAC
Expand Down Expand Up @@ -39,6 +39,7 @@ jobs:

topmost:
uses: ./.github/workflows/third-party-RustDeskTempTopMostWindow.yml
needs: bridge
with:
upload-artifact: true
target: windows-2022
Expand Down Expand Up @@ -700,9 +701,6 @@ jobs:
set -euo pipefail
MANIFEST_PUBLICATION_TIMESTAMP=$(date -u '+%Y-%m-%dT%H:%M:%SZ')
export MANIFEST_PUBLICATION_TIMESTAMP
if [ -f flutter/build/windows/x64/runner/Release/custom_.txt ]; then
cp -- flutter/build/windows/x64/runner/Release/custom_.txt output/custom_.txt
fi
test -f "${MANIFEST_HELPER_PATH:-}" || { echo "::error::preserved manifest helper is unavailable"; exit 1; }
python3 "$MANIFEST_HELPER_PATH" \
--platform "$MANIFEST_PLATFORM" --app-name "$RQS_APP_NAME" --version "$RQS_VERSION" \
Expand Down
71 changes: 71 additions & 0 deletions .github/workflows/update-webpki-roots.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Update webpki-roots

# Weekly refresh of the compiled-in TLS root certificates (the webpki-roots
# crate, a snapshot of the Mozilla root store). Roots are otherwise frozen at
# whatever Cargo.lock pins, so old builds miss newly added CAs and keep
# removed (distrusted) ones. Changes go through a PR on purpose: added or
# removed roots should be reviewed, not silently baked into releases.
#
# Note: PRs created with the default GITHUB_TOKEN do not trigger other
# workflows (GitHub limitation). Close and reopen the PR, or push to its
# branch, to run CI on it.

on:
schedule:
- cron: "0 3 * * 1"
workflow_dispatch:

# A manual dispatch overlapping the weekly run would race it force-pushing
# the same branch; queue instead of overlapping, and never cancel a run
# that may have already pushed.
concurrency:
group: update-webpki-roots
cancel-in-progress: false

jobs:
update:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
env:
BRANCH: auto-update-webpki-roots
steps:
- name: Checkout source code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4

- name: Update webpki-roots in all lockfiles
id: update
run: |
set -e
git ls-files -z '*Cargo.lock' | while IFS= read -r -d '' lock; do
dir=$(dirname "$lock")
for v in $(sed -n '/name = "webpki-roots"/{n;s/.*version = "\(.*\)"/\1/p;}' "$lock" | sort -u); do
echo "updating webpki-roots@$v in $dir"
(cd "$dir" && cargo update -p "webpki-roots@$v")
done
done
if git diff --quiet -- '*Cargo.lock'; then
echo "changed=0" >> "$GITHUB_OUTPUT"
else
echo "changed=1" >> "$GITHUB_OUTPUT"
git --no-pager diff -- '*Cargo.lock'
fi

- name: Create pull request
if: steps.update.outputs.changed == '1'
env:
GH_TOKEN: ${{ github.token }}
run: |
set -e
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git checkout -B "$BRANCH"
git add -- '*Cargo.lock'
git commit -m "chore: update webpki-roots to latest Mozilla root store"
git push -f origin "$BRANCH"
if [ -z "$(gh pr list --head "$BRANCH" --state open --json number --jq '.[].number')" ]; then
gh pr create \
--title "chore: update webpki-roots to latest Mozilla root store" \
--body "Automated weekly refresh of the compiled-in TLS root certificates (webpki-roots). Please review the added/removed roots. CI does not run automatically on PRs created by GITHUB_TOKEN; close and reopen this PR to trigger it."
fi
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,6 @@ examples/**/target/
vcpkg_installed
flutter/lib/generated_plugin_registrant.dart
libsciter.dylib
flutter/web/
flutter/web/
# libdrmtap is cloned at build time by build.py (not a submodule)
/third_party/libdrmtap/
19 changes: 19 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,19 @@
* Do not make formatting-only changes.
* Keep naming/style consistent with nearby code.

### Comments

* Keep them short: one line by default, three at most.
* Say **why**, never what. If the code already says it, delete the comment.
* A comment must never be longer than the code it describes.
* Applies to YAML, shell and Python too, not just Rust.

### Be minimally invasive

* Prefer purely additive changes: layer new (`#[cfg]`-gated) blocks or new functions around existing code instead of restructuring it. The ideal diff for a fix adds lines and modifies/deletes none.
* Do not extract or reshape existing code just to enable your new code; look for a mechanism that leaves existing lines untouched (e.g. hide/show an existing object instead of refactoring its construction into a helper for rebuilding).
* Put new logic in self-contained functions in the module it belongs to (platform-specific logic in `src/platform/`, with `use` inside the function body to avoid churning shared import blocks). Call sites in shared files (`src/tray.rs`, `src/core_main.rs`, `src/server/connection.rs`, …) should be thin one-line hooks.

## Localization (`src/lang/*.rs`)

Each file is a `HashMap<key, translation>`. Layout:
Expand All @@ -84,3 +97,9 @@ Then translate that source into the file's target language (infer the language f
* Preserve placeholders (`{}`) and escape sequences (`\n`, `\"`) exactly as in the source.
* Do not translate brand or technical tokens: `RustDesk`, `Socks5`, `TLS`, `UAC`, `Wayland`, `X11`, `TCP`, `UDP`, `2FA`, `RDP`, `D3D`, etc.
* Copy URL values (e.g. `doc_*` keys) verbatim from `en.rs`.

### Adding new keys (feature work)

* New English-text keys use sentence case, not Title Case: `Use ID whitelisting`, **not** `Use ID Whitelisting`. Acronyms (ID, IP, 2FA…) stay uppercase. Legacy Title-Case keys (e.g. `Use IP Whitelisting`) stay as-is — do not rename them.
* Since the key itself is the English display text, a sentence-case key usually needs **no** `en.rs` entry; add one only when the display text must differ from the key (e.g. `*_tip` keys).
* Append each new key to `template.rs` (with `""`) and to every `src/lang/*.rs` file (translated, or `""` if unsure), at the end of the list.
Loading