From b314f6d89dcfd262cf8d13eb46695e93bbf19f71 Mon Sep 17 00:00:00 2001
From: rustdesk
Date: Tue, 14 Jun 2022 18:13:57 +0800
Subject: [PATCH 01/24] change fastlane desc
---
.../metadata/android/en-US/full_description.txt | 12 +++++++++++-
.../metadata/android/en-US/short_description.txt | 2 +-
.../metadata/android/zh-CN/full_description.txt | 15 ++++++++++++---
.../metadata/android/zh-CN/short_description.txt | 2 +-
4 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt
index e32132ee7..966ad3df8 100644
--- a/fastlane/metadata/android/en-US/full_description.txt
+++ b/fastlane/metadata/android/en-US/full_description.txt
@@ -1 +1,11 @@
-Yet another remote desktop software, written in Rust. Works out of the box, no configuration required. You have full control of your data, with no concerns about security. You can use our rendezvous/relay server, set up your own, or write your own rendezvous/relay server.
\ No newline at end of file
+An open-source remote desktop application, the open source TeamViewer alternative.
+Source code: https://github.com/rustdesk/rustdesk
+Doc: https://rustdesk.com/docs/en/manual/mobile/
+
+In order for a remote device to control your Android device via mouse or touch, you need to allow RustDesk to use the "Accessibility" service, RustDesk uses AccessibilityService API to implement Addroid remote control.
+
+In addtion to remote control, you can also transfer files between Android devices and PCs easily with RustDesk.
+
+You have full control of your data, with no concerns about security. You can use our rendezvous/relay server, or self-hosting, or write your own rendezvous/relay server. Self-hosting server is free and open source: https://github.com/rustdesk/rustdesk-server
+
+Please download and install desktop version from: https://rustdesk.com, then you can access and control your desktop from your mobile, or control your mobile from desktop.
diff --git a/fastlane/metadata/android/en-US/short_description.txt b/fastlane/metadata/android/en-US/short_description.txt
index b88c8e1d7..357fb37ab 100644
--- a/fastlane/metadata/android/en-US/short_description.txt
+++ b/fastlane/metadata/android/en-US/short_description.txt
@@ -1 +1 @@
-Yet another remote desktop software
\ No newline at end of file
+An open-source remote desktop application, the open source TeamViewer alternative.
diff --git a/fastlane/metadata/android/zh-CN/full_description.txt b/fastlane/metadata/android/zh-CN/full_description.txt
index 51fad180b..f1f44057e 100644
--- a/fastlane/metadata/android/zh-CN/full_description.txt
+++ b/fastlane/metadata/android/zh-CN/full_description.txt
@@ -1,3 +1,12 @@
-远程桌面软件,开箱即用,无需任何配置。您完全掌控数据,不用担心安全问题。您可以使用我们的注册/中继服务器,
-或者自己设置,
-亦或者开发您的版本。
\ No newline at end of file
+开源远程桌面应用,开源 TeamViewer 替代方案。
+源代码:https://github.com/rustdesk/rustdesk
+文档:https://rustdesk.com/docs/en/manual/mobile/
+
+为了让远程设备通过鼠标或触摸控制您的 Android 设备,您需要允许 RustDesk 使用“Accessibility”服务,RustDesk 使用 AccessibilityService API 来实现 Addroid 远程控制。
+
+除了远程控制,您还可以使用 RustDesk 在 Android 设备和 PC 之间轻松传输文件。
+
+您完全掌控数据,不用担心安全问题。您可以使用我们的注册/中继服务器,或者自建,亦或者开发您的版本。
+自托管服务器是免费和开源的:https://github.com/rustdesk/rustdesk-server
+
+请从:https://rustdesk.com 下载并安装桌面版,然后您可以通过手机访问和控制您的桌面,或从桌面控制您的手机。
diff --git a/fastlane/metadata/android/zh-CN/short_description.txt b/fastlane/metadata/android/zh-CN/short_description.txt
index ac41efbee..69a4a5b52 100644
--- a/fastlane/metadata/android/zh-CN/short_description.txt
+++ b/fastlane/metadata/android/zh-CN/short_description.txt
@@ -1 +1 @@
-远程桌面软件
\ No newline at end of file
+开源远程桌面应用,开源 TeamViewer 替代方案
From 709e4a04ceb367a608a7745e106e86369e0ed08e Mon Sep 17 00:00:00 2001
From: csf
Date: Tue, 14 Jun 2022 21:43:17 +0800
Subject: [PATCH 02/24] update arm32 in build_android_deps.sh
---
flutter/build_android_deps.sh | 157 ++++++++++++++++++++++------------
1 file changed, 100 insertions(+), 57 deletions(-)
diff --git a/flutter/build_android_deps.sh b/flutter/build_android_deps.sh
index 566196d52..ca6792916 100755
--- a/flutter/build_android_deps.sh
+++ b/flutter/build_android_deps.sh
@@ -4,7 +4,7 @@
# Required:
# 1. set VCPKG_ROOT / ANDROID_NDK path environment variables
# 2. vcpkg initialized
-# 3. ndk >= 22 (if ndk< 22 you need to change LD as `export LD=$TOOLCHAIN/bin/aarch64-linux-android-ld`)
+# 3. ndk, version: 22 (if ndk < 22 you need to change LD as `export LD=$TOOLCHAIN/bin/$NDK_LLVM_TARGET-ld`)
if [ -z "$ANDROID_NDK" ]; then
echo "Failed! Please set ANDROID_NDK"
@@ -16,66 +16,109 @@ if [ -z "$VCPKG_ROOT" ]; then
exit 1
fi
-PREFIX=$VCPKG_ROOT/installed/arm64-android/
+API_LEVEL="21"
-echo "*** [Start] Build opus / libyuv from vcpkg"
-export ANDROID_NDK_HOME=$ANDROID_NDK
-pushd $VCPKG_ROOT
-$VCPKG_ROOT/vcpkg install opus --triplet arm64-android
-$VCPKG_ROOT/vcpkg install libyuv --triplet arm64-android
-popd
-echo "*** [Finished] Build opus / libyuv from vcpkg"
+# NDK llvm toolchain
+HOST_TAG="linux-x86_64" # current platform, set as `ls $ANDROID_NDK/toolchains/llvm/prebuilt/`
+TOOLCHAIN=$ANDROID_NDK/toolchains/llvm/prebuilt/$HOST_TAG
+
+function build {
+ ANDROID_ABI=$1
+ VCPKG_TARGET=$2
+ NDK_LLVM_TARGET=$3
+ LIBVPX_TARGET=$4
+
+ PREFIX=$VCPKG_ROOT/installed/$VCPKG_TARGET/
+
+ # 1
+ echo "*** [$ANDROID_ABI][Start] Build opus / libyuv from vcpkg"
+ export ANDROID_NDK_HOME=$ANDROID_NDK
+ pushd $VCPKG_ROOT
+ $VCPKG_ROOT/vcpkg install opus --triplet $VCPKG_TARGET
+ $VCPKG_ROOT/vcpkg install libyuv --triplet $VCPKG_TARGET
+ popd
+ echo "*** [$ANDROID_ABI][Finished] Build opus / libyuv from vcpkg"
+
+ # 2
+ echo "*** [$ANDROID_ABI][Start] Build libvpx"
+ pushd build/libvpx
+ export AR=$TOOLCHAIN/bin/${NDK_LLVM_TARGET}-ar
+ export AS=$TOOLCHAIN/bin/${NDK_LLVM_TARGET}-as
+ export LD=$TOOLCHAIN/bin/${NDK_LLVM_TARGET}-ld.gold # if ndk < 22, use aarch64-linux-android-ld
+ export RANLIB=$TOOLCHAIN/bin/${NDK_LLVM_TARGET}-ranlib
+ export STRIP=$TOOLCHAIN/bin/${NDK_LLVM_TARGET}-strip
+
+ if [ $NDK_LLVM_TARGET == "arm-linux-androideabi" ]
+ then
+ export CC=$TOOLCHAIN/bin/armv7a-linux-androideabi${API_LEVEL}-clang
+ export CXX=$TOOLCHAIN/bin/armv7a-linux-androideabi${API_LEVEL}-clang++
+ else
+ export CC=$TOOLCHAIN/bin/${NDK_LLVM_TARGET}${API_LEVEL}-clang
+ export CXX=$TOOLCHAIN/bin/${NDK_LLVM_TARGET}${API_LEVEL}-clang++
+ fi
+
+ ./configure --target=$LIBVPX_TARGET \
+ --enable-pic --disable-vp8 \
+ --disable-webm-io \
+ --disable-unit-tests \
+ --disable-examples \
+ --disable-libyuv \
+ --disable-postproc \
+ --disable-vp8 \
+ --disable-tools \
+ --disable-docs \
+ --prefix=$PREFIX
+ make -j5
+ make install
+
+ popd
+ echo "*** [$ANDROID_ABI][Finished] Build libvpx"
+
+ # 3
+ echo "*** [$ANDROID_ABI][Start] Build oboe"
+ pushd build/oboe
+ cmake -DBUILD_SHARED_LIBS=true \
+ -DCMAKE_BUILD_TYPE=RelWithDebInfo \
+ -DANDROID_TOOLCHAIN=clang \
+ -DANDROID_STL=c++_shared \
+ -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
+ -DCMAKE_INSTALL_PREFIX=$PREFIX \
+ -DANDROID_ABI=$ANDROID_ABI \
+ -DANDROID_PLATFORM=android-$API_LEVEL
+ make -j5
+ make install
+ mv $PREFIX/lib/$ANDROID_ABI/liboboe.a $PREFIX/lib/
+ popd
+ echo "*** [$ANDROID_ABI][Finished] Build oboe"
+
+ echo "*** [$ANDROID_ABI][All Finished]"
+}
-echo "*** [Start] Build libvpx"
git clone -b v1.11.0 --depth=1 https://github.com/webmproject/libvpx.git build/libvpx
-pushd build/libvpx
-export NDK=$ANDROID_NDK
-export HOST_TAG=linux-x86_64
-export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/$HOST_TAG
-export AR=$TOOLCHAIN/bin/aarch64-linux-android-ar
-export AS=$TOOLCHAIN/bin/aarch64-linux-android-as
-export CC=$TOOLCHAIN/bin/aarch64-linux-android21-clang
-export CXX=$TOOLCHAIN/bin/aarch64-linux-android21-clang++
-export LD=$TOOLCHAIN/bin/aarch64-linux-android-ld.gold # if ndk < 22, use aarch64-linux-android-ld
-export RANLIB=$TOOLCHAIN/bin/aarch64-linux-android-ranlib
-export STRIP=$TOOLCHAIN/bin/aarch64-linux-android-strip
-
-./configure --target=arm64-android-gcc \
- --enable-pic --disable-vp8 \
- --disable-webm-io \
- --disable-unit-tests \
- --disable-examples \
- --disable-libyuv \
- --disable-postproc \
- --disable-vp8 \
- --disable-tools \
- --disable-docs \
- --prefix=$PREFIX
-make -j5
-make install
-
-popd
-echo "*** [Finished] Build libvpx"
-
-
-echo "*** [Start] Build oboe"
git clone -b 1.6.1 --depth=1 https://github.com/google/oboe build/oboe
-patch -d build/oboe -p1 < ../src/oboe.patch
-pushd build/oboe
-cmake -DBUILD_SHARED_LIBS=true \
- -DCMAKE_BUILD_TYPE=RelWithDebInfo \
- -DANDROID_TOOLCHAIN=clang \
- -DANDROID_STL=c++_shared \
- -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
- -DCMAKE_INSTALL_PREFIX=$PREFIX \
- -DANDROID_ABI=arm64-v8a \
- -DANDROID_PLATFORM=android-21
-make -j5
-make install
-mv $PREFIX/lib/arm64-v8a/liboboe.a $PREFIX/lib/
-popd
-echo "*** [Finished] Build oboe"
-echo "*** [All Finished]"
+patch -N -d build/oboe -p1 < ../src/oboe.patch
+
+# VCPKG_TARGET ANDROID_ABI
+# arm64-android arm64-v8a
+# arm-android armeabi-v7a
+# x64-android x86_64
+# x86-android x86
+
+# NDK_LLVM_TARGET
+# aarch64-linux-android
+# arm-linux-androideabi
+# x86_64-linux-android
+# i686-linux-android
+
+# LIBVPX_TARGET :
+# arm64-android-gcc
+# armv7-android-gcc
+# x86_64-android-gcc
+# x86-android-gcc
+
+# args: ANDROID_ABI VCPKG_TARGET NDK_LLVM_TARGET LIBVPX_TARGET
+build arm64-v8a arm64-android aarch64-linux-android arm64-android-gcc
+build armeabi-v7a arm-android arm-linux-androideabi armv7-android-gcc
# rm -rf build/libvpx
# rm -rf build/oboe
\ No newline at end of file
From ef93d4584a9db36c5edbf9f4b783f96abe16dfa7 Mon Sep 17 00:00:00 2001
From: csf
Date: Wed, 15 Jun 2022 16:18:49 +0800
Subject: [PATCH 03/24] fix build_android_deps
---
flutter/build_android_deps.sh | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/flutter/build_android_deps.sh b/flutter/build_android_deps.sh
index ca6792916..f120346cf 100755
--- a/flutter/build_android_deps.sh
+++ b/flutter/build_android_deps.sh
@@ -56,7 +56,7 @@ function build {
export CC=$TOOLCHAIN/bin/${NDK_LLVM_TARGET}${API_LEVEL}-clang
export CXX=$TOOLCHAIN/bin/${NDK_LLVM_TARGET}${API_LEVEL}-clang++
fi
-
+ make clean
./configure --target=$LIBVPX_TARGET \
--enable-pic --disable-vp8 \
--disable-webm-io \
@@ -77,6 +77,7 @@ function build {
# 3
echo "*** [$ANDROID_ABI][Start] Build oboe"
pushd build/oboe
+ make clean
cmake -DBUILD_SHARED_LIBS=true \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DANDROID_TOOLCHAIN=clang \
From 47d8b2b03d3a447e66b9100a1e8b860f7ddb7b24 Mon Sep 17 00:00:00 2001
From: Vedant <83997633+vedantmgoyal2009@users.noreply.github.com>
Date: Wed, 15 Jun 2022 18:35:36 +0530
Subject: [PATCH 04/24] Create winget.yml
---
.github/workflows/winget.yml | 12 ++++++++++++
1 file changed, 12 insertions(+)
create mode 100644 .github/workflows/winget.yml
diff --git a/.github/workflows/winget.yml b/.github/workflows/winget.yml
new file mode 100644
index 000000000..9b35b3a7e
--- /dev/null
+++ b/.github/workflows/winget.yml
@@ -0,0 +1,12 @@
+name: Publish to WinGet
+on:
+ release:
+ types: [released]
+jobs:
+ publish:
+ runs-on: windows-latest # action can only be run on windows
+ steps:
+ - uses: vedantmgoyal2009/vedantmgoyal2009/winget-pkgs-automation/releaser-action@v1.0.0
+ with:
+ identifier: RustDesk.RustDesk
+ token: ${{ secrets.WINGET_TOKEN }}
From de4389977b20e6d9b0d2a934943f4d17fe7b16c7 Mon Sep 17 00:00:00 2001
From: csf
Date: Wed, 15 Jun 2022 21:29:56 +0800
Subject: [PATCH 05/24] https://github.com/rustdesk/rustdesk/issues/775
---
src/mobile.rs | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/mobile.rs b/src/mobile.rs
index fe02513a0..5b9651e54 100644
--- a/src/mobile.rs
+++ b/src/mobile.rs
@@ -436,7 +436,12 @@ impl Interface for Session {
let mut displays = Vec::new();
let mut current = pi.current_display as usize;
- if !lc.is_file_transfer {
+ if lc.is_file_transfer {
+ if pi.username.is_empty() {
+ self.msgbox("error", "Error", "No active console user logged on, please connect and logon first.");
+ return;
+ }
+ } else {
if pi.displays.is_empty() {
self.msgbox("error", "Remote Error", "No Display");
}
From 3239ef525c2ef1fdd1bbfc12581ad715d66398dc Mon Sep 17 00:00:00 2001
From: Vedant <83997633+vedantmgoyal2009@users.noreply.github.com>
Date: Sat, 18 Jun 2022 23:55:31 +0530
Subject: [PATCH 06/24] Update winget.yml
---
.github/workflows/winget.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/winget.yml b/.github/workflows/winget.yml
index 9b35b3a7e..82243264c 100644
--- a/.github/workflows/winget.yml
+++ b/.github/workflows/winget.yml
@@ -6,7 +6,7 @@ jobs:
publish:
runs-on: windows-latest # action can only be run on windows
steps:
- - uses: vedantmgoyal2009/vedantmgoyal2009/winget-pkgs-automation/releaser-action@v1.0.0
+ - uses: vedantmgoyal2009/winget-releaser@latest
with:
identifier: RustDesk.RustDesk
token: ${{ secrets.WINGET_TOKEN }}
From bca5fe85117f38de0da4446e63f5823e00a044b7 Mon Sep 17 00:00:00 2001
From: Hamidi Mohammed
Date: Sat, 18 Jun 2022 20:23:01 +0100
Subject: [PATCH 07/24] Add README-AR.md
Signed-off-by: Hamidi Mohammed
---
README-CS.md | 2 +-
README-DE.md | 2 +-
README-EO.md | 2 +-
README-ES.md | 2 +-
README-FA.md | 2 +-
README-FI.md | 2 +-
README-FR.md | 2 +-
README-ID.md | 2 +-
README-IT.md | 2 +-
README-JP.md | 2 +-
README-KR.md | 2 +-
README-ML.md | 2 +-
README-NL.md | 2 +-
README-PL.md | 2 +-
README-PTBR.md | 2 +-
README-RU.md | 2 +-
README-ZH.md | 2 +-
README.md | 2 +-
18 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/README-CS.md b/README-CS.md
index 2606e2def..1dd5463a1 100644
--- a/README-CS.md
+++ b/README-CS.md
@@ -5,7 +5,7 @@
Docker •
Struktura •
Ukázky
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어]
+ [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
Potřebujeme Vaši pomoc s překláním textů tohoto ČTIMNE, uživatelského rozhraní aplikace RustDesk a dokumentace k ní do vašeho jazyka
diff --git a/README-DE.md b/README-DE.md
index 217fbc76a..3f770d226 100644
--- a/README-DE.md
+++ b/README-DE.md
@@ -5,7 +5,7 @@
Docker •
Dateistruktur •
Screenshots
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어]
+ [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
Wir brauchen deine Hilfe um diese README Datei zu verbessern und aktualisieren
diff --git a/README-EO.md b/README-EO.md
index 224caa064..21a4f9521 100644
--- a/README-EO.md
+++ b/README-EO.md
@@ -5,7 +5,7 @@
Docker •
Strukturo •
Ekrankopio
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어]
+ [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
Ni bezonas helpon traduki tiun README kaj la interfacon al via denaska lingvo
diff --git a/README-ES.md b/README-ES.md
index 19a0484ef..1c0b5dd7b 100644
--- a/README-ES.md
+++ b/README-ES.md
@@ -5,7 +5,7 @@
Docker •
Estructura •
Captura de pantalla
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어]
+ [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
Necesitamos tu ayuda para traducir este README a tu idioma
diff --git a/README-FA.md b/README-FA.md
index 33b9f29bd..0f7ca1a95 100644
--- a/README-FA.md
+++ b/README-FA.md
@@ -5,7 +5,7 @@
داکر •
ساخت •
سرور
- [česky] | [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어]
+ [česky] | [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
برای ترجمه این RustDesk UI ،README و Doc به زبان مادری شما به کمکتون نیاز داریم
diff --git a/README-FI.md b/README-FI.md
index ea923170e..a2d7534e0 100644
--- a/README-FI.md
+++ b/README-FI.md
@@ -5,7 +5,7 @@
Docker •
Rakenne •
Tilannevedos
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어]
+ [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
Tarvitsemme apua tämän README-tiedoston kääntämiseksi äidinkielellesi
diff --git a/README-FR.md b/README-FR.md
index 9dbeaecf2..b1f8e3670 100644
--- a/README-FR.md
+++ b/README-FR.md
@@ -5,7 +5,7 @@
Docker -
Structure -
Images
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어]
+ [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
Nous avons besoin de votre aide pour traduire ce README dans votre langue maternelle.
diff --git a/README-ID.md b/README-ID.md
index 31400a945..624336f45 100644
--- a/README-ID.md
+++ b/README-ID.md
@@ -5,7 +5,7 @@
Docker •
Structure •
Snapshot
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어]
+ [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
Kami membutuhkan bantuan Anda untuk menerjemahkan README ini dan RustDesk UI ke bahasa asli anda
diff --git a/README-IT.md b/README-IT.md
index 6a0df6ac6..7eba7860a 100644
--- a/README-IT.md
+++ b/README-IT.md
@@ -5,7 +5,7 @@
Docker •
Struttura •
Screenshots
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어]
+ [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
Abbiamo bisogno del tuo aiuto per tradurre questo README e la RustDesk UI nella tua lingua nativa
diff --git a/README-JP.md b/README-JP.md
index a7858b332..60816a5d5 100644
--- a/README-JP.md
+++ b/README-JP.md
@@ -5,7 +5,7 @@
Docker •
Structure •
Snapshot
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어]
+ [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
このREADMEをあなたの母国語に翻訳するために、あなたの助けが必要です。
diff --git a/README-KR.md b/README-KR.md
index 9652e978a..750cf91bd 100644
--- a/README-KR.md
+++ b/README-KR.md
@@ -5,7 +5,7 @@
Docker •
Structure •
Snapshot
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어]
+ [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
README를 모국어로 번역하기 위한 당신의 도움의 필요합니다.
diff --git a/README-ML.md b/README-ML.md
index 69e3269cd..c479d0496 100644
--- a/README-ML.md
+++ b/README-ML.md
@@ -5,7 +5,7 @@
Docker •
Structure •
Snapshot
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어]
+ [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
ഈ README നിങ്ങളുടെ മാതൃഭാഷയിലേക്ക് വിവർത്തനം ചെയ്യാൻ ഞങ്ങൾക്ക് നിങ്ങളുടെ സഹായം ആവശ്യമാണ്
diff --git a/README-NL.md b/README-NL.md
index 0b355a273..2d87504db 100644
--- a/README-NL.md
+++ b/README-NL.md
@@ -5,7 +5,7 @@
Docker •
Structuur •
Snapshot
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어]
+ [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
We hebben je hulp nodig om deze README te vertalen naar jouw moedertaal
diff --git a/README-PL.md b/README-PL.md
index 2922eae0d..162ca7648 100644
--- a/README-PL.md
+++ b/README-PL.md
@@ -5,7 +5,7 @@
Docker •
Struktura •
Snapshot
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어]
+ [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
Potrzebujemy twojej pomocy w tłumaczeniu README na twój ojczysty język
diff --git a/README-PTBR.md b/README-PTBR.md
index 7eff79566..76b360283 100644
--- a/README-PTBR.md
+++ b/README-PTBR.md
@@ -5,7 +5,7 @@
Docker •
Estrutura •
Screenshots
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어]
+ [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
Precisamos de sua ajuda para traduzir este README e a UI do RustDesk para sua língua nativa
diff --git a/README-RU.md b/README-RU.md
index ffc1256d4..54c161cf0 100644
--- a/README-RU.md
+++ b/README-RU.md
@@ -5,7 +5,7 @@
Docker •
Structure •
Snapshot
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어]
+ [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
Нам нужна ваша помощь для перевода этого README и RustDesk UI на ваш родной язык
diff --git a/README-ZH.md b/README-ZH.md
index 00176a1c4..8d4203b16 100644
--- a/README-ZH.md
+++ b/README-ZH.md
@@ -5,7 +5,7 @@
Docker •
结构 •
截图
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어]
+ [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
Chat with us: [知乎](https://www.zhihu.com/people/rustdesk) | [Discord](https://discord.gg/nDceKgxnkV) | [Reddit](https://www.reddit.com/r/rustdesk)
diff --git a/README.md b/README.md
index a9ddc6071..613e425e2 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
Docker •
Structure •
Snapshot
- [česky] | [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어]
+ [česky] | [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
We need your help to translate this README, RustDesk UI and Doc to your native language
From 0d01dccd791caf020fc1188165f10f68057f0a2f Mon Sep 17 00:00:00 2001
From: Hamidi Mohammed
Date: Sat, 18 Jun 2022 20:24:07 +0100
Subject: [PATCH 08/24] Add README-AR.md
Signed-off-by: Hamidi Mohammed
---
README-AR.md | 190 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 190 insertions(+)
create mode 100644 README-AR.md
diff --git a/README-AR.md b/README-AR.md
new file mode 100644
index 000000000..055a654d2
--- /dev/null
+++ b/README-AR.md
@@ -0,0 +1,190 @@
+
+ 
+ Servers •
+ Build •
+ Docker •
+ Structure •
+ Snapshot
+ [česky] | [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
+ لغتك الأم, Doc و RustDesk UI, README نحن بحاجة إلى مساعدتك لترجمة هذا
+
+
+[Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk) :تواصل معنا عبر
+
+[](https://ko-fi.com/I2I04VU09)
+
+.Rustبرنامج آخر لسطح المكتب عن بعد، مكتوب بـ
+يعمل خارج الصندوق، لا حاجة إلى إعدادات. لديك سيطرة كاملة على بياناتك، دون مخاوف بشأن الأمن. يمكنك استخدام خادم
+ الخاص بنا rendezvous/relay
+[جهز لنفسك واحدا](https://rustdesk.com/server), أو
+[خاص بك rendezvous/relay أكتب خادم](https://github.com/rustdesk/rustdesk-server-demo).
+
+
+
+لمساعدتك على ذلك [`CONTRIBUTING.md`](CONTRIBUTING.md) يرحب بمساهمة الجميع. اطلع على RustDesk.
+
+[**؟ RustDesk كيفية يعمل**](https://github.com/rustdesk/rustdesk/wiki/How-does-RustDesk-work%3F)
+
+[**BINARY تنزيل**](https://github.com/rustdesk/rustdesk/releases)
+
+## خوادم مفتوحة ومجانية
+
+فيما يلي الخوادم التي تستخدمها مجانًا، وقد تتغير طوال الوقت. إذا لم تكن قريبًا من أحد هؤلاء، فقد تكون شبكتك بطيئة.
+| الموقع | المورد | المواصفات |
+| --------- | ------------- | ------------------ |
+| Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM |
+| Singapore | Vultr | 1 VCPU / 1GB RAM |
+| Dallas | Vultr | 1 VCPU / 1GB RAM | |
+
+## التبعيات
+
+ لواجهة المستخدم الرسومية [sciter](https://sciter.com/) نسخة سطح المكتب تستخدم
+ بنفسك sciter dynamic library عليك تحميل
+
+[Windows](https://raw.githubusercontent.com/c-smile/sciter-sdk/master/bin.win/x64/sciter.dll) |
+[Linux](https://raw.githubusercontent.com/c-smile/sciter-sdk/master/bin.lnx/x64/libsciter-gtk.so) |
+[MacOS](https://raw.githubusercontent.com/c-smile/sciter-sdk/master/bin.osx/libsciter.dylib)
+
+ Sciter إلى Flutter سنقوم بترحيل نسخة سطح المكتب من .Flutter تستخدم إصدارات الهاتف المحمول.
+
+## خطوات البناء
+
+- C++ build env و Rust development env قم بإعداد
+
+- بطريقة صحيحة `VCPKG_ROOT` env variable وأعد [vcpkg](https://github.com/microsoft/vcpkg) ثبت
+
+ - Windows: `vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static`
+ - Linux/MacOS: `vcpkg install libvpx libyuv opus`
+
+- run `cargo run`
+
+## [البناء](https://rustdesk.com/docs/en/dev/build/)
+
+## Linux
+
+### Ubuntu 18 (Debian 10)
+
+```sh
+sudo apt install -y g++ gcc git curl wget nasm yasm libgtk-3-dev clang libxcb-randr0-dev libxdo-dev libxfixes-dev libxcb-shape0-dev libxcb-xfixes0-dev libasound2-dev libpulse-dev cmake
+```
+
+### Fedora 28 (CentOS 8)
+
+```sh
+sudo yum -y install gcc-c++ git curl wget nasm yasm gcc gtk3-devel clang libxcb-devel libxdo-devel libXfixes-devel pulseaudio-libs-devel cmake alsa-lib-devel
+```
+
+### Arch (Manjaro)
+
+```sh
+sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-config clang gtk3 xdotool libxcb libxfixes alsa-lib pulseaudio
+```
+
+### pynput package تثبيت
+
+```sh
+pip3 install pynput
+```
+
+### vcpkg تثبيت
+
+```sh
+git clone https://github.com/microsoft/vcpkg
+cd vcpkg
+git checkout 2021.12.01
+cd ..
+vcpkg/bootstrap-vcpkg.sh
+export VCPKG_ROOT=$HOME/vcpkg
+vcpkg/vcpkg install libvpx libyuv opus
+```
+
+### Fix libvpx (For Fedora)
+
+```sh
+cd vcpkg/buildtrees/libvpx/src
+cd *
+./configure
+sed -i 's/CFLAGS+=-I/CFLAGS+=-fPIC -I/g' Makefile
+sed -i 's/CXXFLAGS+=-I/CXXFLAGS+=-fPIC -I/g' Makefile
+make
+cp libvpx.a $HOME/vcpkg/installed/x64-linux/lib/
+cd
+```
+
+### البناء
+
+```sh
+curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
+source $HOME/.cargo/env
+git clone https://github.com/rustdesk/rustdesk
+cd rustdesk
+mkdir -p target/debug
+wget https://raw.githubusercontent.com/c-smile/sciter-sdk/master/bin.lnx/x64/libsciter-gtk.so
+mv libsciter-gtk.so target/debug
+VCPKG_ROOT=$HOME/vcpkg cargo run
+```
+
+### X11 (Xorg) إلى Wayland تغيير
+
+افتراضية GNOME session ك Xorg إتبع [هذه](https://docs.fedoraproject.org/en-US/quick-docs/configuring-xorg-as-default-gnome-session/) الخطوات لإعداد Wayland لا تدعم RustDesk
+
+## Docker طريقة البناء باستخدام
+
+ابدأ باستنساخ المستودع وبناء الكونتاينر:
+
+```sh
+git clone https://github.com/rustdesk/rustdesk
+cd rustdesk
+docker build -t "rustdesk-builder" .
+```
+
+ثم، في كل مرة تحتاج إلى بناء التطبيق، قم بتشغيل الأمر التالي:
+
+```sh
+docker run --rm -it -v $PWD:/home/user/rustdesk -v rustdesk-git-cache:/home/user/.cargo/git -v rustdesk-registry-cache:/home/user/.cargo/registry -e PUID="$(id -u)" -e PGID="$(id -g)" rustdesk-builder
+```
+
+لاحظ أن البناء الأول قد يستغرق وقتًا أطول قبل تخزين التبعيات، وسيكون البناء اللاحق أسرع. بالإضافة إلى ذلك، إذا كنت بحاجة إلى تحديد وسائط مختلفة لأمر البناء، فيمكنك القيام بذلك في نهاية الأمر بوضع
+``
+على سبيل المثال، إذا كنت ترغب في بناء إصدار محسن، فستقوم بتشغيل الأمر أعلاه متبوعًا بـ
+`--release`
+:سيكون الملف القابل للتنفيذ الناتج متاحًا في مجلد تارغت، ويمكن تشغيله باستخدام
+
+```sh
+target/debug/rustdesk
+```
+
+:أو في حال قمت ببناء إصدار محسن
+
+```sh
+target/release/rustdesk
+```
+
+RustDesk يرجى التأكد من أنك تنفذ هذه الأوامر من جذر مستودع
+وإلا فقد لا يتمكن التطبيق من العثور على الموارد المطلوبة. لاحظ أيضًا أن الأوامر الفرعية الأخرى مثل
+`install` أو `run`
+لا يتم دعمها حاليًا عبر هذه الطريقة لأنها ستقوم بتثبيت أو تشغيل البرنامج داخل الكونتاينر بدلاً من الهوست.
+
+## هيكل الملف
+
+- **[libs/hbb_common](https://github.com/rustdesk/rustdesk/tree/master/libs/hbb_common)**: وظائف لنقل الملفات، وبعض وظائف المرافق الأخرى tcp/udp، protobuf ترميز الفيديو، إعدادات
+
+- **[libs/scrap](https://github.com/rustdesk/rustdesk/tree/master/libs/scrap)**: التقاط الشاشة
+- **[libs/enigo](https://github.com/rustdesk/rustdesk/tree/master/libs/enigo)**: التحكم في لوحة المفاتيح/الماوس الخاصة بكل منصة
+- **[src/ui](https://github.com/rustdesk/rustdesk/tree/master/src/ui)**: واجهة المستخدم الرسومية
+- **[src/server](https://github.com/rustdesk/rustdesk/tree/master/src/server)**: خدمات الصوت/الحافظة/المدخلات/الفيديو، ووصلات الشبكة
+- **[src/client.rs](https://github.com/rustdesk/rustdesk/tree/master/src/client.rs)**: بدء اتصال متقارن
+- **[src/rendezvous_mediator.rs](https://github.com/rustdesk/rustdesk/tree/master/src/rendezvous_mediator.rs)**: أو المنقول عن بُعد (TCP hole punching) انتظر الاتصال المباشر [rustdesk-server](https://github.com/rustdesk/rustdesk-server) الإتصال ب
+- **[src/platform](https://github.com/rustdesk/rustdesk/tree/master/src/platform)**: رمز خاص بكل منصة
+- **[flutter](https://github.com/rustdesk/rustdesk/tree/master/flutter)**: رمز الهاتف المحمول
+- **[flutter/web/js](https://github.com/rustdesk/rustdesk/tree/master/flutter/web/js)**:Flutter لعميل الويب الخاص ب Javascript
+
+## لقطات
+
+
+
+
+
+
+
+
From 5a051ae3b6b9fdf2777d6a3568eff68f2fa1e5f8 Mon Sep 17 00:00:00 2001
From: Hamidi Mohammed
Date: Sun, 19 Jun 2022 17:15:37 +0100
Subject: [PATCH 09/24] code enhancement
Signed-off-by: Hamidi Mohammed
---
flutter/lib/common.dart | 4 ++--
flutter/lib/models/file_model.dart | 8 --------
flutter/lib/models/native_model.dart | 1 -
flutter/lib/models/web_model.dart | 2 ++
flutter/lib/pages/connection_page.dart | 4 ++--
flutter/lib/pages/remote_page.dart | 2 +-
flutter/lib/pages/settings_page.dart | 16 ++++++++--------
flutter/lib/widgets/gestures.dart | 7 ++-----
8 files changed, 17 insertions(+), 27 deletions(-)
diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart
index c6a70460d..d6be51986 100644
--- a/flutter/lib/common.dart
+++ b/flutter/lib/common.dart
@@ -233,7 +233,7 @@ class AccessibilityListener extends StatelessWidget {
}
},
onPointerUp: (evt) {
- if (evt.size == 1 && GestureBinding.instance != null) {
+ if (evt.size == 1) {
GestureBinding.instance.handlePointerEvent(PointerUpEvent(
pointer: evt.pointer + offset,
size: 0.1,
@@ -243,7 +243,7 @@ class AccessibilityListener extends StatelessWidget {
}
},
onPointerMove: (evt) {
- if (evt.size == 1 && GestureBinding.instance != null) {
+ if (evt.size == 1) {
GestureBinding.instance.handlePointerEvent(PointerMoveEvent(
pointer: evt.pointer + offset,
size: 0.1,
diff --git a/flutter/lib/models/file_model.dart b/flutter/lib/models/file_model.dart
index 49184cf5b..e4afc892f 100644
--- a/flutter/lib/models/file_model.dart
+++ b/flutter/lib/models/file_model.dart
@@ -593,15 +593,7 @@ class FileFetcher {
tryCompleteTask(String? msg, String? isLocalStr) {
if (msg == null || isLocalStr == null) return;
- late final isLocal;
late final tasks;
- if (isLocalStr == "true") {
- isLocal = true;
- } else if (isLocalStr == "false") {
- isLocal = false;
- } else {
- return;
- }
try {
final fd = FileDirectory.fromJson(jsonDecode(msg));
if (fd.id > 0) {
diff --git a/flutter/lib/models/native_model.dart b/flutter/lib/models/native_model.dart
index f6824dda8..a600e372e 100644
--- a/flutter/lib/models/native_model.dart
+++ b/flutter/lib/models/native_model.dart
@@ -21,7 +21,6 @@ typedef F2 = Pointer Function(Pointer, Pointer);
typedef F3 = void Function(Pointer, Pointer);
class PlatformFFI {
- static Pointer? _lastRgbaFrame;
static String _dir = '';
static String _homeDir = '';
static F2? _getByName;
diff --git a/flutter/lib/models/web_model.dart b/flutter/lib/models/web_model.dart
index d9668272a..3ec6c9b9f 100644
--- a/flutter/lib/models/web_model.dart
+++ b/flutter/lib/models/web_model.dart
@@ -1,3 +1,5 @@
+// ignore_for_file: avoid_web_libraries_in_flutter
+
import 'dart:convert';
import 'dart:typed_data';
import 'dart:js';
diff --git a/flutter/lib/pages/connection_page.dart b/flutter/lib/pages/connection_page.dart
index 2cfbaa63b..90f290136 100644
--- a/flutter/lib/pages/connection_page.dart
+++ b/flutter/lib/pages/connection_page.dart
@@ -100,8 +100,8 @@ class _ConnectionPageState extends State {
: InkWell(
onTap: () async {
final url = _updateUrl + '.apk';
- if (await canLaunch(url)) {
- await launch(url);
+ if (await canLaunchUrl(Uri.parse(url))) {
+ await launchUrl(Uri.parse(url));
}
},
child: Container(
diff --git a/flutter/lib/pages/remote_page.dart b/flutter/lib/pages/remote_page.dart
index 9feef9577..b93069203 100644
--- a/flutter/lib/pages/remote_page.dart
+++ b/flutter/lib/pages/remote_page.dart
@@ -126,7 +126,7 @@ class _RemotePageState extends State {
common < oldValue.length &&
common < newValue.length &&
newValue[common] == oldValue[common];
- ++common);
+ ++common) {}
for (i = 0; i < oldValue.length - common; ++i) {
FFI.inputKey('VK_BACK');
}
diff --git a/flutter/lib/pages/settings_page.dart b/flutter/lib/pages/settings_page.dart
index 90ff0d564..2c8b7fe9a 100644
--- a/flutter/lib/pages/settings_page.dart
+++ b/flutter/lib/pages/settings_page.dart
@@ -68,8 +68,8 @@ class _SettingsState extends State {
tiles: [
SettingsTile.navigation(
onPressed: (context) async {
- if (await canLaunch(url)) {
- await launch(url);
+ if (await canLaunchUrl(Uri.parse(url))) {
+ await launchUrl(Uri.parse(url));
}
},
title: Text(translate("Version: ") + version),
@@ -105,8 +105,8 @@ void showAbout() {
InkWell(
onTap: () async {
const url = 'https://rustdesk.com/';
- if (await canLaunch(url)) {
- await launch(url);
+ if (await canLaunchUrl(Uri.parse(url))) {
+ await launchUrl(Uri.parse(url));
}
},
child: Padding(
@@ -149,7 +149,7 @@ fetch('http://localhost:21114/api/login', {
'uuid': FFI.getByName('uuid')
};
try {
- final response = await http.post(Uri.parse('${url}/api/login'),
+ final response = await http.post(Uri.parse('$url/api/login'),
headers: {"Content-Type": "application/json"}, body: json.encode(body));
return parseResp(response.body);
} catch (e) {
@@ -186,7 +186,7 @@ void refreshCurrentUser() async {
'uuid': FFI.getByName('uuid')
};
try {
- final response = await http.post(Uri.parse('${url}/api/currentUser'),
+ final response = await http.post(Uri.parse('$url/api/currentUser'),
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer $token"
@@ -212,7 +212,7 @@ void logout() async {
'uuid': FFI.getByName('uuid')
};
try {
- await http.post(Uri.parse('${url}/api/logout'),
+ await http.post(Uri.parse('$url/api/logout'),
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer $token"
@@ -242,7 +242,7 @@ String getUrl() {
url = 'http://${tmp[0]}:$port';
}
} else {
- url = 'http://${url}:21114';
+ url = 'http://$url:21114';
}
}
}
diff --git a/flutter/lib/widgets/gestures.dart b/flutter/lib/widgets/gestures.dart
index d70fe05e6..960439678 100644
--- a/flutter/lib/widgets/gestures.dart
+++ b/flutter/lib/widgets/gestures.dart
@@ -594,10 +594,7 @@ class _TapTracker {
required this.entry,
required Duration doubleTapMinTime,
required this.gestureSettings,
- }) : assert(doubleTapMinTime != null),
- assert(event != null),
- assert(event.buttons != null),
- pointer = event.pointer,
+ }) : pointer = event.pointer,
_initialGlobalPosition = event.position,
initialButtons = event.buttons,
_doubleTapMinTimeCountdown =
@@ -643,7 +640,7 @@ class _TapTracker {
/// CountdownZoned tracks whether the specified duration has elapsed since
/// creation, honoring [Zone].
class _CountdownZoned {
- _CountdownZoned({required Duration duration}) : assert(duration != null) {
+ _CountdownZoned({required Duration duration}) {
Timer(duration, _onTimeout);
}
From 5a471e286d2378d9b23d2f33d1c3c6538901fe98 Mon Sep 17 00:00:00 2001
From: Daniel HybridNetworks
Date: Wed, 22 Jun 2022 20:26:03 -0300
Subject: [PATCH 10/24] Add Spanish translation
---
src/lang.rs | 2 +
src/lang/es.rs | 283 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 285 insertions(+)
create mode 100644 src/lang/es.rs
diff --git a/src/lang.rs b/src/lang.rs
index c6e522940..4b4998fc1 100644
--- a/src/lang.rs
+++ b/src/lang.rs
@@ -6,6 +6,7 @@ mod da;
mod sk;
mod de;
mod en;
+mod es;
mod eo;
mod fr;
mod id;
@@ -44,6 +45,7 @@ pub fn translate_locale(name: String, locale: &str) -> String {
"it" => it::T.deref(),
"tw" => tw::T.deref(),
"de" => de::T.deref(),
+ "es" => es::T.deref(),
"ru" => ru::T.deref(),
"eo" => eo::T.deref(),
"id" => id::T.deref(),
diff --git a/src/lang/es.rs b/src/lang/es.rs
new file mode 100644
index 000000000..ba4c671a8
--- /dev/null
+++ b/src/lang/es.rs
@@ -0,0 +1,283 @@
+lazy_static::lazy_static! {
+pub static ref T: std::collections::HashMap<&'static str, &'static str> =
+ [
+ ("Status", "Estado"),
+ ("Your Desktop", "Tu escritorio"),
+ ("desk_tip", "Puoi accedere al tuo desktop usando l'ID e la password riportati qui."),
+ ("Password", "Contraseña"),
+ ("Ready", "Listo"),
+ ("Established", "Establecido"),
+ ("connecting_status", "Conexión a la red RustDesk en progreso..."),
+ ("Enable Service", "Habilitar Servicio"),
+ ("Start Service", "Iniciar Servicio"),
+ ("Service is running", "Servicio se está ejecutando"),
+ ("Service is not running", "Servicio no se está ejecutando"),
+ ("not_ready_status", "No está listo. Comprueba tu conexión"),
+ ("Control Remote Desktop", "Controlar Escritorio Remoto"),
+ ("Transfer File", "Transferir archivo"),
+ ("Connect", "Conectar"),
+ ("Recent Sessions", "Sesiones recientes"),
+ ("Address Book", "Directorio"),
+ ("Confirmation", "Confirmación"),
+ ("TCP Tunneling", "Tunel TCP"),
+ ("Remove", "Remover"),
+ ("Refresh random password", "Actualizar contraseña aleatoria"),
+ ("Set your own password", "Establece tu propia contraseña"),
+ ("Enable Keyboard/Mouse", "Habilitar teclado/ratón"),
+ ("Enable Clipboard", "Habilitar portapapeles"),
+ ("Enable File Transfer", "Habilitar transferencia de archivos"),
+ ("Enable TCP Tunneling", "Habilitar tunel TCP"),
+ ("IP Whitelisting", "Lista blanca IP"),
+ ("ID/Relay Server", "Servidor de ID/Relay"),
+ ("Stop service", "Parar servicio"),
+ ("Change ID", "Cambiar identificación"),
+ ("Website", "Sitio web"),
+ ("About", "Sobre"),
+ ("Mute", "Silencio"),
+ ("Audio Input", "Entrada de audio"),
+ ("ID Server", "ID server"),
+ ("Relay Server", "Server relay"),
+ ("API Server", "Server API"),
+ ("invalid_http", "debe comenzar con http:// o https://"),
+ ("Invalid IP", "IP inválida"),
+ ("id_change_tip", "Solo puedes usar caracteres a-z, A-Z, 0-9 e _ (guion bajo). El primer carácter debe ser a-z o A-Z. La longitud debe estar entre 6 a 16 caracteres."),
+ ("Invalid format", "Formato inválido"),
+ ("server_not_support", "Aún no es compatible con el servidor"),
+ ("Not available", "Indisponible"),
+ ("Too frequent", "Demasiado frecuente"),
+ ("Cancel", "Cancelar"),
+ ("Skip", "Saltar"),
+ ("Close", "Cerrar"),
+ ("Retry", "Volver"),
+ ("OK", "OK"),
+ ("Password Required", "Se requiere contraseña"),
+ ("Please enter your password", "Por favor, introduzca su contraseña"),
+ ("Remember password", "Recordar contraseña"),
+ ("Wrong Password", "Contraseña incorrecta"),
+ ("Do you want to enter again?", "Quieres volver a entrar?"),
+ ("Connection Error", "Error de conexión"),
+ ("Error", "Error"),
+ ("Reset by the peer", "Restablecido por el par"),
+ ("Connecting...", "Conectando..."),
+ ("Connection in progress. Please wait.", "Conexión en curso. Espere por favor."),
+ ("Please try 1 minute later", "Intente 1 minuto más tarde"),
+ ("Login Error", "Error de inicio de sesión"),
+ ("Successful", "Exitoso"),
+ ("Connected, waiting for image...", "Conectado, esperando imagen..."),
+ ("Name", "Nombre"),
+ ("Type", "Tipo"),
+ ("Modified", "Modificado"),
+ ("Size", "Tamaño"),
+ ("Show Hidden Files", "Mostrar archivos ocultos"),
+ ("Receive", "Recibir"),
+ ("Send", "Enviar"),
+ ("Refresh File", "Actualizar archivo"),
+ ("Local", "Local"),
+ ("Remote", "Remoto"),
+ ("Remote Computer", "Computadora remota"),
+ ("Local Computer", "Computadora local"),
+ ("Confirm Delete", "Confirmar eliminación"),
+ ("Delete", "Borrar"),
+ ("Properties", "Propiedades"),
+ ("Multi Select", "Selección múltiple"),
+ ("Empty Directory", "Directorio vacío"),
+ ("Not an empty directory", "No es un directorio vacío"),
+ ("Are you sure you want to delete this file?", "Estás seguro de que quieres eliminar este archivo?"),
+ ("Are you sure you want to delete this empty directory?", "Está seguro de que desea eliminar este directorio vacío?"),
+ ("Are you sure you want to delete the file of this directory?", "Está seguro de que desea eliminar el archivo de este directorio?"),
+ ("Do this for all conflicts", "Haga esto para todos los conflictos"),
+ ("This is irreversible!", "Esto es irreversible!"),
+ ("Deleting", "Borrando"),
+ ("files", "archivos"),
+ ("Waiting", "Esperando"),
+ ("Finished", "Acabado"),
+ ("Speed", "Velocidad"),
+ ("Custom Image Quality", "Calidad de imagen personalizada"),
+ ("Privacy mode", "Modo privado"),
+ ("Block user input", "Bloquear entrada de usuario"),
+ ("Unblock user input", "Desbloquear entrada de usuario"),
+ ("Adjust Window", "Ajustar ventana"),
+ ("Original", "Original"),
+ ("Shrink", "Encogerse"),
+ ("Stretch", "Estirar"),
+ ("Good image quality", "Buena calidad de imagen"),
+ ("Balanced", "Equilibrado"),
+ ("Optimize reaction time", "Optimizar el tiempo de reacción"),
+ ("Custom", "Personalizado"),
+ ("Show remote cursor", "Mostrar cursor remoto"),
+ ("Disable clipboard", "Deshabilitar portapapeles"),
+ ("Lock after session end", "Bloquear después del final de la sesión"),
+ ("Insert", "Insertar"),
+ ("Insert Lock", "Insertar bloqueo"),
+ ("Refresh", "Actualizar"),
+ ("ID does not exist", "ID no existe"),
+ ("Failed to connect to rendezvous server", "No se pudo conectar al servidor de encuentro"),
+ ("Please try later", "Por favor intente mas tarde"),
+ ("Remote desktop is offline", "El escritorio remoto está fuera de línea"),
+ ("Key mismatch", "La clave no coincide"),
+ ("Timeout", "Timeout"),
+ ("Failed to connect to relay server", "No se pudo conectar al servidor de retransmisión"),
+ ("Failed to connect via rendezvous server", "No se pudo conectar a través del servidor de encuentro"),
+ ("Failed to connect via relay server", "No se pudo conectar a través del servidor de retransmisión"),
+ ("Failed to make direct connection to remote desktop", "No se pudo establecer la conexión directa con el escritorio remoto"),
+ ("Set Password", "Configurar la clave"),
+ ("OS Password", "Contraseña del sistema operativo"),
+ ("install_tip", "Debido al Control de cuentas de usuario, es posible que RustDesk no funcione correctamente como escritorio remoto. Para evitar este problema, haga clic en el botón de abajo para instalar RustDesk a nivel de sistema."),
+ ("Click to upgrade", "Clic para actualizar"),
+ ("Click to download", "Clic para descargar"),
+ ("Click to update", "Fare clic per aggiornare"),
+ ("Configure", "Configurar"),
+ ("config_acc", "Para controlar su escritorio desde el exterior, debe otorgar permiso a RustDesk de \"Accesibilidad\"."),
+ ("config_screen", "Para controlar su escritorio desde el exterior, debe otorgar permiso a RustDesk de \"Grabación de pantalla\"."),
+ ("Installing ...", "Instalando ..."),
+ ("Install", "Instalar"),
+ ("Installation", "Instalación"),
+ ("Installation Path", "Ruta de instalación"),
+ ("Create start menu shortcuts", "Crear accesos directos al menú de inicio"),
+ ("Create desktop icon", "Crear icono de escritorio"),
+ ("agreement_tip", "Al iniciar la instalación, acepta los términos del acuerdo de licencia."),
+ ("Accept and Install", "Aceptar e instalar"),
+ ("End-user license agreement", "Acuerdo de licencia de usuario final"),
+ ("Generating ...", "Generando ..."),
+ ("Your installation is lower version.", "Su instalación es una versión inferior."),
+ ("not_close_tcp_tip", "No cierre esta ventana mientras esté usando el túnel"),
+ ("Listening ...", "Escuchando ..."),
+ ("Remote Host", "Servidor remoto"),
+ ("Remote Port", "Puerto remoto"),
+ ("Action", "Acción"),
+ ("Add", "Agregar"),
+ ("Local Port", "Puerto local"),
+ ("setup_server_tip", "Para una conexión más rápida, configure su propio servidor"),
+ ("Too short, at least 6 characters.", "Demasiado corto, al menos 6 caracteres."),
+ ("The confirmation is not identical.", "La confirmación no es idéntica."),
+ ("Permissions", "Permisos"),
+ ("Accept", "Aceptar"),
+ ("Dismiss", "Cancelar"),
+ ("Disconnect", "Desconectar"),
+ ("Allow using keyboard and mouse", "Permitir el uso del teclado y el mouse"),
+ ("Allow using clipboard", "Permitir usar portapapeles"),
+ ("Allow hearing sound", "Permitir escuchar sonido"),
+ ("Allow file copy and paste", "Permitir copiar y pegar archivos"),
+ ("Connected", "Conectado"),
+ ("Direct and encrypted connection", "Conexión directa y encriptada"),
+ ("Relayed and encrypted connection", "Conexión retransmitida y cifrada"),
+ ("Direct and unencrypted connection", "Conexión directa y sin cifrar"),
+ ("Relayed and unencrypted connection", "Conexión retransmitida y sin cifrar"),
+ ("Enter Remote ID", "Ingrese el ID remoto"),
+ ("Enter your password", "Ingrese su contraseña"),
+ ("Logging in...", "Iniciando sesión..."),
+ ("Enable RDP session sharing", "Habilitar el uso compartido de sesiones RDP"),
+ ("Auto Login", "Ingreso automático"),
+ ("Enable Direct IP Access", "Habilitar acceso IP directo"),
+ ("Rename", "Renombrar"),
+ ("Space", "Espacio"),
+ ("Create Desktop Shortcut", "Crear acceso directo del escritorio"),
+ ("Change Path", "Cambiar ruta"),
+ ("Create Folder", "Crear carpeta"),
+ ("Please enter the folder name", "Por favor ingrese el nombre de la carpeta"),
+ ("Fix it", "Resolver"),
+ ("Warning", "Aviso"),
+ ("Login screen using Wayland is not supported", "La pantalla de inicio de sesión con Wayland no es compatible"),
+ ("Reboot required", "Reinicio requerido"),
+ ("Unsupported display server ", "Servidor de visualización no compatible"),
+ ("x11 expected", "x11 necesario"),
+ ("Port", "Puerto"),
+ ("Settings", "Ajustes"),
+ ("Username", " Nombre de usuario"),
+ ("Invalid port", "Puerto inválido"),
+ ("Closed manually by the peer", "Cerrado manualmente por el par"),
+ ("Enable remote configuration modification", "Habilitar modificación de configuración remota"),
+ ("Run without install", "Ejecutar sin instalar"),
+ ("Always connected via relay", "Siempre conectado a través de relay"),
+ ("Always connect via relay", "Conéctese siempre a través de relay"),
+ ("whitelist_tip", "Solo las direcciones IP autorizadas pueden conectarse a este escritorio"),
+ ("Login", "Iniciar sesión"),
+ ("Logout", "Salir"),
+ ("Tags", "Tags"),
+ ("Search ID", "Buscar ID"),
+ ("Current Wayland display server is not supported", "El servidor de visualización actual de Wayland no es compatible"),
+ ("whitelist_sep", "Separados por coma, punto y coma, espacio o nueva línea"),
+ ("Add ID", "Agregar ID"),
+ ("Add Tag", "Agregar tag"),
+ ("Unselect all tags", "Deseleccionar todos los tags"),
+ ("Network error", "Error de red"),
+ ("Username missed", "Olvidó su nombre de usuario"),
+ ("Password missed", "Olvidó su contraseña"),
+ ("Wrong credentials", "Credenciales incorrectas"),
+ ("Edit Tag", "Editar tag"),
+ ("Unremember Password", "Olvidaste tu contraseña"),
+ ("Favorites", "Favoritos"),
+ ("Add to Favorites", "Agregar a favoritos"),
+ ("Remove from Favorites", "Quitar de favoritos"),
+ ("Empty", "Vacío"),
+ ("Invalid folder name", "Nombre de carpeta no válido"),
+ ("Socks5 Proxy", "Proxy Socks5"),
+ ("Hostname", "Nombre de host"),
+ ("Discovered", "Descubierto"),
+ ("install_daemon_tip", "Para comenzar en el encendido, debe instalar el servicio del sistema."),
+ ("Remote ID", "ID remoto"),
+ ("Paste", "Pegar"),
+ ("Paste here?", "Pegar aqui?"),
+ ("Are you sure to close the connection?", "Estás seguro de cerrar la conexión?"),
+ ("Download new version", "Descargar nueva versión"),
+ ("Touch mode", "Modo táctil"),
+ ("Mouse mode", "Modo ratón"),
+ ("One-Finger Tap", "Toque con un dedo"),
+ ("Left Mouse", "Ratón izquierdo"),
+ ("One-Long Tap", "Un toque largo"),
+ ("Two-Finger Tap", "Toque con dos dedos"),
+ ("Right Mouse", "Botón derecho"),
+ ("One-Finger Move", "Movimiento con un dedo"),
+ ("Double Tap & Move", "Toca dos veces y mueve"),
+ ("Mouse Drag", "Arrastre de ratón"),
+ ("Three-Finger vertically", "Tres dedos verticalmente"),
+ ("Mouse Wheel", "Rueda de ratón"),
+ ("Two-Finger Move", "Movimiento con dos dedos"),
+ ("Canvas Move", "Movimiento de lienzo"),
+ ("Pinch to Zoom", "Pellizcar para ampliar"),
+ ("Canvas Zoom", "Ampliar lienzo"),
+ ("Reset canvas", "Restablecer lienzo"),
+ ("No permission of file transfer", "Sin permiso de transferencia de archivos"),
+ ("Note", "Nota"),
+ ("Connection", "Conexión"),
+ ("Share Screen", "Compartir pantalla"),
+ ("CLOSE", "CERRAR"),
+ ("OPEN", "ABRIR"),
+ ("Chat", "Chat"),
+ ("Total", "Total"),
+ ("items", "items"),
+ ("Selected", "Seleccionado"),
+ ("Screen Capture", "Captura de pantalla"),
+ ("Input Control", "Control de entrada"),
+ ("Audio Capture", "Captura de audio"),
+ ("File Connection", "Conexión de archivos"),
+ ("Screen Connection", "Conexión de pantalla"),
+ ("Do you accept?", "Aceptas?"),
+ ("Open System Setting", "Configuración del sistema abierto"),
+ ("How to get Android input permission?", "Cómo obtener el permiso de entrada de Android?"),
+ ("android_input_permission_tip1", "Para que un dispositivo remoto controle su dispositivo Android a través del mouse o toque, debe permitir que RustDesk use el servicio de \"Accesibilidad\"."),
+ ("android_input_permission_tip2", "Vaya a la página de configuración del sistema que se abrirá a continuación, busque y acceda a [Servicios instalados], active el servicio [RustDesk Input]."),
+ ("android_new_connection_tip", "Se recibió una nueva solicitud de control para el dispositivo actual."),
+ ("android_service_will_start_tip", "Habilitar la captura de pantalla iniciará automáticamente el servicio, lo que permitirá que otros dispositivos soliciten una conexión desde este dispositivo."),
+ ("android_stop_service_tip", "Cerrar el servicio cerrará automáticamente todas las conexiones establecidas."),
+ ("android_version_audio_tip", "La versión actual de Android no admite la captura de audio, actualice a Android 10 o posterior."),
+ ("android_start_service_tip", "Toque el permiso [Iniciar servicio] o ABRIR [Captura de pantalla] para iniciar el servicio de uso compartido de pantalla."),
+ ("Account", "Cuenta"),
+ ("Overwrite", "Sobrescribir"),
+ ("This file exists, skip or overwrite this file?", "Este archivo existe, ¿omitir o sobrescribir este archivo?"),
+ ("Quit", "Salir"),
+ ("doc_mac_permission", "https://rustdesk.com/docs/en/manual/mac/#enable-permissions"),
+ ("Help", "Ayuda"),
+ ("Failed", "Fallido"),
+ ("Succeeded", "Logrado"),
+ ("Someone turns on privacy mode, exit", "Alguien active el modo privacidad, salga"),
+ ("Unsupported", "No soportado"),
+ ("Peer denied", "Par negado"),
+ ("Please install plugins", "Instale complementos"),
+ ("Peer exit", "Par salio"),
+ ("Failed to turn off", "Error al apagar"),
+ ("Turned off", "Apagado"),
+ ("In privacy mode", "En modo de privacidad"),
+ ("Out privacy mode", "Fuera del modo de privacidad"),
+ ].iter().cloned().collect();
+}
From 047111fcc9bc0a4533de65fa9b916bc3b656463d Mon Sep 17 00:00:00 2001
From: Daniel HybridNetworks
Date: Wed, 22 Jun 2022 20:51:49 -0300
Subject: [PATCH 11/24] Update README-ES.md
---
README-ES.md | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/README-ES.md b/README-ES.md
index 1c0b5dd7b..ce8601fa0 100644
--- a/README-ES.md
+++ b/README-ES.md
@@ -5,11 +5,11 @@
Docker •
Estructura •
Captura de pantalla
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
+ [česky] | [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
Necesitamos tu ayuda para traducir este README a tu idioma
-Chat with us: [Discord](https://discord.gg/nDceKgxnkV) | [Reddit](https://www.reddit.com/r/rustdesk)
+Chatea con nosotros: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
[](https://ko-fi.com/I2I04VU09)
@@ -23,9 +23,11 @@ RustDesk agradece la contribución de todo el mundo. Ve [`CONTRIBUTING.md`](CONT
A continuación se muestran los servidores que está utilizando de forma gratuita, puede cambiar en algún momento. Si no estás cerca de uno de ellos, tu red puede ser lenta.
-- Seoul, AWS lightsail, 1 VCPU/0.5G RAM
-- Singapore, Vultr, 1 VCPU/1G RAM
-- Dallas, Vultr, 1 VCPU/1G RAM
+| Ubicación | Vendedor | Especificación |
+| --------- | ------------- | ------------------ |
+| Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM |
+| Singapore | Vultr | 1 VCPU / 1GB RAM |
+| Dallas | Vultr | 1 VCPU / 1GB RAM | |
## Dependencies
@@ -37,7 +39,7 @@ La versión Desktop usa [sciter](https://sciter.com/) para GUI, por favor bajate
## Pasos para compilar desde el inicio
-- Prepara el entono de desarrollode Rust y el entorno de compilación de C++ y Rust.
+- Prepara el entono de desarrollo de Rust y el entorno de compilación de C++ y Rust.
- Instala [vcpkg](https://github.com/microsoft/vcpkg), y configura la variable de entono `VCPKG_ROOT` correctamente.
@@ -78,7 +80,7 @@ export VCPKG_ROOT=$HOME/vcpkg
vcpkg/vcpkg install libvpx libyuv opus
```
-### Soluciona libvpx (For Fedora)
+### Soluciona libvpx (Para Fedora)
```sh
cd vcpkg/buildtrees/libvpx/src
@@ -124,7 +126,7 @@ Entonces, cada vez que necesites compilar una modificación, ejecuta el siguient
docker run --rm -it -v $PWD:/home/user/rustdesk -v rustdesk-git-cache:/home/user/.cargo/git -v rustdesk-registry-cache:/home/user/.cargo/registry -e PUID="$(id -u)" -e PGID="$(id -g)" rustdesk-builder
```
-Ten en cuenta que la primera compilación puede tardar más tiempo antes de que las dependencias se almacenen en la caché, las siguientes compilaciones serán más rápidas. Además, si necesitas especificar diferentes argumentos a la orden de compilación, puede hacerlo al final de la linea de comandos en el apartado``. Por ejemplo, si desea compilar una versión optimizada para publicación, deberá ejecutar el comando anterior seguido de `--release`. El ejecutable resultante estará disponible en la carpeta de destino en su sistema, y puede ser ejecutado con:
+Ten en cuenta que la primera compilación puede tardar más tiempo antes de que las dependencias se almacenen en la caché, las siguientes compilaciones serán más rápidas. Además, si necesitas especificar diferentes argumentos a la orden de compilación, puede hacerlo al final de la linea de comandos en el apartado ``. Por ejemplo, si desea compilar una versión optimizada para publicación, deberá ejecutar el comando anterior seguido de `--release`. El ejecutable resultante estará disponible en la carpeta de destino en su sistema, y puede ser ejecutado con:
```sh
target/debug/rustdesk
@@ -148,6 +150,8 @@ Por favor, asegurate de que estás ejecutando estos comandos desde la raíz del
- **[src/client.rs](https://github.com/rustdesk/rustdesk/tree/master/src/client.rs)**: iniciar una conexión "peer to peer"
- **[src/rendezvous_mediator.rs](https://github.com/rustdesk/rustdesk/tree/master/src/rendezvous_mediator.rs)**: Comunicación con [rustdesk-server](https://github.com/rustdesk/rustdesk-server), esperar la conexión remota directa ("TCP hole punching") o conexión indirecta ("relayed")
- **[src/platform](https://github.com/rustdesk/rustdesk/tree/master/src/platform)**: código específico de cada plataforma
+- **[flutter](https://github.com/rustdesk/rustdesk/tree/master/flutter)**: Flutter, código para moviles
+- **[flutter/web/js](https://github.com/rustdesk/rustdesk/tree/master/flutter/web/js)**: Javascript para cliente web Flutter
## Captura de pantalla
From d968ed302979c2523952fcd3cb9678864c4a11b1 Mon Sep 17 00:00:00 2001
From: fufesou
Date: Thu, 23 Jun 2022 10:29:22 +0800
Subject: [PATCH 12/24] socks5_reconnect: handle socks5 server down
Signed-off-by: fufesou
---
src/rendezvous_mediator.rs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/rendezvous_mediator.rs b/src/rendezvous_mediator.rs
index f575f684f..b332c69c9 100644
--- a/src/rendezvous_mediator.rs
+++ b/src/rendezvous_mediator.rs
@@ -216,7 +216,7 @@ impl RendezvousMediator {
},
Some(Err(e)) => bail!("Failed to receive next {}", e), // maybe socks5 tcp disconnected
None => {
- // unreachable!()
+ bail!("Socket receive none. Maybe socks5 server is down.");
},
}
},
From ef1f34cefabc1a93cc1b980a1059e016d5004dfb Mon Sep 17 00:00:00 2001
From: rustdesk
Date: Thu, 23 Jun 2022 11:15:37 +0800
Subject: [PATCH 13/24] update dep
---
Cargo.lock | 148 ++++++++++++++++++++++++-----------------------------
1 file changed, 68 insertions(+), 80 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 02260e9fa..c55c906fc 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -123,9 +123,9 @@ dependencies = [
[[package]]
name = "anyhow"
-version = "1.0.57"
+version = "1.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc"
+checksum = "bb07d2053ccdbe10e2af2995a2f116c1330396493dc1269f6a91d0ae82e19704"
[[package]]
name = "arboard"
@@ -455,7 +455,7 @@ version = "0.24.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6358dedf60f4d9b8db43ad187391afe959746101346fe51bb978126bec61dfb"
dependencies = [
- "clap 3.1.18",
+ "clap 3.2.6",
"heck 0.4.0",
"indexmap",
"log",
@@ -553,9 +553,9 @@ dependencies = [
[[package]]
name = "clap"
-version = "3.1.18"
+version = "3.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2dbdf4bdacb33466e854ce889eee8dfd5729abf7ccd7664d0a2d60cd384440b"
+checksum = "9f1fe12880bae935d142c8702d500c63a4e8634b6c3c57ad72bf978fc7b6249a"
dependencies = [
"atty",
"bitflags",
@@ -568,9 +568,9 @@ dependencies = [
[[package]]
name = "clap_lex"
-version = "0.2.0"
+version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213"
+checksum = "87eba3c8c7f42ef17f6c659fc7416d0f4758cd3e58861ee63c5fa4a4dde649e4"
dependencies = [
"os_str_bytes",
]
@@ -876,9 +876,9 @@ dependencies = [
[[package]]
name = "crossbeam-channel"
-version = "0.5.4"
+version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53"
+checksum = "4c02a4d71819009c192cf4872265391563fd6a84c81ff2c0f2a7026ca4c1d85c"
dependencies = [
"cfg-if 1.0.0",
"crossbeam-utils",
@@ -897,15 +897,15 @@ dependencies = [
[[package]]
name = "crossbeam-epoch"
-version = "0.9.8"
+version = "0.9.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c"
+checksum = "07db9d94cbd326813772c968ccd25999e5f8ae22f4f8d1b11effa37ef6ce281d"
dependencies = [
"autocfg 1.1.0",
"cfg-if 1.0.0",
"crossbeam-utils",
- "lazy_static",
"memoffset",
+ "once_cell",
"scopeguard",
]
@@ -921,12 +921,12 @@ dependencies = [
[[package]]
name = "crossbeam-utils"
-version = "0.8.8"
+version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38"
+checksum = "8ff1f980957787286a554052d03c7aee98d99cc32e09f6d45f0a814133c87978"
dependencies = [
"cfg-if 1.0.0",
- "lazy_static",
+ "once_cell",
]
[[package]]
@@ -1751,13 +1751,13 @@ dependencies = [
[[package]]
name = "getrandom"
-version = "0.2.6"
+version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"
+checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
dependencies = [
"cfg-if 1.0.0",
"libc",
- "wasi 0.10.2+wasi-snapshot-preview1",
+ "wasi",
]
[[package]]
@@ -2123,9 +2123,9 @@ dependencies = [
[[package]]
name = "hashbrown"
-version = "0.11.2"
+version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
+checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3"
[[package]]
name = "hbb_common"
@@ -2322,9 +2322,9 @@ dependencies = [
[[package]]
name = "indexmap"
-version = "1.8.2"
+version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6012d540c5baa3589337a98ce73408de9b5a25ec9fc2c6fd6be8f0d39e0ca5a"
+checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
dependencies = [
"autocfg 1.1.0",
"hashbrown",
@@ -2412,9 +2412,9 @@ checksum = "229d53d58899083193af11e15917b5640cd40b29ff475a1fe4ef725deb02d0f2"
[[package]]
name = "js-sys"
-version = "0.3.57"
+version = "0.3.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397"
+checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27"
dependencies = [
"wasm-bindgen",
]
@@ -2744,13 +2744,13 @@ dependencies = [
[[package]]
name = "mio"
-version = "0.8.3"
+version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "713d550d9b44d89174e066b7a6217ae06234c10cb47819a88290d2b353c31799"
+checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf"
dependencies = [
"libc",
"log",
- "wasi 0.11.0+wasi-snapshot-preview1",
+ "wasi",
"windows-sys 0.36.1",
]
@@ -3008,9 +3008,9 @@ dependencies = [
[[package]]
name = "num-complex"
-version = "0.4.1"
+version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97fbc387afefefd5e9e39493299f3069e14a140dd34dc19b4c1c1a8fddb6a790"
+checksum = "7ae39348c8bc5fbd7f40c727a9925f03517afd2ab27d46702108b6a7e5414c19"
dependencies = [
"num-traits 0.2.15",
]
@@ -3504,9 +3504,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
-version = "1.0.39"
+version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f"
+checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"
dependencies = [
"unicode-ident",
]
@@ -3635,9 +3635,9 @@ dependencies = [
[[package]]
name = "quote"
-version = "1.0.18"
+version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
+checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
dependencies = [
"proc-macro2",
]
@@ -3912,9 +3912,9 @@ dependencies = [
[[package]]
name = "reqwest"
-version = "0.11.10"
+version = "0.11.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46a1f7aa4f35e5e8b4160449f51afc758f0ce6454315a9fa7d0d113e958c41eb"
+checksum = "b75aa69a3f06bbcc66ede33af2af253c6f7a86b1ca0033f60c580a27074fbf92"
dependencies = [
"base64",
"bytes",
@@ -3934,12 +3934,13 @@ dependencies = [
"percent-encoding",
"pin-project-lite",
"rustls",
- "rustls-pemfile 0.3.0",
+ "rustls-pemfile 1.0.0",
"serde 1.0.137",
"serde_json 1.0.81",
"serde_urlencoded",
"tokio",
"tokio-rustls",
+ "tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
@@ -4048,7 +4049,7 @@ dependencies = [
"base64",
"cc",
"cfg-if 1.0.0",
- "clap 3.1.18",
+ "clap 3.2.6",
"clipboard",
"cocoa 0.24.0",
"core-foundation 0.9.3",
@@ -4151,15 +4152,6 @@ dependencies = [
"base64",
]
-[[package]]
-name = "rustls-pemfile"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ee86d63972a7c661d1536fefe8c3c8407321c3df668891286de28abcd087360"
-dependencies = [
- "base64",
-]
-
[[package]]
name = "rustls-pemfile"
version = "1.0.0"
@@ -4181,9 +4173,9 @@ dependencies = [
[[package]]
name = "rustversion"
-version = "1.0.6"
+version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f"
+checksum = "a0a5f7c728f5d284929a1cccb5bc19884422bfe6ef4d6c409da2c41838983fcf"
[[package]]
name = "ryu"
@@ -4612,9 +4604,9 @@ dependencies = [
[[package]]
name = "syn"
-version = "1.0.96"
+version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf"
+checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
dependencies = [
"proc-macro2",
"quote",
@@ -4635,13 +4627,15 @@ dependencies = [
[[package]]
name = "sys-locale"
-version = "0.2.0"
+version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3913c5a3d30054d7f77cf07cdd800c8103ace15c6e44437c5db66a43dd3a92cf"
+checksum = "658ee915b6c7b73ec4c1ffcd838506b5c5a4087eadc1ec8f862f1066cf2c8132"
dependencies = [
"cc",
"cstr_core",
+ "js-sys",
"libc",
+ "wasm-bindgen",
"web-sys",
"winapi 0.3.9",
]
@@ -4789,9 +4783,9 @@ dependencies = [
[[package]]
name = "time"
-version = "0.3.9"
+version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c2702e08a7a860f005826c6815dcac101b19b5eb330c27fe4a5928fec1d20ddd"
+checksum = "72c91f41dcb2f096c05f0873d667dceec1087ce5bcf984ec8ffb19acddbb3217"
dependencies = [
"itoa 1.0.2",
"libc",
@@ -4829,7 +4823,7 @@ dependencies = [
"bytes",
"libc",
"memchr",
- "mio 0.8.3",
+ "mio 0.8.4",
"num_cpus",
"once_cell",
"parking_lot 0.12.1",
@@ -4865,7 +4859,7 @@ dependencies = [
[[package]]
name = "tokio-socks"
version = "0.5.1"
-source = "git+https://github.com/open-trade/tokio-socks#3de8300fbce37e2cdaef042e016aa95058d007cf"
+source = "git+https://github.com/open-trade/tokio-socks#c34272f219b24dc6508f13fa81eff9850e616ce2"
dependencies = [
"bytes",
"either",
@@ -4919,9 +4913,9 @@ dependencies = [
[[package]]
name = "tower-service"
-version = "0.3.1"
+version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
+checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
[[package]]
name = "tracing"
@@ -5025,9 +5019,9 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
[[package]]
name = "unicode-ident"
-version = "1.0.0"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee"
+checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
[[package]]
name = "unicode-normalization"
@@ -5146,12 +5140,6 @@ dependencies = [
"try-lock",
]
-[[package]]
-name = "wasi"
-version = "0.10.2+wasi-snapshot-preview1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
-
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
@@ -5160,9 +5148,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
-version = "0.2.80"
+version = "0.2.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad"
+checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994"
dependencies = [
"cfg-if 1.0.0",
"wasm-bindgen-macro",
@@ -5170,9 +5158,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-backend"
-version = "0.2.80"
+version = "0.2.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4"
+checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a"
dependencies = [
"bumpalo",
"lazy_static",
@@ -5185,9 +5173,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-futures"
-version = "0.4.30"
+version = "0.4.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6f741de44b75e14c35df886aff5f1eb73aa114fa5d4d00dcd37b5e01259bf3b2"
+checksum = "de9a9cec1733468a8c657e57fa2413d2ae2c0129b95e87c5b72b8ace4d13f31f"
dependencies = [
"cfg-if 1.0.0",
"js-sys",
@@ -5197,9 +5185,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
-version = "0.2.80"
+version = "0.2.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5"
+checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -5207,9 +5195,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
-version = "0.2.80"
+version = "0.2.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b"
+checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048"
dependencies = [
"proc-macro2",
"quote",
@@ -5220,9 +5208,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
-version = "0.2.80"
+version = "0.2.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744"
+checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be"
[[package]]
name = "wayland-client"
@@ -5299,9 +5287,9 @@ dependencies = [
[[package]]
name = "web-sys"
-version = "0.3.57"
+version = "0.3.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283"
+checksum = "2fed94beee57daf8dd7d51f2b15dc2bcde92d7a72304cdf662a4371008b71b90"
dependencies = [
"js-sys",
"wasm-bindgen",
From 27851afc55078716bb6d431d5c7d0af91e98c27f Mon Sep 17 00:00:00 2001
From: RustDesk <71636191+rustdesk@users.noreply.github.com>
Date: Thu, 23 Jun 2022 13:33:36 +0800
Subject: [PATCH 14/24] Update README.md
---
README.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/README.md b/README.md
index 613e425e2..1faf6b7cf 100644
--- a/README.md
+++ b/README.md
@@ -11,6 +11,9 @@
Chat with us: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
+[
](https://f-droid.org/en/packages/com.carriez.flutter_hbb)
[](https://ko-fi.com/I2I04VU09)
From aaedcd6ac85a0c8a2b7bc21702cea602ac7fd405 Mon Sep 17 00:00:00 2001
From: RustDesk <71636191+rustdesk@users.noreply.github.com>
Date: Thu, 23 Jun 2022 13:46:15 +0800
Subject: [PATCH 15/24] Update README.md
---
README.md | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index 1faf6b7cf..2166073a7 100644
--- a/README.md
+++ b/README.md
@@ -11,10 +11,6 @@
Chat with us: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
-[
](https://f-droid.org/en/packages/com.carriez.flutter_hbb)
-
[](https://ko-fi.com/I2I04VU09)
Yet another remote desktop software, written in Rust. Works out of the box, no configuration required. You have full control of your data, with no concerns about security. You can use our rendezvous/relay server, [set up your own](https://rustdesk.com/server), or [write your own rendezvous/relay server](https://github.com/rustdesk/rustdesk-server-demo).
@@ -27,6 +23,10 @@ RustDesk welcomes contribution from everyone. See [`CONTRIBUTING.md`](CONTRIBUTI
[**BINARY DOWNLOAD**](https://github.com/rustdesk/rustdesk/releases)
+[
](https://f-droid.org/en/packages/com.carriez.flutter_hbb)
+
## Free Public Servers
Below are the servers you are using for free, it may change along the time. If you are not close to one of these, your network may be slow.
From 1833b8c2dce9849953bd9cf63a1af791799a8f9f Mon Sep 17 00:00:00 2001
From: Asura
Date: Thu, 23 Jun 2022 01:06:30 -0700
Subject: [PATCH 16/24] fix(pynput): Convert keysym to keycode according to the
system input source
---
pynput_service.py | 58 ++++++++++-------------------------------------
1 file changed, 12 insertions(+), 46 deletions(-)
diff --git a/pynput_service.py b/pynput_service.py
index d8df09e96..30bdd90f9 100644
--- a/pynput_service.py
+++ b/pynput_service.py
@@ -1,65 +1,32 @@
from pynput.keyboard import Key, Controller
from pynput.keyboard._xorg import KeyCode
from pynput._util.xorg import display_manager
-import Xlib
import os
import sys
import socket
+from Xlib.ext.xtest import fake_input
+from Xlib import X
KeyCode._from_symbol("\0") # test
+
class MyController(Controller):
def _handle(self, key, is_press):
"""Resolves a key identifier and sends a keyboard event.
:param event: The *X* keyboard event.
:param int keysym: The keysym to handle.
"""
- event = Xlib.display.event.KeyPress if is_press \
- else Xlib.display.event.KeyRelease
+ event = X.KeyPress if is_press \
+ else X.KeyRelease
+
keysym = self._keysym(key)
+ # Get keycode according to system language
+ keycode = self._display.keysym_to_keycode(keysym)
+ print(keycode)
- # Make sure to verify that the key was resolved
- if keysym is None:
- raise self.InvalidKeyException(key)
+ fake_input(self._display, event, keycode)
+ self._display.sync()
- # If the key has a virtual key code, use that immediately with
- # fake_input; fake input,being an X server extension, has access to
- # more internal state that we do
- if key.vk is not None:
- with display_manager(self._display) as dm:
- Xlib.ext.xtest.fake_input(
- dm,
- Xlib.X.KeyPress if is_press else Xlib.X.KeyRelease,
- dm.keysym_to_keycode(key.vk))
-
- # Otherwise use XSendEvent; we need to use this in the general case to
- # work around problems with keyboard layouts
- else:
- try:
- keycode, shift_state = self.keyboard_mapping[keysym]
- with self.modifiers as modifiers:
- alt_gr = Key.alt_gr in modifiers
- if alt_gr:
- self._send_key(event, keycode, shift_state)
- else:
- with display_manager(self._display) as dm:
- Xlib.ext.xtest.fake_input(
- dm,
- Xlib.X.KeyPress if is_press else Xlib.X.KeyRelease,
- keycode)
-
- except KeyError:
- with self._borrow_lock:
- keycode, index, count = self._borrows[keysym]
- self._send_key(
- event,
- keycode,
- index_to_shift(self._display, index))
- count += 1 if is_press else -1
- self._borrows[keysym] = (keycode, index, count)
-
- # Notify any running listeners
- self._emit('_on_fake_event', key, is_press)
keyboard = MyController()
@@ -77,7 +44,7 @@ server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
server.bind(server_address)
server.listen(1)
clientsocket, address = server.accept()
-os.system('chmod a+rw %s'%server_address)
+os.system('chmod a+rw %s' % server_address)
print("Got pynput connection")
@@ -121,4 +88,3 @@ def loop():
loop()
clientsocket.close()
server.close()
-
From 8aeacf77b3faf3f54e66b205875d5ab618c97924 Mon Sep 17 00:00:00 2001
From: Asura <99897242+asur4s@users.noreply.github.com>
Date: Thu, 23 Jun 2022 19:27:10 +0800
Subject: [PATCH 17/24] fix: remove print
---
pynput_service.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/pynput_service.py b/pynput_service.py
index 30bdd90f9..382df9bed 100644
--- a/pynput_service.py
+++ b/pynput_service.py
@@ -22,7 +22,6 @@ class MyController(Controller):
keysym = self._keysym(key)
# Get keycode according to system language
keycode = self._display.keysym_to_keycode(keysym)
- print(keycode)
fake_input(self._display, event, keycode)
self._display.sync()
From 649ff52970c7a077cfe9a0aa404dca4e3d22534a Mon Sep 17 00:00:00 2001
From: rustdesk
Date: Fri, 24 Jun 2022 02:47:46 +0800
Subject: [PATCH 18/24] https://github.com/rustdesk/rustdesk/issues/751
---
src/rendezvous_mediator.rs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/rendezvous_mediator.rs b/src/rendezvous_mediator.rs
index b332c69c9..a7f90b977 100644
--- a/src/rendezvous_mediator.rs
+++ b/src/rendezvous_mediator.rs
@@ -231,7 +231,7 @@ impl RendezvousMediator {
}
last_timer = now;
let elapsed_resp = last_register_resp.map(|x| x.elapsed().as_millis() as i64).unwrap_or(REG_INTERVAL);
- let timeout = (last_register_sent.map(|x| x.elapsed().as_millis() as i64).unwrap_or(REG_INTERVAL) - elapsed_resp) > REG_TIMEOUT;
+ let timeout = (elapsed_resp - last_register_sent.map(|x| x.elapsed().as_millis() as i64).unwrap_or(REG_INTERVAL)) > REG_TIMEOUT;
if timeout || elapsed_resp >= REG_INTERVAL {
allow_err!(rz.register_peer(&mut socket).await);
last_register_sent = now;
From c842642c026a948257caf2a6e43a7f187ab6084e Mon Sep 17 00:00:00 2001
From: Asura <99897242+asur4s@users.noreply.github.com>
Date: Fri, 24 Jun 2022 12:01:22 +0800
Subject: [PATCH 19/24] Replaced fake_input with display_manager's send_event
---
pynput_service.py | 31 ++++++++++++++++++++++++-------
1 file changed, 24 insertions(+), 7 deletions(-)
diff --git a/pynput_service.py b/pynput_service.py
index 382df9bed..24edcc1f9 100644
--- a/pynput_service.py
+++ b/pynput_service.py
@@ -6,6 +6,7 @@ import sys
import socket
from Xlib.ext.xtest import fake_input
from Xlib import X
+import Xlib
KeyCode._from_symbol("\0") # test
@@ -16,15 +17,31 @@ class MyController(Controller):
:param event: The *X* keyboard event.
:param int keysym: The keysym to handle.
"""
- event = X.KeyPress if is_press \
- else X.KeyRelease
- keysym = self._keysym(key)
- # Get keycode according to system language
- keycode = self._display.keysym_to_keycode(keysym)
+ event = Xlib.display.event.KeyPress if is_press \
+ else Xlib.display.event.KeyRelease
+
+ origin_keysym = self._keysym(key)
+ keycode = self._display.keysym_to_keycode(origin_keysym)
+
+ with display_manager(self._display) as dm, self.modifiers as modifiers:
+ # Under certain cimcumstances, such as when running under Xephyr,
+ # the value returned by dm.get_input_focus is an int
+ window = dm.get_input_focus().focus
+ send_event = getattr(
+ window,
+ 'send_event',
+ lambda event: dm.send_event(window, event))
+ send_event(event(
+ detail=keycode,
+ state=self._shift_mask(modifiers),
+ time=0,
+ root=dm.screen().root,
+ window=window,
+ same_screen=0,
+ child=Xlib.X.NONE,
+ root_x=0, root_y=0, event_x=0, event_y=0))
- fake_input(self._display, event, keycode)
- self._display.sync()
keyboard = MyController()
From 2ef9a9b8428a3903ebf5d097d88cae0894b515fb Mon Sep 17 00:00:00 2001
From: rustdesk
Date: Sat, 25 Jun 2022 02:44:19 +0800
Subject: [PATCH 20/24] upgrade seria
---
libs/hbb_common/src/config.rs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/hbb_common/src/config.rs b/libs/hbb_common/src/config.rs
index 1c14be303..cf3d669dc 100644
--- a/libs/hbb_common/src/config.rs
+++ b/libs/hbb_common/src/config.rs
@@ -16,7 +16,7 @@ pub const RENDEZVOUS_TIMEOUT: u64 = 12_000;
pub const CONNECT_TIMEOUT: u64 = 18_000;
pub const REG_INTERVAL: i64 = 12_000;
pub const COMPRESS_LEVEL: i32 = 3;
-const SERIAL: i32 = 1;
+const SERIAL: i32 = 3;
// 128x128
#[cfg(target_os = "macos")] // 128x128 on 160x160 canvas, then shrink to 128, mac looks better with padding
pub const ICON: &str = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAMAAAD04JH5AAAAyVBMVEUAAAAAcf8Acf8Acf8Acv8Acf8Acf8Acf8Acf8AcP8Acf8Ab/8AcP8Acf////8AaP/z+f/o8v/k7v/5/v/T5f8AYP/u9v/X6f+hx/+Kuv95pP8Aef/B1/+TwP9xoP8BdP/g6P+Irv9ZmP8Bgf/E3f98q/9sn/+01f+Es/9nm/9Jif8hhv8off/M4P+syP+avP86iP/c7f+xy/9yqf9Om/9hk/9Rjv+60P99tv9fpf88lv8yjf8Tgf8deP+kvP8BiP8NeP8hkP80gP8oj2VLAAAADXRSTlMA7o7qLvnaxZ1FOxYPjH9HWgAABHJJREFUeNrtm+tW4jAQgBfwuu7MtIUWsOUiCCioIIgLiqvr+z/UHq/LJKVkmwTcc/r9E2nzlU4mSTP9lpGRkZGR8VX5cZjfL+yCEXYL+/nDH//U/Pd8DgyTy39Xbv7oIAcWyB0cqbW/sweW2NtRaj8H1sgpGOwUIAH7Bkd7YJW9dXFwAJY5WNP/cmCZQnJvzIN18on5LwfWySXlxEPYAIcad8D6PdiHDbCfIFCADVBIENiFDbCbIACKPPXrZ+cP8E6/0znvP4EymgIEravIRcTxu8HxNSJ60a8W0AYECKrlAN+YwAthCd9wm1Ug6wKzIn5SgRduXfwkqDasCjx0XFzi9PV6zwNcIuhcWBOg+ikySq8C9UD4dEKWBCoOcspvAuLHTo9sCDQiFPHotRM48j8G5gVur1FdAN2uaYEuiz7xFsgEJ2RUoMUakXuBTHHoGxQYOBhHjeUBAefEnMAowFhaLBOKuOemBBbxLRQrH2PBCgMvNCPQGMeevTb9zLrPxz2Mo+QbEaijzPUcOOHMQZkKGRAIPem39+bypREMPTkQW/oCfk866zAkiIFG4yIKRE/aAnfiSd0WrORY6pFdXQEqi9mvAQm0RIOSnoCcZ8vJoz3diCnjRk+g8VP4/fuQDJ2Lxr6WwG0gXs9aTpDzW0vgDBlVUpixR8gYk44AD8FrUKHr8JQJGgIDnoDqoALxmWPQSi9AVVzm8gKUuEPGr/QCvptwJkbSYT/TC4S8C96DGjTj86aHtAI0x2WaBIq0eSYYpRa4EsdWVVwWu9O0Aj6f6dyBMnwEraeOgSYu0wZlauzA47QCbT7DgAQSE+hZWoEBF/BBmWOewNMK3BsSqKUW4MGcWqCSVmDkbvkXGKQOwg6PAUO9oL3xXhA20yaiCjuwYygRVQlUOTWTCf2SuNJTxeFjgaHByGuAIvd8ItdPLTDhS7IuqEE1YSKVOgbayLhSFQhMzYh8hwfBs1r7c505YVIQYEdNoKwxK06MJiyrpUFHiF0NAfCQUVHoiRclIXJIR6C2fqG37pBHvcWpgwzvAtYwkR5UGV2e42UISdBJETl3mg8ouo54Rcnti1/vaT+iuUQBt500Cgo4U10BeHSkk57FB0JjWkKRMWgLUA0lLodtImAQdaMiiri3+gIAPZQoutHNsgKF1aaDMhMyIdBf8Th+Bh8MTjGWCpl5Wv43tDmnF+IUVMrcZgRoiAxhtrloYizNkZaAnF5leglbNhj0wYCAbCDvGb0mP4nib7O7ZlcYQ2m1gPtIZgVgGNNMeaVAaWR+57TrqgtUnm3sHQ+kYeE6fufUubG1ez50FXbPnWgBlgSABmN3TTcsRl2yWkHRrwbiunvk/W2+Mg1hPZplPDeXRbZzStFH15s1QIVd3UImP5z/bHpeeQLvRJ7XLFUffQIlCvqlXETQbgN9/rlYABGosv+Vi9m2Xs639YLGrZd0br+odetlvdsvbN56abfd4vbCzv9Q3v/ygoOV21A4OPpfXvH4Ai+5ZGRkZGRkbJA/t/I0QMzoMiEAAAAASUVORK5CYII=
From e670b7e0594749a12375e9725eddf777560c14af Mon Sep 17 00:00:00 2001
From: rustdesk
Date: Mon, 27 Jun 2022 00:36:31 +0800
Subject: [PATCH 21/24] debug install
---
Cargo.lock | 20 ++++++++++----------
src/main.rs | 11 ++++-------
src/platform/windows.rs | 39 +++++++++++++++++++--------------------
src/ui.rs | 4 +++-
4 files changed, 36 insertions(+), 38 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index c55c906fc..7e679ef91 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -921,9 +921,9 @@ dependencies = [
[[package]]
name = "crossbeam-utils"
-version = "0.8.9"
+version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ff1f980957787286a554052d03c7aee98d99cc32e09f6d45f0a814133c87978"
+checksum = "7d82ee10ce34d7bc12c2122495e7593a9c41347ecdd64185af4ecf72cb1a7f83"
dependencies = [
"cfg-if 1.0.0",
"once_cell",
@@ -2571,9 +2571,9 @@ dependencies = [
[[package]]
name = "linked-hash-map"
-version = "0.5.4"
+version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
+checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]]
name = "lock_api"
@@ -4462,9 +4462,9 @@ checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32"
[[package]]
name = "smallvec"
-version = "1.8.0"
+version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
+checksum = "cc88c725d61fc6c3132893370cac4a0200e3fedf5da8331c570664b1987f5ca2"
[[package]]
name = "smithay-client-toolkit"
@@ -4942,9 +4942,9 @@ dependencies = [
[[package]]
name = "tracing-core"
-version = "0.1.27"
+version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7709595b8878a4965ce5e87ebf880a7d39c9afc6837721b21a5a816a8117d921"
+checksum = "7b7358be39f2f274f322d2aaed611acc57f382e8eb1e5b48cb9ae30933495ce7"
dependencies = [
"once_cell",
]
@@ -5025,9 +5025,9 @@ checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
[[package]]
name = "unicode-normalization"
-version = "0.1.19"
+version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
+checksum = "81dee68f85cab8cf68dec42158baf3a79a1cdc065a8b103025965d6ccb7f6cbd"
dependencies = [
"tinyvec",
]
diff --git a/src/main.rs b/src/main.rs
index 04930ab4b..a5b1d7b04 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -97,6 +97,7 @@ fn main() {
"desktopicon startmenu",
"".to_owned(),
false,
+ false,
));
return;
} else if args[0] == "--silent-install" {
@@ -104,12 +105,9 @@ fn main() {
"desktopicon startmenu",
"".to_owned(),
true,
+ args.len() > 1,
));
return;
- } else if args[0] == "--extract" {
- #[cfg(feature = "with_rc")]
- hbb_common::allow_err!(crate::rc::extract_resources(&args[1]));
- return;
}
}
if args[0] == "--remove" {
@@ -197,7 +195,7 @@ fn main() {
.about("RustDesk command line tool")
.args_from_usage(&args)
.get_matches();
- use hbb_common::{env_logger::*, config::LocalConfig};
+ use hbb_common::env_logger::*;
init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "info"));
if let Some(p) = matches.value_of("port-forward") {
let options: Vec = p.split(":").map(|x| x.to_owned()).collect();
@@ -224,7 +222,6 @@ fn main() {
remote_host = options[3].clone();
}
let key = matches.value_of("key").unwrap_or("").to_owned();
- let token = LocalConfig::get_option("access_token");
- cli::start_one_port_forward(options[0].clone(), port, remote_host, remote_port, key, token);
+ cli::start_one_port_forward(options[0].clone(), port, remote_host, remote_port, key);
}
}
diff --git a/src/platform/windows.rs b/src/platform/windows.rs
index cc3b4a050..4e8f7e16a 100644
--- a/src/platform/windows.rs
+++ b/src/platform/windows.rs
@@ -698,7 +698,7 @@ pub fn set_share_rdp(enable: bool) {
subkey,
if enable { "true" } else { "false" }
);
- run_cmds(cmd, false).ok();
+ run_cmds(cmd, false, "share_rdp").ok();
}
pub fn get_active_username() -> String {
@@ -835,7 +835,7 @@ pub fn check_update_broker_process() -> ResultType<()> {
origin_process_exe = origin_process_exe,
cur_exe = cur_exe.to_string_lossy().to_string(),
);
- run_cmds(cmds, false)?;
+ run_cmds(cmds, false, "update_broker")?;
Ok(())
}
@@ -876,7 +876,7 @@ pub fn update_me() -> ResultType<()> {
lic = register_licence(),
);
std::thread::sleep(std::time::Duration::from_millis(1000));
- run_cmds(cmds, false)?;
+ run_cmds(cmds, false, "update")?;
std::thread::sleep(std::time::Duration::from_millis(2000));
std::process::Command::new(&exe).arg("--tray").spawn().ok();
std::process::Command::new(&exe).spawn().ok();
@@ -905,7 +905,7 @@ fn get_after_install(exe: &str) -> String {
", ext=ext, exe=exe, app_name=app_name)
}
-pub fn install_me(options: &str, path: String, silent: bool) -> ResultType<()> {
+pub fn install_me(options: &str, path: String, silent: bool, debug: bool) -> ResultType<()> {
let uninstall_str = get_uninstall();
let mut path = path.trim_end_matches('\\').to_owned();
let (subkey, _path, start_menu, exe) = get_default_install_info();
@@ -929,7 +929,7 @@ pub fn install_me(options: &str, path: String, silent: bool) -> ResultType<()> {
version_build = versions[2];
}
- let tmp_path = "C:\\Windows\\temp";
+ let tmp_path = std::env::temp_dir().to_string_lossy().to_string();
let mk_shortcut = write_cmds(
format!(
"
@@ -945,6 +945,7 @@ oLink.Save
exe = exe,
),
"vbs",
+ "mk_shortcut",
)?
.to_str()
.unwrap_or("")
@@ -966,6 +967,7 @@ oLink.Save
exe = exe,
),
"vbs",
+ "uninstall_shortcut",
)?
.to_str()
.unwrap_or("")
@@ -986,6 +988,7 @@ oLink.Save
exe = exe,
),
"vbs",
+ "tray_shortcut",
)?
.to_str()
.unwrap_or("")
@@ -1042,7 +1045,7 @@ reg add {subkey} /f /v WindowsInstaller /t REG_DWORD /d 0
cscript \"{mk_shortcut}\"
cscript \"{uninstall_shortcut}\"
cscript \"{tray_shortcut}\"
-copy /Y \"{tmp_path}\\{app_name} Tray.lnk\" \"C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\\"
+copy /Y \"{tmp_path}\\{app_name} Tray.lnk\" \"%PROGRAMDATA%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\\"
{shortcuts}
copy /Y \"{tmp_path}\\Uninstall {app_name}.lnk\" \"{path}\\\"
del /f \"{mk_shortcut}\"
@@ -1079,7 +1082,7 @@ sc delete {app_name}
lic=register_licence(),
after_install=get_after_install(&exe),
);
- run_cmds(cmds, false)?;
+ run_cmds(cmds, debug, "install")?;
std::thread::sleep(std::time::Duration::from_millis(2000));
if !silent {
std::process::Command::new(&exe).spawn()?;
@@ -1091,11 +1094,11 @@ sc delete {app_name}
pub fn run_after_install() -> ResultType<()> {
let (_, _, _, exe) = get_install_info();
- run_cmds(get_after_install(&exe), true)
+ run_cmds(get_after_install(&exe), true, "after_install")
}
pub fn run_before_uninstall() -> ResultType<()> {
- run_cmds(get_before_uninstall(), true)
+ run_cmds(get_before_uninstall(), true, "before_install")
}
fn get_before_uninstall() -> String {
@@ -1126,7 +1129,7 @@ fn get_uninstall() -> String {
rd /s /q \"{path}\"
rd /s /q \"{start_menu}\"
del /f /q \"%PUBLIC%\\Desktop\\{app_name}*\"
- del /f /q \"C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\{app_name} Tray.lnk\"
+ del /f /q \"%PROGRAMDATA%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\{app_name} Tray.lnk\"
",
before_uninstall=get_before_uninstall(),
subkey=subkey,
@@ -1137,17 +1140,12 @@ fn get_uninstall() -> String {
}
pub fn uninstall_me() -> ResultType<()> {
- run_cmds(get_uninstall(), true)
+ run_cmds(get_uninstall(), true, "uninstall")
}
-fn write_cmds(cmds: String, ext: &str) -> ResultType {
+fn write_cmds(cmds: String, ext: &str, tip: &str) -> ResultType {
let mut tmp = std::env::temp_dir();
- tmp.push(format!(
- "{}_{:?}.{}",
- crate::get_app_name(),
- cmds.as_ptr(),
- ext
- ));
+ tmp.push(format!("{}_{}.{}", crate::get_app_name(), tip, ext));
let mut file = std::fs::File::create(&tmp)?;
// in case cmds mixed with \r\n and \n, make sure all ending with \r\n
// in some windows, \r\n required for cmd file to run
@@ -1170,8 +1168,8 @@ fn to_le(v: &mut [u16]) -> &[u8] {
unsafe { v.align_to().1 }
}
-fn run_cmds(cmds: String, show: bool) -> ResultType<()> {
- let tmp = write_cmds(cmds, "bat")?;
+fn run_cmds(cmds: String, show: bool, tip: &str) -> ResultType<()> {
+ let tmp = write_cmds(cmds, "bat", tip)?;
let tmp_fn = tmp.to_str().unwrap_or("");
let res = runas::Command::new("cmd")
.args(&["/C", &tmp_fn])
@@ -1348,6 +1346,7 @@ oLink.Save
id = id,
),
"vbs",
+ "connect_shortcut",
)?
.to_str()
.unwrap_or("")
diff --git a/src/ui.rs b/src/ui.rs
index 76ba23226..b93c11d44 100644
--- a/src/ui.rs
+++ b/src/ui.rs
@@ -213,7 +213,9 @@ impl UI {
fn install_me(&mut self, _options: String, _path: String) {
#[cfg(windows)]
std::thread::spawn(move || {
- allow_err!(crate::platform::windows::install_me(&_options, _path, false));
+ allow_err!(crate::platform::windows::install_me(
+ &_options, _path, false, false
+ ));
std::process::exit(0);
});
}
From 2fa2c2d385cd5198075db808d4964abf03b24154 Mon Sep 17 00:00:00 2001
From: Asura
Date: Sun, 26 Jun 2022 18:19:38 -0700
Subject: [PATCH 22/24] fix(pynput): Use fake input to solve lock screen
problems
---
pynput_service.py | 30 +++++++-----------------------
1 file changed, 7 insertions(+), 23 deletions(-)
diff --git a/pynput_service.py b/pynput_service.py
index 24edcc1f9..90b8741ce 100644
--- a/pynput_service.py
+++ b/pynput_service.py
@@ -17,30 +17,14 @@ class MyController(Controller):
:param event: The *X* keyboard event.
:param int keysym: The keysym to handle.
"""
+ keysym = self._keysym(key)
+ keycode = self._display.keysym_to_keycode(keysym)
- event = Xlib.display.event.KeyPress if is_press \
- else Xlib.display.event.KeyRelease
-
- origin_keysym = self._keysym(key)
- keycode = self._display.keysym_to_keycode(origin_keysym)
-
- with display_manager(self._display) as dm, self.modifiers as modifiers:
- # Under certain cimcumstances, such as when running under Xephyr,
- # the value returned by dm.get_input_focus is an int
- window = dm.get_input_focus().focus
- send_event = getattr(
- window,
- 'send_event',
- lambda event: dm.send_event(window, event))
- send_event(event(
- detail=keycode,
- state=self._shift_mask(modifiers),
- time=0,
- root=dm.screen().root,
- window=window,
- same_screen=0,
- child=Xlib.X.NONE,
- root_x=0, root_y=0, event_x=0, event_y=0))
+ with display_manager(self._display) as dm:
+ Xlib.ext.xtest.fake_input(
+ dm,
+ Xlib.X.KeyPress if is_press else Xlib.X.KeyRelease,
+ keycode)
From ece86cda9edfd8d52f182b833f2e25e31a86d2d6 Mon Sep 17 00:00:00 2001
From: csf
Date: Thu, 23 Jun 2022 17:42:30 +0800
Subject: [PATCH 23/24] abr
---
libs/hbb_common/protos/message.proto | 11 +-
libs/hbb_common/src/config.rs | 2 +
libs/scrap/src/common/android.rs | 4 +-
libs/scrap/src/common/codec.rs | 29 +--
libs/scrap/src/common/x11.rs | 4 +-
src/client.rs | 29 +--
src/server/connection.rs | 45 ++--
src/server/video_service.rs | 365 +++++++++++++++++++--------
src/ui/header.tis | 27 +-
src/ui/remote.css | 14 +-
src/ui/remote.html | 56 ++--
src/ui/remote.rs | 74 +++++-
src/ui/remote.tis | 39 +++
13 files changed, 493 insertions(+), 206 deletions(-)
diff --git a/libs/hbb_common/protos/message.proto b/libs/hbb_common/protos/message.proto
index 048301d7e..7dd746e3c 100644
--- a/libs/hbb_common/protos/message.proto
+++ b/libs/hbb_common/protos/message.proto
@@ -425,9 +425,9 @@ message PermissionInfo {
enum ImageQuality {
NotSet = 0;
- Low = 2;
- Balanced = 3;
- Best = 4;
+ Low = 50;
+ Balanced = 66;
+ Best = 100;
}
message OptionMessage {
@@ -441,15 +441,18 @@ message OptionMessage {
BoolOption show_remote_cursor = 3;
BoolOption privacy_mode = 4;
BoolOption block_input = 5;
- int32 custom_image_quality = 6;
+ uint32 custom_image_quality = 6;
BoolOption disable_audio = 7;
BoolOption disable_clipboard = 8;
BoolOption enable_file_transfer = 9;
+ BoolOption enable_abr = 10;
}
message TestDelay {
int64 time = 1;
bool from_client = 2;
+ uint32 last_delay = 3;
+ uint32 target_bitrate = 4;
}
message PublicKey {
diff --git a/libs/hbb_common/src/config.rs b/libs/hbb_common/src/config.rs
index 1c14be303..068816dc5 100644
--- a/libs/hbb_common/src/config.rs
+++ b/libs/hbb_common/src/config.rs
@@ -139,6 +139,8 @@ pub struct PeerConfig {
pub disable_clipboard: bool,
#[serde(default)]
pub enable_file_transfer: bool,
+ #[serde(default)]
+ pub show_quality_monitor: bool,
// the other scalar value must before this
#[serde(default)]
diff --git a/libs/scrap/src/common/android.rs b/libs/scrap/src/common/android.rs
index 1975a6505..8322da3cd 100644
--- a/libs/scrap/src/common/android.rs
+++ b/libs/scrap/src/common/android.rs
@@ -3,8 +3,8 @@ use crate::rgba_to_i420;
use lazy_static::lazy_static;
use serde_json::Value;
use std::collections::HashMap;
-use std::io;
use std::sync::Mutex;
+use std::{io, time::Duration};
lazy_static! {
static ref SCREEN_SIZE: Mutex<(u16, u16, u16)> = Mutex::new((0, 0, 0)); // (width, height, scale)
@@ -33,7 +33,7 @@ impl Capturer {
self.display.height() as usize
}
- pub fn frame<'a>(&'a mut self, _timeout_ms: u32) -> io::Result> {
+ pub fn frame<'a>(&'a mut self, _timeout: Duration) -> io::Result> {
if let Some(buf) = get_video_raw() {
crate::would_block_if_equal(&mut self.saved_raw_data, buf)?;
rgba_to_i420(self.width(), self.height(), buf, &mut self.bgra);
diff --git a/libs/scrap/src/common/codec.rs b/libs/scrap/src/common/codec.rs
index f1533d7cf..2766243a3 100644
--- a/libs/scrap/src/common/codec.rs
+++ b/libs/scrap/src/common/codec.rs
@@ -107,17 +107,6 @@ impl Encoder {
c.rc_target_bitrate = config.bitrate;
c.rc_undershoot_pct = 95;
c.rc_dropframe_thresh = 25;
- if config.rc_min_quantizer > 0 {
- c.rc_min_quantizer = config.rc_min_quantizer;
- }
- if config.rc_max_quantizer > 0 {
- c.rc_max_quantizer = config.rc_max_quantizer;
- }
- let mut speed = config.speed;
- if speed <= 0 {
- speed = 6;
- }
-
c.g_threads = if num_threads == 0 {
num_cpus::get() as _
} else {
@@ -162,7 +151,7 @@ impl Encoder {
Higher numbers (7 or 8) will be lower quality but more manageable for lower latency
use cases and also for lower CPU power devices such as mobile.
*/
- call_vpx!(vpx_codec_control_(&mut ctx, VP8E_SET_CPUUSED as _, speed,));
+ call_vpx!(vpx_codec_control_(&mut ctx, VP8E_SET_CPUUSED as _, 7,));
// set row level multi-threading
/*
as some people in comments and below have already commented,
@@ -222,6 +211,19 @@ impl Encoder {
})
}
+ pub fn set_bitrate(&mut self, bitrate: c_uint) -> Result<()> {
+ // let mut cfg = self.ctx.config.enc;
+ let mut new_enc_cfg = unsafe { *self.ctx.config.enc.to_owned() };
+ new_enc_cfg.rc_target_bitrate = bitrate;
+ call_vpx!(vpx_codec_enc_config_set(&mut self.ctx, &new_enc_cfg));
+ return Ok(());
+ }
+
+ pub fn get_bitrate(&mut self) -> u32 {
+ let cfg = unsafe { *self.ctx.config.enc.to_owned() };
+ cfg.rc_target_bitrate
+ }
+
/// Notify the encoder to return any pending packets
pub fn flush(&mut self) -> Result {
call_vpx!(vpx_codec_encode(
@@ -273,9 +275,6 @@ pub struct Config {
pub bitrate: c_uint,
/// The codec
pub codec: VideoCodecId,
- pub rc_min_quantizer: u32,
- pub rc_max_quantizer: u32,
- pub speed: i32,
}
pub struct EncodeFrames<'a> {
diff --git a/libs/scrap/src/common/x11.rs b/libs/scrap/src/common/x11.rs
index f8217e3b7..255819902 100644
--- a/libs/scrap/src/common/x11.rs
+++ b/libs/scrap/src/common/x11.rs
@@ -1,5 +1,5 @@
use crate::x11;
-use std::{io, ops};
+use std::{io, ops, time::Duration};
pub struct Capturer(x11::Capturer);
@@ -16,7 +16,7 @@ impl Capturer {
self.0.display().rect().h as usize
}
- pub fn frame<'a>(&'a mut self, _timeout_ms: u32) -> io::Result> {
+ pub fn frame<'a>(&'a mut self, _timeout: Duration) -> io::Result> {
Ok(Frame(self.0.frame()?))
}
}
diff --git a/src/client.rs b/src/client.rs
index fed83cece..85bb2c0cb 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -886,6 +886,8 @@ impl LoginConfigHandler {
option.block_input = BoolOption::Yes.into();
} else if name == "unblock-input" {
option.block_input = BoolOption::No.into();
+ } else if name == "show-quality-monitor" {
+ config.show_quality_monitor = !config.show_quality_monitor;
} else {
let v = self.options.get(&name).is_some();
if v {
@@ -918,15 +920,8 @@ impl LoginConfigHandler {
n += 1;
} else if q == "custom" {
let config = PeerConfig::load(&self.id);
- let mut it = config.custom_image_quality.iter();
- let bitrate = it.next();
- let quantizer = it.next();
- if let Some(bitrate) = bitrate {
- if let Some(quantizer) = quantizer {
- msg.custom_image_quality = bitrate << 8 | quantizer;
- n += 1;
- }
- }
+ msg.custom_image_quality = config.custom_image_quality[0] as _;
+ n += 1;
}
if self.get_toggle_option("show-remote-cursor") {
msg.show_remote_cursor = BoolOption::Yes.into();
@@ -988,6 +983,8 @@ impl LoginConfigHandler {
self.config.disable_audio
} else if name == "disable-clipboard" {
self.config.disable_clipboard
+ } else if name == "show-quality-monitor" {
+ self.config.show_quality_monitor
} else {
!self.get_option(name).is_empty()
}
@@ -1009,17 +1006,17 @@ impl LoginConfigHandler {
msg_out
}
- pub fn save_custom_image_quality(&mut self, bitrate: i32, quantizer: i32) -> Message {
+ pub fn save_custom_image_quality(&mut self, custom_image_quality: u32) -> Message {
let mut misc = Misc::new();
misc.set_option(OptionMessage {
- custom_image_quality: bitrate << 8 | quantizer,
+ custom_image_quality,
..Default::default()
});
let mut msg_out = Message::new();
msg_out.set_misc(misc);
let mut config = self.load_config();
config.image_quality = "custom".to_owned();
- config.custom_image_quality = vec![bitrate, quantizer];
+ config.custom_image_quality = vec![custom_image_quality as _];
self.save_config(config);
msg_out
}
@@ -1214,14 +1211,6 @@ where
return (video_sender, audio_sender);
}
-pub async fn handle_test_delay(t: TestDelay, peer: &mut Stream) {
- if !t.from_client {
- let mut msg_out = Message::new();
- msg_out.set_test_delay(t);
- allow_err!(peer.send(&msg_out).await);
- }
-}
-
// mask = buttons << 3 | type
// type, 1: down, 2: up, 3: wheel
// buttons, 1: left, 2: right, 4: middle
diff --git a/src/server/connection.rs b/src/server/connection.rs
index 304b20655..21072e9cd 100644
--- a/src/server/connection.rs
+++ b/src/server/connection.rs
@@ -3,6 +3,7 @@ use super::{input_service::*, *};
use crate::clipboard_file::*;
#[cfg(not(any(target_os = "android", target_os = "ios")))]
use crate::common::update_clipboard;
+use crate::video_service;
#[cfg(any(target_os = "android", target_os = "ios"))]
use crate::{common::MOBILE_INFO2, mobile::connection_manager::start_channel};
use crate::{ipc, VERSION};
@@ -69,7 +70,6 @@ pub struct Connection {
audio: bool,
file: bool,
last_test_delay: i64,
- image_quality: i32,
lock_after_session_end: bool,
show_remote_cursor: bool, // by peer
ip: String,
@@ -105,7 +105,7 @@ impl Subscriber for ConnInner {
}
}
-const TEST_DELAY_TIMEOUT: Duration = Duration::from_secs(3);
+const TEST_DELAY_TIMEOUT: Duration = Duration::from_secs(1);
const SEC30: Duration = Duration::from_secs(30);
const H1: Duration = Duration::from_secs(3600);
const MILLI1: Duration = Duration::from_millis(1);
@@ -154,7 +154,6 @@ impl Connection {
audio: Config::get_option("enable-audio").is_empty(),
file: Config::get_option("enable-file-transfer").is_empty(),
last_test_delay: 0,
- image_quality: ImageQuality::Balanced.value(),
lock_after_session_end: false,
show_remote_cursor: false,
ip: "".to_owned(),
@@ -376,8 +375,11 @@ impl Connection {
if time > 0 && conn.last_test_delay == 0 {
conn.last_test_delay = time;
let mut msg_out = Message::new();
+ let qos = video_service::VIDEO_QOS.lock().unwrap();
msg_out.set_test_delay(TestDelay{
time,
+ last_delay:qos.current_delay,
+ target_bitrate:qos.target_bitrate,
..Default::default()
});
conn.inner.send(msg_out.into());
@@ -394,8 +396,7 @@ impl Connection {
let _ = privacy_mode::turn_off_privacy(0);
}
video_service::notify_video_frame_feched(id, None);
- video_service::update_test_latency(id, 0);
- video_service::update_image_quality(id, None);
+ video_service::VIDEO_QOS.lock().unwrap().reset();
if let Err(err) = conn.try_port_forward_loop(&mut rx_from_cm).await {
conn.on_close(&err.to_string(), false);
}
@@ -664,7 +665,7 @@ impl Connection {
res.set_peer_info(pi);
} else {
try_activate_screen();
- match super::video_service::get_displays() {
+ match video_service::get_displays() {
Err(err) => {
res.set_error(format!("X11 error: {}", err));
}
@@ -886,10 +887,11 @@ impl Connection {
self.inner.send(msg_out.into());
} else {
self.last_test_delay = 0;
- let latency = crate::get_time() - t.time;
- if latency > 0 {
- super::video_service::update_test_latency(self.inner.id(), latency);
- }
+ let new_delay = (crate::get_time() - t.time) as u32;
+ video_service::VIDEO_QOS
+ .lock()
+ .unwrap()
+ .update_network_delay(new_delay);
}
} else if self.authorized {
match msg.union {
@@ -1065,7 +1067,7 @@ impl Connection {
},
Some(message::Union::misc(misc)) => match misc.union {
Some(misc::Union::switch_display(s)) => {
- super::video_service::switch_display(s.display);
+ video_service::switch_display(s.display);
}
Some(misc::Union::chat_message(c)) => {
self.send_to_cm(ipc::Data::ChatMessage { text: c.text });
@@ -1075,7 +1077,7 @@ impl Connection {
}
Some(misc::Union::refresh_video(r)) => {
if r {
- super::video_service::refresh();
+ video_service::refresh();
}
}
Some(misc::Union::video_received(_)) => {
@@ -1095,13 +1097,18 @@ impl Connection {
async fn update_option(&mut self, o: &OptionMessage) {
log::info!("Option update: {:?}", o);
if let Ok(q) = o.image_quality.enum_value() {
- self.image_quality = q.value();
- super::video_service::update_image_quality(self.inner.id(), Some(q.value()));
- }
- let q = o.custom_image_quality;
- if q > 0 {
- self.image_quality = q;
- super::video_service::update_image_quality(self.inner.id(), Some(q));
+ let mut image_quality = None;
+ if let ImageQuality::NotSet = q {
+ if o.custom_image_quality > 0 {
+ image_quality = Some(o.custom_image_quality);
+ }
+ } else {
+ image_quality = Some(q.value() as _)
+ }
+ video_service::VIDEO_QOS
+ .lock()
+ .unwrap()
+ .update_image_quality(image_quality);
}
if let Ok(q) = o.lock_after_session_end.enum_value() {
if q != BoolOption::NotSet {
diff --git a/src/server/video_service.rs b/src/server/video_service.rs
index b486cd311..8dcf2db73 100644
--- a/src/server/video_service.rs
+++ b/src/server/video_service.rs
@@ -33,19 +33,249 @@ use std::{
use virtual_display;
pub const NAME: &'static str = "video";
+const FPS: u8 = 30;
lazy_static::lazy_static! {
static ref CURRENT_DISPLAY: Arc> = Arc::new(Mutex::new(usize::MAX));
static ref LAST_ACTIVE: Arc> = Arc::new(Mutex::new(Instant::now()));
static ref SWITCH: Arc> = Default::default();
- static ref TEST_LATENCIES: Arc>> = Default::default();
- static ref IMAGE_QUALITIES: Arc>> = Default::default();
static ref FRAME_FETCHED_NOTIFIER: (UnboundedSender<(i32, Option)>, Arc)>>>) = {
let (tx, rx) = unbounded_channel();
(tx, Arc::new(TokioMutex::new(rx)))
};
static ref PRIVACY_MODE_CONN_ID: Mutex = Mutex::new(0);
static ref IS_CAPTURER_MAGNIFIER_SUPPORTED: bool = is_capturer_mag_supported();
+ pub static ref VIDEO_QOS: Arc> = Default::default();
+}
+
+pub struct VideoQoS {
+ width: u32,
+ height: u32,
+ user_image_quality: u32,
+ current_image_quality: u32,
+ enable_abr: bool,
+
+ pub current_delay: u32,
+ pub fps: u8, // abr
+ pub target_bitrate: u32, // abr
+ updated: bool,
+
+ state: AdaptiveState,
+ last_delay: u32,
+ count: u32,
+}
+
+#[derive(Debug)]
+enum AdaptiveState {
+ Normal,
+ LowDelay,
+ HeightDelay,
+}
+
+impl Default for VideoQoS {
+ fn default() -> Self {
+ VideoQoS {
+ fps: FPS,
+ user_image_quality: ImageQuality::Balanced.value() as _,
+ current_image_quality: ImageQuality::Balanced.value() as _,
+ enable_abr: false,
+ width: 0,
+ height: 0,
+ current_delay: 0,
+ target_bitrate: 0,
+ updated: false,
+ state: AdaptiveState::Normal,
+ last_delay: 0,
+ count: 0,
+ }
+ }
+}
+
+const MAX: f32 = 1.2;
+const MIN: f32 = 0.8;
+const MAX_COUNT: u32 = 3;
+const MAX_DELAY: u32 = 500;
+const MIN_DELAY: u32 = 50;
+
+impl VideoQoS {
+ pub fn set_size(&mut self, width: u32, height: u32) {
+ if width == 0 || height == 0 {
+ return;
+ }
+ self.width = width;
+ self.height = height;
+ }
+
+ pub fn spf(&mut self) -> Duration {
+ if self.fps <= 0 {
+ self.fps = FPS;
+ }
+ time::Duration::from_secs_f32(1. / (self.fps as f32))
+ }
+
+ // abr
+ pub fn update_network_delay(&mut self, delay: u32) {
+ if self.current_delay.eq(&0) {
+ self.current_delay = delay;
+ return;
+ }
+ let current_delay = self.current_delay as f32;
+
+ self.current_delay = delay / 2 + self.current_delay / 2;
+ log::debug!(
+ "update_network_delay:{}, {}, state:{:?},count:{}",
+ self.current_delay,
+ delay,
+ self.state,
+ self.count
+ );
+
+ if self.current_delay < MIN_DELAY {
+ if self.fps != 30 && self.current_image_quality != self.user_image_quality {
+ log::debug!("current_delay is normal, set to user_image_quality");
+ self.fps = 30;
+ self.current_image_quality = self.user_image_quality;
+ let _ = self.generate_bitrate().ok();
+ self.updated = true;
+ }
+ self.state = AdaptiveState::Normal;
+ } else if self.current_delay > MAX_DELAY {
+ if self.fps != 5 && self.current_image_quality != 25 {
+ log::debug!("current_delay is very height, set fps to 5, image_quality to 25");
+ self.fps = 5;
+ self.current_image_quality = 25;
+ let _ = self.generate_bitrate().ok();
+ self.updated = true;
+ }
+ } else {
+ let delay = delay as f32;
+ let last_delay = self.last_delay as f32;
+ match self.state {
+ AdaptiveState::Normal => {
+ if delay > current_delay * MAX {
+ self.state = AdaptiveState::HeightDelay;
+ } else if delay < current_delay * MIN
+ && self.current_image_quality < self.user_image_quality
+ {
+ self.state = AdaptiveState::LowDelay;
+ }
+ self.count = 1;
+ self.last_delay = self.current_delay
+ }
+ AdaptiveState::HeightDelay => {
+ if delay > last_delay {
+ if self.count > MAX_COUNT {
+ self.decrease_quality();
+ self.reset_state();
+ return;
+ }
+ self.count += 1;
+ } else {
+ self.reset_state();
+ }
+ }
+ AdaptiveState::LowDelay => {
+ if delay < last_delay * MIN {
+ if self.count > MAX_COUNT {
+ self.increase_quality();
+ self.reset_state();
+ return;
+ }
+ self.count += 1;
+ } else {
+ self.reset_state();
+ }
+ }
+ }
+ }
+ }
+
+ fn reset_state(&mut self) {
+ self.count = 0;
+ self.state = AdaptiveState::Normal;
+ }
+
+ fn increase_quality(&mut self) {
+ log::debug!("Adaptive increase quality");
+ if self.fps < FPS {
+ log::debug!("increase fps {} -> {}", self.fps, FPS);
+ self.fps = FPS;
+ } else {
+ self.current_image_quality += self.current_image_quality / 2;
+ let _ = self.generate_bitrate().ok();
+ log::debug!("increase quality:{}", self.current_image_quality);
+ }
+ self.updated = true;
+ }
+
+ fn decrease_quality(&mut self) {
+ log::debug!("Adaptive decrease quality");
+ if self.fps < 15 {
+ log::debug!("fps is low enough :{}", self.fps);
+ return;
+ }
+ if self.current_image_quality < ImageQuality::Low.value() as _ {
+ self.fps = self.fps / 2;
+ log::debug!("decrease fps:{}", self.fps);
+ } else {
+ self.current_image_quality -= self.current_image_quality / 2;
+ let _ = self.generate_bitrate().ok();
+ log::debug!("decrease quality:{}", self.current_image_quality);
+ };
+ self.updated = true;
+ }
+
+ pub fn update_image_quality(&mut self, image_quality: Option) {
+ if let Some(image_quality) = image_quality {
+ if image_quality < 10 || image_quality > 200 {
+ self.current_image_quality = ImageQuality::Balanced.value() as _;
+ }
+ if self.current_image_quality != image_quality {
+ self.current_image_quality = image_quality;
+ let _ = self.generate_bitrate().ok();
+ self.updated = true;
+ }
+ } else {
+ self.current_image_quality = ImageQuality::Balanced.value() as _;
+ }
+ self.user_image_quality = self.current_image_quality;
+ }
+
+ pub fn generate_bitrate(&mut self) -> ResultType {
+ // https://www.nvidia.com/en-us/geforce/guides/broadcasting-guide/
+ if self.width == 0 || self.height == 0 {
+ bail!("Fail to generate_bitrate, width or height is not set");
+ }
+ if self.current_image_quality == 0 {
+ self.current_image_quality = ImageQuality::Balanced.value() as _;
+ }
+
+ let base_bitrate = ((self.width * self.height) / 800) as u32;
+
+ #[cfg(target_os = "android")]
+ {
+ // fix when andorid screen shrinks
+ let fix = Display::fix_quality() as u32;
+ log::debug!("Android screen, fix quality:{}", fix);
+ let base_bitrate = base_bitrate * fix;
+ self.target_bitrate = base_bitrate * self.image_quality / 100;
+ Ok(self.target_bitrate)
+ }
+ self.target_bitrate = base_bitrate * self.current_image_quality / 100;
+ Ok(self.target_bitrate)
+ }
+
+ pub fn check_if_updated(&mut self) -> bool {
+ if self.updated {
+ self.updated = false;
+ return true;
+ }
+ return false;
+ }
+
+ pub fn reset(&mut self) {
+ *self = Default::default();
+ }
}
fn is_capturer_mag_supported() -> bool {
@@ -125,7 +355,7 @@ impl VideoFrameController {
}
trait TraitCapturer {
- fn frame<'a>(&'a mut self, timeout_ms: u32) -> Result>;
+ fn frame<'a>(&'a mut self, timeout: Duration) -> Result>;
#[cfg(windows)]
fn is_gdi(&self) -> bool;
@@ -134,8 +364,8 @@ trait TraitCapturer {
}
impl TraitCapturer for Capturer {
- fn frame<'a>(&'a mut self, timeout_ms: u32) -> Result> {
- self.frame(timeout_ms)
+ fn frame<'a>(&'a mut self, timeout: Duration) -> Result> {
+ self.frame(timeout)
}
#[cfg(windows)]
@@ -320,9 +550,6 @@ fn run(sp: GenericService) -> ResultType<()> {
#[cfg(windows)]
ensure_close_virtual_device()?;
- let fps = 30;
- let wait = 1000 / fps;
- let spf = time::Duration::from_secs_f32(1. / (fps as f32));
let (ndisplay, current, display) = get_current_display()?;
let (origin, width, height) = (display.origin(), display.width(), display.height());
log::debug!(
@@ -357,24 +584,26 @@ fn run(sp: GenericService) -> ResultType<()> {
}
let mut c = create_capturer(captuerer_privacy_mode_id, display)?;
- let q = get_image_quality();
- let (bitrate, rc_min_quantizer, rc_max_quantizer, speed) = get_quality(width, height, q);
- log::info!("bitrate={}, rc_min_quantizer={}", bitrate, rc_min_quantizer);
+ let mut video_qos = VIDEO_QOS.lock().unwrap();
+
+ video_qos.set_size(width as _, height as _);
+ let mut spf = video_qos.spf();
+ let bitrate = video_qos.generate_bitrate()?;
+ drop(video_qos);
+
+ log::info!("init encoder, bitrate={}", bitrate);
let cfg = Config {
width: width as _,
height: height as _,
timebase: [1, 1000], // Output timestamp precision
bitrate,
codec: VideoCodecId::VP9,
- rc_min_quantizer,
- rc_max_quantizer,
- speed,
};
- let mut vpx;
- match Encoder::new(&cfg, (num_cpus::get() / 2) as _) {
- Ok(x) => vpx = x,
+
+ let mut vpx = match Encoder::new(&cfg, (num_cpus::get() / 2) as _) {
+ Ok(x) => x,
Err(err) => bail!("Failed to create encoder: {}", err),
- }
+ };
if *SWITCH.lock().unwrap() {
log::debug!("Broadcasting display switch");
@@ -401,10 +630,24 @@ fn run(sp: GenericService) -> ResultType<()> {
let mut try_gdi = 1;
#[cfg(windows)]
log::info!("gdi: {}", c.is_gdi());
+
while sp.ok() {
#[cfg(windows)]
check_uac_switch(privacy_mode_id, captuerer_privacy_mode_id)?;
+ {
+ let mut video_qos = VIDEO_QOS.lock().unwrap();
+ if video_qos.check_if_updated() {
+ log::debug!(
+ "qos is updated, target_bitrate:{}, fps:{}",
+ video_qos.target_bitrate,
+ video_qos.fps
+ );
+ vpx.set_bitrate(video_qos.target_bitrate).unwrap();
+ spf = video_qos.spf();
+ }
+ }
+
if *SWITCH.lock().unwrap() {
bail!("SWITCH");
}
@@ -413,9 +656,6 @@ fn run(sp: GenericService) -> ResultType<()> {
bail!("SWITCH");
}
check_privacy_mode_changed(&sp, privacy_mode_id)?;
- if get_image_quality() != q {
- bail!("SWITCH");
- }
#[cfg(windows)]
{
if crate::platform::windows::desktop_changed() {
@@ -437,7 +677,7 @@ fn run(sp: GenericService) -> ResultType<()> {
frame_controller.reset();
#[cfg(any(target_os = "android", target_os = "ios"))]
- let res = match (*c).frame(wait as _) {
+ let res = match c.frame(spf) {
Ok(frame) => {
let time = now - start;
let ms = (time.as_secs() * 1000 + time.subsec_millis() as u64) as i64;
@@ -460,7 +700,7 @@ fn run(sp: GenericService) -> ResultType<()> {
};
#[cfg(not(any(target_os = "android", target_os = "ios")))]
- let res = match (*c).frame(wait as _) {
+ let res = match c.frame(spf) {
Ok(frame) => {
let time = now - start;
let ms = (time.as_secs() * 1000 + time.subsec_millis() as u64) as i64;
@@ -748,82 +988,3 @@ fn get_current_display() -> ResultType<(usize, usize, Display)> {
}
return Ok((n, current, displays.remove(current)));
}
-
-#[inline]
-fn update_latency(id: i32, latency: i64, latencies: &mut HashMap) {
- if latency <= 0 {
- latencies.remove(&id);
- } else {
- latencies.insert(id, latency);
- }
-}
-
-pub fn update_test_latency(id: i32, latency: i64) {
- update_latency(id, latency, &mut *TEST_LATENCIES.lock().unwrap());
-}
-
-fn convert_quality(q: i32) -> i32 {
- let q = {
- if q == ImageQuality::Balanced.value() {
- (100 * 2 / 3, 12)
- } else if q == ImageQuality::Low.value() {
- (100 / 2, 18)
- } else if q == ImageQuality::Best.value() {
- (100, 12)
- } else {
- let bitrate = q >> 8 & 0xFF;
- let quantizer = q & 0xFF;
- (bitrate * 2, (100 - quantizer) * 36 / 100)
- }
- };
- if q.0 <= 0 {
- 0
- } else {
- q.0 << 8 | q.1
- }
-}
-
-pub fn update_image_quality(id: i32, q: Option) {
- match q {
- Some(q) => {
- let q = convert_quality(q);
- if q > 0 {
- IMAGE_QUALITIES.lock().unwrap().insert(id, q);
- } else {
- IMAGE_QUALITIES.lock().unwrap().remove(&id);
- }
- }
- None => {
- IMAGE_QUALITIES.lock().unwrap().remove(&id);
- }
- }
-}
-
-fn get_image_quality() -> i32 {
- IMAGE_QUALITIES
- .lock()
- .unwrap()
- .values()
- .min()
- .unwrap_or(&convert_quality(ImageQuality::Balanced.value()))
- .clone()
-}
-
-#[inline]
-fn get_quality(w: usize, h: usize, q: i32) -> (u32, u32, u32, i32) {
- // https://www.nvidia.com/en-us/geforce/guides/broadcasting-guide/
- let bitrate = q >> 8 & 0xFF;
- let quantizer = q & 0xFF;
- let b = ((w * h) / 1000) as u32;
-
- #[cfg(target_os = "android")]
- {
- // fix when andorid screen shrinks
- let fix = Display::fix_quality() as u32;
- log::debug!("Android screen, fix quality:{}", fix);
- let b = b * fix;
- return (bitrate as u32 * b / 100, quantizer as _, 56, 7);
- }
-
- (bitrate as u32 * b / 100, quantizer as _, 56, 7)
-}
diff --git a/src/ui/header.tis b/src/ui/header.tis
index 4b2615a45..88ee8b6e6 100644
--- a/src/ui/header.tis
+++ b/src/ui/header.tis
@@ -159,6 +159,7 @@ class Header: Reactor.Component {
{svg_checkmark}{translate('Custom')}
{svg_checkmark}{translate('Show remote cursor')}
+ {svg_checkmark}{translate('Show quality monitor')}
{audio_enabled ? {svg_checkmark}{translate('Mute')} : ""}
{is_win && pi.platform == 'Windows' && file_enabled ? {svg_checkmark}{translate('Allow file copy and paste')} : ""}
{keyboard_enabled && clipboard_enabled ? {svg_checkmark}{translate('Disable clipboard')} : ""}
@@ -315,7 +316,9 @@ class Header: Reactor.Component {
handle_custom_image_quality();
} else if (me.id == "privacy-mode") {
togglePrivacyMode(me.id);
- } else if (me.attributes.hasClass("toggle-option")) {
+ } else if (me.id == "show-quality-monitor") {
+ toggleQualityMonitor(me.id);
+ }else if (me.attributes.hasClass("toggle-option")) {
handler.toggle_option(me.id);
toggleMenuState();
} else if (!me.attributes.hasClass("selected")) {
@@ -332,16 +335,13 @@ class Header: Reactor.Component {
}
function handle_custom_image_quality() {
- var tmp = handler.get_custom_image_quality();
- var bitrate0 = tmp[0] || 50;
- var quantizer0 = tmp.length > 1 ? tmp[1] : 100;
+ var bitrate = handler.get_custom_image_quality()[0] / 2;
msgbox("custom", "Custom Image Quality", "", function(res=null) {
if (!res) return;
if (!res.bitrate) return;
- handler.save_custom_image_quality(res.bitrate, res.quantizer);
+ handler.save_custom_image_quality(res.bitrate * 2);
toggleMenuState();
});
}
@@ -357,7 +357,7 @@ function toggleMenuState() {
for (var el in $$(menu#display-options>li)) {
el.attributes.toggleClass("selected", values.indexOf(el.id) >= 0);
}
- for (var id in ["show-remote-cursor", "disable-audio", "enable-file-transfer", "disable-clipboard", "lock-after-session-end"]) {
+ for (var id in ["show-remote-cursor", "show-quality-monitor", "disable-audio", "enable-file-transfer", "disable-clipboard", "lock-after-session-end"]) {
var el = self.select('#' + id);
if (el) {
var value = handler.get_toggle_option(id);
@@ -425,6 +425,17 @@ function togglePrivacyMode(privacy_id) {
}
}
+function toggleQualityMonitor(name) {
+ var show = handler.get_toggle_option(name);
+ if (show) {
+ $(#quality-monitor).style.set{ display: "none" };
+ } else {
+ $(#quality-monitor).style.set{ display: "block" };
+ }
+ handler.toggle_option(name);
+ toggleMenuState();
+}
+
handler.updateBlockInputState = function(input_blocked) {
if (!input_blocked) {
handler.toggle_option("block-input");
diff --git a/src/ui/remote.css b/src/ui/remote.css
index 617285e9c..66c5ce80f 100644
--- a/src/ui/remote.css
+++ b/src/ui/remote.css
@@ -9,6 +9,16 @@ div#video-wrapper {
background: #212121;
}
+div#quality-monitor {
+ top: 20px;
+ right: 20px;
+ background: #7571719c;
+ padding: 5px;
+ min-width: 150px;
+ color: azure;
+ border: solid azure;
+}
+
video#handler {
behavior: native-remote video;
size: *;
@@ -24,7 +34,7 @@ img#cursor {
}
.goup {
- transform: rotate(90deg);
+ transform: rotate(90deg);
}
table#remote-folder-view {
@@ -33,4 +43,4 @@ table#remote-folder-view {
table#local-folder-view {
context-menu: selector(menu#local-folder-view);
-}
+}
\ No newline at end of file
diff --git a/src/ui/remote.html b/src/ui/remote.html
index 32c1409e2..d58c3449b 100644
--- a/src/ui/remote.html
+++ b/src/ui/remote.html
@@ -1,12 +1,13 @@
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-