From 678a3d2d282068cf9d343fec9b09df27121a7540 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Sat, 2 Oct 2021 08:48:41 +0800 Subject: [PATCH 01/21] README format bug --- README-DE.md | 2 +- README-ES.md | 2 +- README-FR.md | 2 +- README-PL.md | 2 +- README-ZH.md | 2 +- README.md | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README-DE.md b/README-DE.md index 95d908023..d24234b85 100644 --- a/README-DE.md +++ b/README-DE.md @@ -136,7 +136,7 @@ target/release/rustdesk Bitte gehe sicher, dass du diese Befehle vom Stammverzeichnis vom RustDesk Repository nutzt, sonst kann es passieren, dass das Programm die Ressourcen nicht finden kann. Bitte bedenke auch, dass Unterbefehle von Cargo, wie z.B. `install` oder `run` aktuell noch nicht unterstützt werden, da sie das Programm innerhalb des Containers starten oder installieren würden, anstatt auf deinem eigentlichen System. -### Ändere Wayland zu X11 (Xorg) +## Ändere Wayland zu X11 (Xorg) RustDesk unterstützt "Wayland" nicht. Siehe [hier](https://docs.fedoraproject.org/en-US/quick-docs/configuring-xorg-as-default-gnome-session/) um Xorg als Standard GNOME Session zu nutzen. diff --git a/README-ES.md b/README-ES.md index 79d880287..7e7c07bb3 100644 --- a/README-ES.md +++ b/README-ES.md @@ -134,7 +134,7 @@ target/release/rustdesk Por favor, asegurate de que estás ejecutando estos comandos desde la raíz del repositorio de RustDesk, de lo contrario la aplicación puede ser incapaz de encontrar los recursos necesarios. También hay que tener en cuenta que otros subcomandos de carga como `install` o `run` no estan actualmente soportados via este metodo y podrían requerir ser instalados dentro del contenedor y no en el host. -### Cambia Wayland a X11 (Xorg) +## Cambia Wayland a X11 (Xorg) RustDesk no soporta Wayland. Comprueba [aquí](https://docs.fedoraproject.org/en-US/quick-docs/configuring-xorg-as-default-gnome-session/) para configurar Xorg en la sesión por defecto de GNOME. diff --git a/README-FR.md b/README-FR.md index 453309504..33e21783e 100644 --- a/README-FR.md +++ b/README-FR.md @@ -134,7 +134,7 @@ target/release/rustdesk Veuillez vous assurer que vous exécutez ces commandes à partir de la racine du référentiel RustDesk, sinon l'application ne pourra pas trouver les ressources requises. Notez également que les autres sous-commandes de cargo telles que `install` ou `run` ne sont pas actuellement supportées par cette méthode car elles installeraient ou exécuteraient le programme à l'intérieur du conteneur au lieu de l'hôte. -### Changer Wayland en X11 (Xorg) +## Changer Wayland en X11 (Xorg) RustDesk ne supporte pas Wayland. Lisez [cela](https://docs.fedoraproject.org/en-US/quick-docs/configuring-xorg-as-default-gnome-session/) pour configurer Xorg comme la session GNOME par défaut. diff --git a/README-PL.md b/README-PL.md index 793a1f2fb..38d786dcf 100644 --- a/README-PL.md +++ b/README-PL.md @@ -135,7 +135,7 @@ target/release/rustdesk Upewnij się, że uruchamiasz te polecenia z katalogu głównego repozytorium RustDesk, w przeciwnym razie aplikacja może nie być w stanie znaleźć wymaganych zasobów. Należy również pamiętać, że inne podpolecenia ładowania, takie jak `install` lub `run` nie są obecnie obsługiwane za pomocą tej metody, ponieważ instalowałyby lub uruchamiały program wewnątrz kontenera zamiast na hoście. -### Zmień Wayland na X11 (Xorg) +## Zmień Wayland na X11 (Xorg) RustDesk nie obsługuje Waylanda. Sprawdź [this](https://docs.fedoraproject.org/en-US/quick-docs/configuring-xorg-as-default-gnome-session/) by skonfigurować Xorg jako domyślną sesję GNOME. diff --git a/README-ZH.md b/README-ZH.md index 9382683b2..fe7405a08 100644 --- a/README-ZH.md +++ b/README-ZH.md @@ -186,7 +186,7 @@ target/release/rustdesk 请确保您从 RustDesk 存储库的根目录运行这些命令,否则应用程序可能无法找到所需的资源。另请注意,此方法当前不支持其他`Cargo`子命令, 例如 `install` 或 `run`,因为运行在容器里,而不是宿主机上。 -### 把 Wayland 修改成 X11 (Xorg) +## 把 Wayland 修改成 X11 (Xorg) RustDesk 暂时不支持 Wayland,不过正在积极开发中. 请查看[this](https://docs.fedoraproject.org/en-US/quick-docs/configuring-xorg-as-default-gnome-session/)配置 X11. diff --git a/README.md b/README.md index f6b13cd6c..60ecb829a 100644 --- a/README.md +++ b/README.md @@ -135,7 +135,7 @@ target/release/rustdesk Please ensure that you are running these commands from the root of the RustDesk repository, otherwise the application may be unable to find the required resources. Also note that other cargo subcommands such as `install` or `run` are not currently supported via this method as they would install or run the program inside the container instead of the host. -### Change Wayland to X11 (Xorg) +## Change Wayland to X11 (Xorg) RustDesk does not support Wayland. Check [this](https://docs.fedoraproject.org/en-US/quick-docs/configuring-xorg-as-default-gnome-session/) to configuring Xorg as the default GNOME session. From c0459b8f94fb05db33b9cbabd45bf7d16e376c9d Mon Sep 17 00:00:00 2001 From: rustdesk Date: Sat, 2 Oct 2021 08:51:56 +0800 Subject: [PATCH 02/21] move change wayland to linux section --- README-DE.md | 8 ++++---- README-ES.md | 8 ++++---- README-FR.md | 8 ++++---- README-PL.md | 8 ++++---- README-ZH.md | 10 +++++----- README.md | 8 ++++---- 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/README-DE.md b/README-DE.md index d24234b85..8ab4cc9cf 100644 --- a/README-DE.md +++ b/README-DE.md @@ -106,6 +106,10 @@ mv libsciter-gtk.so target/debug cargo run ``` +### Ändere Wayland zu X11 (Xorg) + +RustDesk unterstützt "Wayland" nicht. Siehe [hier](https://docs.fedoraproject.org/en-US/quick-docs/configuring-xorg-as-default-gnome-session/) um Xorg als Standard GNOME Session zu nutzen. + ## Auf Docker Kompilieren Beginne damit das Repository zu klonen und den Docker Container zu bauen: @@ -136,10 +140,6 @@ target/release/rustdesk Bitte gehe sicher, dass du diese Befehle vom Stammverzeichnis vom RustDesk Repository nutzt, sonst kann es passieren, dass das Programm die Ressourcen nicht finden kann. Bitte bedenke auch, dass Unterbefehle von Cargo, wie z.B. `install` oder `run` aktuell noch nicht unterstützt werden, da sie das Programm innerhalb des Containers starten oder installieren würden, anstatt auf deinem eigentlichen System. -## Ändere Wayland zu X11 (Xorg) - -RustDesk unterstützt "Wayland" nicht. Siehe [hier](https://docs.fedoraproject.org/en-US/quick-docs/configuring-xorg-as-default-gnome-session/) um Xorg als Standard GNOME Session zu nutzen. - ## Dateistruktur - **[libs/hbb_common](https://github.com/rustdesk/rustdesk/tree/master/libs/hbb_common)**: Video Codec, Konfiguration, TCP/UDP Wrapper, Protokoll Puffer, fs Funktionen für Dateitransfer, und ein paar andere nützliche Funktionen diff --git a/README-ES.md b/README-ES.md index 7e7c07bb3..087be2ee6 100644 --- a/README-ES.md +++ b/README-ES.md @@ -104,6 +104,10 @@ mv libsciter-gtk.so target/debug cargo run ``` +### Cambia Wayland a X11 (Xorg) + +RustDesk no soporta Wayland. Comprueba [aquí](https://docs.fedoraproject.org/en-US/quick-docs/configuring-xorg-as-default-gnome-session/) para configurar Xorg en la sesión por defecto de GNOME. + ## Como compilar con Docker Empieza clonando el repositorio y compilando el contenedor de docker: @@ -134,10 +138,6 @@ target/release/rustdesk Por favor, asegurate de que estás ejecutando estos comandos desde la raíz del repositorio de RustDesk, de lo contrario la aplicación puede ser incapaz de encontrar los recursos necesarios. También hay que tener en cuenta que otros subcomandos de carga como `install` o `run` no estan actualmente soportados via este metodo y podrían requerir ser instalados dentro del contenedor y no en el host. -## Cambia Wayland a X11 (Xorg) - -RustDesk no soporta Wayland. Comprueba [aquí](https://docs.fedoraproject.org/en-US/quick-docs/configuring-xorg-as-default-gnome-session/) para configurar Xorg en la sesión por defecto de GNOME. - ## Estructura de archivos - **[libs/hbb_common](https://github.com/rustdesk/rustdesk/tree/master/libs/hbb_common)**: video codec, configuración, tcp/udp wrapper, protobuf, fs funciones para transferencia de ficheros, y alguna función de utilidad. diff --git a/README-FR.md b/README-FR.md index 33e21783e..611c66961 100644 --- a/README-FR.md +++ b/README-FR.md @@ -104,6 +104,10 @@ mv libsciter-gtk.so target/debug Exécution du cargo ``` +### Changer Wayland en X11 (Xorg) + +RustDesk ne supporte pas Wayland. Lisez [cela](https://docs.fedoraproject.org/en-US/quick-docs/configuring-xorg-as-default-gnome-session/) pour configurer Xorg comme la session GNOME par défaut. + ## Comment construire avec Docker Commencez par cloner le dépôt et construire le conteneur Docker : @@ -134,10 +138,6 @@ target/release/rustdesk Veuillez vous assurer que vous exécutez ces commandes à partir de la racine du référentiel RustDesk, sinon l'application ne pourra pas trouver les ressources requises. Notez également que les autres sous-commandes de cargo telles que `install` ou `run` ne sont pas actuellement supportées par cette méthode car elles installeraient ou exécuteraient le programme à l'intérieur du conteneur au lieu de l'hôte. -## Changer Wayland en X11 (Xorg) - -RustDesk ne supporte pas Wayland. Lisez [cela](https://docs.fedoraproject.org/en-US/quick-docs/configuring-xorg-as-default-gnome-session/) pour configurer Xorg comme la session GNOME par défaut. - ## Structure du projet - **[libs/hbb_common](https://github.com/rustdesk/rustdesk/tree/master/libs/hbb_common)** : codec vidéo, config, wrapper tcp/udp, protobuf, fonctions fs pour le transfert de fichiers, et quelques autres fonctions utilitaires. diff --git a/README-PL.md b/README-PL.md index 38d786dcf..5291d50c7 100644 --- a/README-PL.md +++ b/README-PL.md @@ -105,6 +105,10 @@ mv libsciter-gtk.so target/debug cargo run ``` +### Zmień Wayland na X11 (Xorg) + +RustDesk nie obsługuje Waylanda. Sprawdź [this](https://docs.fedoraproject.org/en-US/quick-docs/configuring-xorg-as-default-gnome-session/) by skonfigurować Xorg jako domyślną sesję GNOME. + ## Jak kompilować za pomocą Dockera Rozpocznij od sklonowania repozytorium i stworzenia kontenera docker: @@ -135,10 +139,6 @@ target/release/rustdesk Upewnij się, że uruchamiasz te polecenia z katalogu głównego repozytorium RustDesk, w przeciwnym razie aplikacja może nie być w stanie znaleźć wymaganych zasobów. Należy również pamiętać, że inne podpolecenia ładowania, takie jak `install` lub `run` nie są obecnie obsługiwane za pomocą tej metody, ponieważ instalowałyby lub uruchamiały program wewnątrz kontenera zamiast na hoście. -## Zmień Wayland na X11 (Xorg) - -RustDesk nie obsługuje Waylanda. Sprawdź [this](https://docs.fedoraproject.org/en-US/quick-docs/configuring-xorg-as-default-gnome-session/) by skonfigurować Xorg jako domyślną sesję GNOME. - ## Struktura plików - **[libs/hbb_common](https://github.com/rustdesk/rustdesk/tree/master/libs/hbb_common)**: kodek wideo, config, wrapper tcp/udp, protobuf, funkcje fs do transferu plików i kilka innych funkcji użytkowych diff --git a/README-ZH.md b/README-ZH.md index fe7405a08..1ffdb5159 100644 --- a/README-ZH.md +++ b/README-ZH.md @@ -105,6 +105,11 @@ mv libsciter-gtk.so target/debug cargo run ``` +### 把 Wayland 修改成 X11 (Xorg) + +RustDesk 暂时不支持 Wayland,不过正在积极开发中. +请查看[this](https://docs.fedoraproject.org/en-US/quick-docs/configuring-xorg-as-default-gnome-session/)配置 X11. + ## 使用 Docker 编译 首先克隆存储库并构建 docker 容器: @@ -186,11 +191,6 @@ target/release/rustdesk 请确保您从 RustDesk 存储库的根目录运行这些命令,否则应用程序可能无法找到所需的资源。另请注意,此方法当前不支持其他`Cargo`子命令, 例如 `install` 或 `run`,因为运行在容器里,而不是宿主机上。 -## 把 Wayland 修改成 X11 (Xorg) - -RustDesk 暂时不支持 Wayland,不过正在积极开发中. -请查看[this](https://docs.fedoraproject.org/en-US/quick-docs/configuring-xorg-as-default-gnome-session/)配置 X11. - ## 文件结构 - **[libs/hbb_common](https://github.com/rustdesk/rustdesk/tree/master/libs/hbb_common)**: 视频编解码, 配置, tcp/udp 封装, protobuf, 文件传输相关文件系统操作函数, 以及一些其他实用函数 diff --git a/README.md b/README.md index 60ecb829a..f9cd7e6d8 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,10 @@ mv libsciter-gtk.so target/debug VCPKG_ROOT=$HOME/vcpkg cargo run ``` +### Change Wayland to X11 (Xorg) + +RustDesk does not support Wayland. Check [this](https://docs.fedoraproject.org/en-US/quick-docs/configuring-xorg-as-default-gnome-session/) to configuring Xorg as the default GNOME session. + ## How to build with Docker Begin by cloning the repository and building the docker container: @@ -135,10 +139,6 @@ target/release/rustdesk Please ensure that you are running these commands from the root of the RustDesk repository, otherwise the application may be unable to find the required resources. Also note that other cargo subcommands such as `install` or `run` are not currently supported via this method as they would install or run the program inside the container instead of the host. -## Change Wayland to X11 (Xorg) - -RustDesk does not support Wayland. Check [this](https://docs.fedoraproject.org/en-US/quick-docs/configuring-xorg-as-default-gnome-session/) to configuring Xorg as the default GNOME session. - ## File Structure - **[libs/hbb_common](https://github.com/rustdesk/rustdesk/tree/master/libs/hbb_common)**: video codec, config, tcp/udp wrapper, protobuf, fs functions for file transfer, and some other utility functions From c0db2e6da4456fe05e5e23cee75cdd622ba286f6 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Fri, 8 Oct 2021 00:16:10 +0800 Subject: [PATCH 03/21] refactor and fix --- src/ui.rs | 13 +++++++++++++ src/ui/index.tis | 27 ++++++++++----------------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/ui.rs b/src/ui.rs index ca6fbd950..b7cacf197 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -333,9 +333,21 @@ impl UI { } } } + + *self.2.lock().unwrap() = m.clone(); ipc::set_options(m).ok(); } + fn set_option(&self, key: String, value: String) { + let mut options = self.2.lock().unwrap(); + if value.is_empty() { + options.remove(&key); + } else { + options.insert(key, value); + } + ipc::set_options(options.clone()).ok(); + } + fn install_path(&mut self) -> String { #[cfg(windows)] return crate::platform::windows::get_install_info().1; @@ -587,6 +599,7 @@ impl sciter::EventHandler for UI { fn test_if_valid_server(String); fn get_sound_inputs(); fn set_options(Value); + fn set_option(String, String); fn get_software_update_url(); fn get_new_version(); fn get_version(); diff --git a/src/ui/index.tis b/src/ui/index.tis index ea48bacdc..55fcf6f7c 100644 --- a/src/ui/index.tis +++ b/src/ui/index.tis @@ -40,9 +40,7 @@ class ConnectStatus: Reactor.Component { } event click $(.connect-status .link) () { - var options = handler.get_options(); - options["stop-service"] = ""; - handler.set_options(options); + handler.set_option("stop-service", ""); } } @@ -138,7 +136,6 @@ function createNewConnect(id, type) { var myIdMenu; var audioInputMenu; -var configOptions = {}; class AudioInputs: Reactor.Component { function this() { audioInputMenu = this; @@ -167,7 +164,7 @@ class AudioInputs: Reactor.Component { } function get_value() { - return configOptions["audio-input"] || this.get_default(); + return handler.get_option("audio-input") || this.get_default(); } function toggleMenuState() { @@ -182,8 +179,7 @@ class AudioInputs: Reactor.Component { var v = me.id; if (v == this.get_value()) return; if (v == this.get_default()) v = ""; - configOptions["audio-input"] = v; - handler.set_options(configOptions); + handler.set_option("audio-input", v); this.toggleMenuState(); } } @@ -223,7 +219,6 @@ class MyIdMenu: Reactor.Component { event click $(svg#menu) (_, me) { audioInputMenu.update({ show: true }); - configOptions = handler.get_options(); this.toggleMenuState(); var menu = $(menu#config-options); me.popup(menu); @@ -232,7 +227,7 @@ class MyIdMenu: Reactor.Component { function toggleMenuState() { for (var el in $$(menu#config-options>li)) { if (el.id && el.id.indexOf("enable-") == 0) { - var enabled = configOptions[el.id] != "N"; + var enabled = handler.get_option(el.id) != "N"; el.attributes.toggleClass("selected", enabled); el.attributes.toggleClass("line-through", !enabled); } @@ -241,11 +236,10 @@ class MyIdMenu: Reactor.Component { event click $(menu#config-options>li) (_, me) { if (me.id && me.id.indexOf("enable-") == 0) { - configOptions[me.id] = configOptions[me.id] == "N" ? "" : "N"; - handler.set_options(configOptions); + handler.set_option(me.id, handler.get_option(me.id) == "N" ? "" : "N"); } if (me.id == "whitelist") { - var old_value = (configOptions["whitelist"] || "").split(",").join("\n"); + var old_value = handler.get_option("whitelist").split(",").join("\n"); handler.msgbox("custom-whitelist", "IP Whitelisting", "
\ \
\ @@ -253,7 +247,7 @@ class MyIdMenu: Reactor.Component { if (!res) return; var value = (res.text || "").trim(); if (value) { - var values = value.split(/[\s,;]+/g); + var values = value.split(/[\s,;\n]+/g); for (var ip in values) { if (!ip.match(/^\d+\.\d+\.\d+\.\d+$/)) { return "Invalid ip: " + ip; @@ -262,11 +256,11 @@ class MyIdMenu: Reactor.Component { value = values.join("\n"); } if (value == old_value) return; - configOptions["whitelist"] = value.replace("\n", ","); stdout.println("whitelist updated"); - handler.set_options(configOptions); + handler.set_option("whitelist", value.replace("\n", ",")); }, 300); } else if (me.id == "custom-server") { + var configOptions = handler.get_options(); var old_relay = configOptions["relay-server"] || ""; var old_id = configOptions["custom-rendezvous-server"] || ""; handler.msgbox("custom-server", "ID/Relay Server", "
\ @@ -293,8 +287,7 @@ class MyIdMenu: Reactor.Component { } else if (me.id == "forum") { handler.open_url("https:://forum.rustdesk.com"); } else if (me.id == "stop-service") { - configOptions["stop-service"] = service_stopped ? "" : "Y"; - handler.set_options(configOptions); + handler.set_option("stop-service", service_stopped ? "" : "Y"); } else if (me.id == "about") { var name = handler.get_app_name(); handler.msgbox("custom-nocancel-nook-hasclose", "About " + name, "
\ From 686e49517100d33225604b575f4b6ee3803a5da3 Mon Sep 17 00:00:00 2001 From: Tom Parker-Shemilt Date: Mon, 11 Oct 2021 21:36:45 +0100 Subject: [PATCH 04/21] Initial CI setup --- .github/workflows/ci.yml | 169 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..3561c5ba0 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,169 @@ +name: CI + +# env: +# MIN_SUPPORTED_RUST_VERSION: "1.46.0" +# CICD_INTERMEDIATES_DIR: "_cicd-intermediates" + +on: + workflow_dispatch: + pull_request: + push: + branches: + - master + tags: + - '*' + +jobs: + # ensure_cargo_fmt: + # name: Ensure 'cargo fmt' has been run + # runs-on: ubuntu-20.04 + # steps: + # - uses: actions-rs/toolchain@v1 + # with: + # toolchain: stable + # default: true + # profile: minimal + # components: rustfmt + # - uses: actions/checkout@v2 + # - run: cargo fmt -- --check + + # min_version: + # name: Minimum supported rust version + # runs-on: ubuntu-20.04 + # steps: + # - name: Checkout source code + # uses: actions/checkout@v2 + + # - name: Install rust toolchain (v${{ env.MIN_SUPPORTED_RUST_VERSION }}) + # uses: actions-rs/toolchain@v1 + # with: + # toolchain: ${{ env.MIN_SUPPORTED_RUST_VERSION }} + # default: true + # profile: minimal # minimal component installation (ie, no documentation) + # components: clippy + # - name: Run clippy (on minimum supported rust version to prevent warnings we can't fix) + # uses: actions-rs/cargo@v1 + # with: + # command: clippy + # args: --locked --all-targets --all-features -- --allow clippy::unknown_clippy_lints + # - name: Run tests + # uses: actions-rs/cargo@v1 + # with: + # command: test + # args: --locked + + build: + name: ${{ matrix.job.target }} (${{ matrix.job.os }}) + runs-on: ${{ matrix.job.os }} + strategy: + fail-fast: false + matrix: + job: + # - { target: aarch64-unknown-linux-gnu , os: ubuntu-20.04, use-cross: true } + # - { target: arm-unknown-linux-gnueabihf , os: ubuntu-20.04, use-cross: true } + # - { target: arm-unknown-linux-musleabihf, os: ubuntu-20.04, use-cross: true } + # - { target: i686-pc-windows-msvc , os: windows-2019 } + # - { target: i686-unknown-linux-gnu , os: ubuntu-20.04, use-cross: true } + # - { target: i686-unknown-linux-musl , os: ubuntu-20.04, use-cross: true } + # - { target: x86_64-apple-darwin , os: macos-10.15 } + # - { target: x86_64-pc-windows-gnu , os: windows-2019 } + # - { target: x86_64-pc-windows-msvc , os: windows-2019 } + - { target: x86_64-unknown-linux-gnu , os: ubuntu-20.04 } + # - { target: x86_64-unknown-linux-musl , os: ubuntu-20.04, use-cross: true } + steps: + - name: Checkout source code + uses: actions/checkout@v2 + + - name: Install prerequisites + shell: bash + run: | + case ${{ matrix.job.target }} in + x86_64-unknown-linux-gnu) 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 ;; + # arm-unknown-linux-*) sudo apt-get -y update ; sudo apt-get -y install gcc-arm-linux-gnueabihf ;; + # aarch64-unknown-linux-gnu) sudo apt-get -y update ; sudo apt-get -y install gcc-aarch64-linux-gnu ;; + esac + + - name: Restore from cache and install vcpkg + uses: lukka/run-vcpkg@v7 + with: + setupOnly: true + - run: | + $VCPKG_ROOT/vcpkg install libvpx libyuv opus + shell: bash + + - name: Install Rust toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + target: ${{ matrix.job.target }} + override: true + profile: minimal # minimal component installation (ie, no documentation) + + - name: Show version information (Rust, cargo, GCC) + shell: bash + run: | + gcc --version || true + rustup -V + rustup toolchain list + rustup default + cargo -V + rustc -V + + - name: Build + uses: actions-rs/cargo@v1 + with: + use-cross: ${{ matrix.job.use-cross }} + command: build + args: --locked --release --target=${{ matrix.job.target }} + + # - name: Strip debug information from executable + # id: strip + # shell: bash + # run: | + # # Figure out suffix of binary + # EXE_suffix="" + # case ${{ matrix.job.target }} in + # *-pc-windows-*) EXE_suffix=".exe" ;; + # esac; + + # # Figure out what strip tool to use if any + # STRIP="strip" + # case ${{ matrix.job.target }} in + # arm-unknown-linux-*) STRIP="arm-linux-gnueabihf-strip" ;; + # aarch64-unknown-linux-gnu) STRIP="aarch64-linux-gnu-strip" ;; + # *-pc-windows-msvc) STRIP="" ;; + # esac; + + # # Setup paths + # BIN_DIR="${{ env.CICD_INTERMEDIATES_DIR }}/stripped-release-bin/" + # mkdir -p "${BIN_DIR}" + # BIN_NAME="${{ env.PROJECT_NAME }}${EXE_suffix}" + # BIN_PATH="${BIN_DIR}/${BIN_NAME}" + + # # Copy the release build binary to the result location + # cp "target/${{ matrix.job.target }}/release/${BIN_NAME}" "${BIN_DIR}" + + # # Also strip if possible + # if [ -n "${STRIP}" ]; then + # "${STRIP}" "${BIN_PATH}" + # fi + + # # Let subsequent steps know where to find the (stripped) bin + # echo ::set-output name=BIN_PATH::${BIN_PATH} + # echo ::set-output name=BIN_NAME::${BIN_NAME} + + - name: Set testing options + id: test-options + shell: bash + run: | + # test only library unit tests and binary for arm-type targets + unset CARGO_TEST_OPTIONS + unset CARGO_TEST_OPTIONS ; case ${{ matrix.job.target }} in arm-* | aarch64-*) CARGO_TEST_OPTIONS="--lib --bin ${PROJECT_NAME}" ;; esac; + echo ::set-output name=CARGO_TEST_OPTIONS::${CARGO_TEST_OPTIONS} + + - name: Run tests + uses: actions-rs/cargo@v1 + with: + use-cross: ${{ matrix.job.use-cross }} + command: test + args: --locked --target=${{ matrix.job.target }} ${{ steps.test-options.outputs.CARGO_TEST_OPTIONS}} \ No newline at end of file From 0ef424636065dca64983d48c0d1b325b78833654 Mon Sep 17 00:00:00 2001 From: Tom Parker-Shemilt Date: Mon, 11 Oct 2021 21:40:06 +0100 Subject: [PATCH 05/21] Set vcpkg commit id --- .github/workflows/ci.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3561c5ba0..1d21d7818 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -87,7 +87,10 @@ jobs: uses: lukka/run-vcpkg@v7 with: setupOnly: true - - run: | + vcpkgGitCommitId: '1d4128f08e30cec31b94500840c7eca8ebc579cb' + + - name: Install vcpkg dependencies + run: | $VCPKG_ROOT/vcpkg install libvpx libyuv opus shell: bash From 7a7cca7e450d38435cd4467cd13152db5b8daca5 Mon Sep 17 00:00:00 2001 From: Tom Parker-Shemilt Date: Mon, 11 Oct 2021 21:48:56 +0100 Subject: [PATCH 06/21] Add rust cache --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1d21d7818..cfa7333e5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -112,6 +112,8 @@ jobs: cargo -V rustc -V + - uses: Swatinem/rust-cache@v1 + - name: Build uses: actions-rs/cargo@v1 with: From d25e17317da6b724c95160add78db0dc139fed55 Mon Sep 17 00:00:00 2001 From: Tom Parker-Shemilt Date: Mon, 11 Oct 2021 22:09:13 +0100 Subject: [PATCH 07/21] Skip tests for the moment --- .github/workflows/ci.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cfa7333e5..b945df652 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -166,9 +166,9 @@ jobs: unset CARGO_TEST_OPTIONS ; case ${{ matrix.job.target }} in arm-* | aarch64-*) CARGO_TEST_OPTIONS="--lib --bin ${PROJECT_NAME}" ;; esac; echo ::set-output name=CARGO_TEST_OPTIONS::${CARGO_TEST_OPTIONS} - - name: Run tests - uses: actions-rs/cargo@v1 - with: - use-cross: ${{ matrix.job.use-cross }} - command: test - args: --locked --target=${{ matrix.job.target }} ${{ steps.test-options.outputs.CARGO_TEST_OPTIONS}} \ No newline at end of file + # - name: Run tests + # uses: actions-rs/cargo@v1 + # with: + # use-cross: ${{ matrix.job.use-cross }} + # command: test + # args: --locked --target=${{ matrix.job.target }} ${{ steps.test-options.outputs.CARGO_TEST_OPTIONS}} \ No newline at end of file From 55d21ab151b9d892fe21d431c28ea39243ec678c Mon Sep 17 00:00:00 2001 From: Tom Parker-Shemilt Date: Mon, 11 Oct 2021 22:35:31 +0100 Subject: [PATCH 08/21] Just build the tests --- .github/workflows/ci.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b945df652..d9cfdbc9b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -166,6 +166,13 @@ jobs: unset CARGO_TEST_OPTIONS ; case ${{ matrix.job.target }} in arm-* | aarch64-*) CARGO_TEST_OPTIONS="--lib --bin ${PROJECT_NAME}" ;; esac; echo ::set-output name=CARGO_TEST_OPTIONS::${CARGO_TEST_OPTIONS} + - name: Build tests + uses: actions-rs/cargo@v1 + with: + use-cross: ${{ matrix.job.use-cross }} + command: build + args: --locked --tests --target=${{ matrix.job.target }} + # - name: Run tests # uses: actions-rs/cargo@v1 # with: From eea85b9b5add642d9c3ecec043bd4c4f0dc8208a Mon Sep 17 00:00:00 2001 From: Starccy <452276725@qq.com> Date: Sun, 17 Oct 2021 21:27:10 +0800 Subject: [PATCH 09/21] send & receive multiple files --- src/ui/file_transfer.css | 10 ++++++++++ src/ui/file_transfer.tis | 32 ++++++++++++++++++++++++++++---- src/ui/grid.tis | 5 +++++ 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/ui/file_transfer.css b/src/ui/file_transfer.css index 8acde0623..d1e1a4072 100644 --- a/src/ui/file_transfer.css +++ b/src/ui/file_transfer.css @@ -30,6 +30,7 @@ table > thead { } table > tbody { + behavior: select-multiple; overflow-y: scroll-indicator; size: *; background: white; @@ -85,6 +86,15 @@ table.has_current tr:current /* current row */ background-color: color(accent); } +table.has_current tbody tr:checked +{ + background-color: color(accent); +} + +table.has_current tbody tr:checked td { + color: highlighttext; +} + table td { padding: 4px; diff --git a/src/ui/file_transfer.tis b/src/ui/file_transfer.tis index da980d3cd..700efbdd2 100644 --- a/src/ui/file_transfer.tis +++ b/src/ui/file_transfer.tis @@ -25,6 +25,12 @@ var svg_computer = ; +const TYPE_DIR = 1; +const TYPE_DIR_LINK = 2; +const TYPE_DIR_DRIVE = 3; +const TYPE_FILE = 4; +const TYPE_FILE_LINK = 5; + function getSize(type, size) { if (!size) { if (type <= 3) return ""; @@ -374,7 +380,7 @@ class FolderView : Reactor.Component { path = this.joinPath(entry.name); } var tm = entry.time ? new Date(entry.time.toFloat() * 1000.).toLocaleString() : 0; - return + return {entry.name} {tm || ""} @@ -463,10 +469,28 @@ class FolderView : Reactor.Component { return [this.joinPath(name), type]; } + function getCurrentRows() { + var rows = this.table.getCurrentRows(); + if (!rows || rows.length== 0) return; + + var records = new Array(); + + for (var i = 0; i < rows.length; ++i) { + var name = rows[i][1].text; + if (!name || name == "..") continue; + + var type = rows[i][0].attributes["type"]; + records.push([this.joinPath(name), type]); + } + return records; + } + event click $(.send) () { - var cur = this.getCurrentRow(); - if (!cur) return; - file_transfer.job_table.send(cur[0], this.is_remote); + var rows = this.getCurrentRows(); + if (!rows || rows.length == 0) return; + for (var i = 0; i < rows.length; ++i) { + file_transfer.job_table.send(rows[i][0], this.is_remote); + } } event change $(.select-dir) (_, el) { diff --git a/src/ui/grid.tis b/src/ui/grid.tis index cb5932678..f33b4ef35 100644 --- a/src/ui/grid.tis +++ b/src/ui/grid.tis @@ -24,6 +24,11 @@ class Grid: Behavior { { return this.$(tbody>tr:current); } + + function getCurrentRows() + { + return this.$$(tbody>tr:checked); + } function getCurrentColumn() { From fb126164ef6b4f1f30a4b46f17abdc253c55eb2c Mon Sep 17 00:00:00 2001 From: Starccy <452276725@qq.com> Date: Sun, 17 Oct 2021 21:50:34 +0800 Subject: [PATCH 10/21] use multiple jobs to delete --- src/ui/common.tis | 4 ++++ src/ui/file_transfer.tis | 41 +++++++++++++++++++++++++--------------- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/ui/common.tis b/src/ui/common.tis index 316def2d4..6af29ab02 100644 --- a/src/ui/common.tis +++ b/src/ui/common.tis @@ -257,6 +257,10 @@ handler.msgbox = function(type, title, text, callback=null, height=180, width=50 self.timer(150ms, function() { msgbox(type, title, text, callback, height, width, retry); }); } +handler.block_msgbox = function(type, title, text, callback=null, height=180, width=500, retry=0) { + msgbox(type, title, text, callback, height, width, retry); +} + var reconnectTimeout = 1; handler.msgbox_retry = function(type, title, text, hasRetry, callback=null, height=180, width=500) { handler.msgbox(type, title, text, callback, height, width, hasRetry ? reconnectTimeout : 0); diff --git a/src/ui/file_transfer.tis b/src/ui/file_transfer.tis index 700efbdd2..74eaf2b69 100644 --- a/src/ui/file_transfer.tis +++ b/src/ui/file_transfer.tis @@ -407,20 +407,31 @@ class FolderView : Reactor.Component { } event click $(.trash) () { - var row = this.getCurrentRow(); - if (!row) return; - var path = row[0]; - var type = row[1]; - var new_history = []; - for (var i = 0; i < this.history.length; ++i) { - var h = this.history[i]; - if ((h + this.sep()).indexOf(path + this.sep()) == -1) new_history.push(h); + var rows = this.getCurrentRows(); + if (!rows || rows.length == 0) return; + + var delete_dirs = new Array(); + + for (var i = 0; i < rows.length; ++i) { + var row = rows[i]; + + var path = row[0]; + var type = row[1]; + + var new_history = []; + for (var j = 0; j < this.history.length; ++j) { + var h = this.history[j]; + if ((h + this.sep()).indexOf(path + this.sep()) == -1) new_history.push(h); + } + this.history = new_history; + if (type == 1) { + delete_dirs.push(path); + } else { + confirmDelete(path, this.is_remote); + } } - this.history = new_history; - if (type == 1) { - file_transfer.job_table.addDelDir(path, this.is_remote); - } else { - confirmDelete(path, this.is_remote); + for (var i = 0; i < delete_dirs.length; ++i) { + file_transfer.job_table.addDelDir(delete_dirs[i], this.is_remote); } } @@ -594,7 +605,7 @@ var deleting_single_file_jobs = {}; var create_dir_jobs = {} function confirmDelete(path, is_remote) { - handler.msgbox("custom-skip", "Confirm Delete", "
\ + handler.block_msgbox("custom-skip", "Confirm Delete", "
\
Are you sure you want to delete this file?
\ " + path + "
\
", function(res=null) { @@ -614,7 +625,7 @@ handler.confirmDeleteFiles = function(id, i, name) { if (i >= n) return; var file_path = job.path; if (name) file_path += handler.get_path_sep(job.is_remote) + name; - handler.msgbox("custom-skip", "Confirm Delete", "
\ + handler.block_msgbox("custom-skip", "Confirm Delete", "
\
Deleting #" + (i + 1) + " of " + n + " files.
\
Are you sure you want to delete this file?
\ " + name + "
\ From 8be912a8cf6fe138db724e3f3332bdad4f2d5dbe Mon Sep 17 00:00:00 2001 From: dannkunt <32395839+dannkunt@users.noreply.github.com> Date: Wed, 20 Oct 2021 08:35:52 +0300 Subject: [PATCH 11/21] Add user privelege To fix this --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index b8c320b44..94d713f6f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,7 @@ RUN git clone https://github.com/microsoft/vcpkg && cd vcpkg && git checkout 134 RUN /vcpkg/bootstrap-vcpkg.sh -disableMetrics RUN /vcpkg/vcpkg --disable-metrics install libvpx libyuv opus -RUN groupadd -r user && useradd -r -g user user --home /home/user && mkdir -p /home/user && chown user /home/user +RUN groupadd -r user && useradd -r -g user user --home /home/user && mkdir -p /home/user && chown user /home/user && echo "user ALL=(ALL) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/user WORKDIR /home/user RUN wget https://raw.githubusercontent.com/c-smile/sciter-sdk/master/bin.lnx/x64/libsciter-gtk.so USER user From 0db250f02a3e3649f33e5da1f3d4111eb8c33e68 Mon Sep 17 00:00:00 2001 From: dannkunt <32395839+dannkunt@users.noreply.github.com> Date: Wed, 20 Oct 2021 08:38:36 +0300 Subject: [PATCH 12/21] Delete this code This code is unnessesary and bug casing with previous fix --- entrypoint | 8 -------- 1 file changed, 8 deletions(-) diff --git a/entrypoint b/entrypoint index 75b9efd18..514de9b9d 100755 --- a/entrypoint +++ b/entrypoint @@ -1,13 +1,5 @@ #!/bin/sh -if [ "$(id -u)" != "${PUID:-1000}" ] || [ "$(id -g)" != "${PGID:-1000}" ]; then - usermod -o -u "${PUID:-1000}" user - groupmod -o -g "${PGID:-1000}" user - chown -R user /home/user - sudo -u user /entrypoint $@ - exit 0 -fi - cd $HOME/rustdesk . $HOME/.cargo/env From 1ddd5203e58ac2f8ee0dd5e58b10bf8d3eb39be0 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Wed, 20 Oct 2021 17:03:48 +0800 Subject: [PATCH 13/21] fix overflow --- src/common.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/common.rs b/src/common.rs index f67751236..e5a7e4f99 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1,6 +1,6 @@ pub use arboard::Clipboard as ClipboardContext; use hbb_common::{ - allow_err, + allow_err, bail, compress::{compress as compress_func, decompress}, config::{Config, COMPRESS_LEVEL, RENDEZVOUS_TIMEOUT}, log, @@ -240,6 +240,10 @@ async fn test_nat_type_() -> ResultType { let rendezvous_server = get_rendezvous_server(100).await; let server1 = rendezvous_server; let mut server2 = server1; + if server1.port() == 0 { // offline + // avoid overflow crash + bail!("Offline"); + } server2.set_port(server1.port() - 1); let mut msg_out = RendezvousMessage::new(); let serial = Config::get_serial(); From 8f222737592d8438562cee4f6d8df75825a3df49 Mon Sep 17 00:00:00 2001 From: RustDesk <71636191+rustdesk@users.noreply.github.com> Date: Thu, 21 Oct 2021 10:00:53 +0800 Subject: [PATCH 14/21] Update ci.yml --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d9cfdbc9b..cd8282187 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -78,7 +78,7 @@ jobs: shell: bash run: | case ${{ matrix.job.target }} in - x86_64-unknown-linux-gnu) 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 ;; + x86_64-unknown-linux-gnu) sudo apt-get -y update ; 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 ;; # arm-unknown-linux-*) sudo apt-get -y update ; sudo apt-get -y install gcc-arm-linux-gnueabihf ;; # aarch64-unknown-linux-gnu) sudo apt-get -y update ; sudo apt-get -y install gcc-aarch64-linux-gnu ;; esac @@ -178,4 +178,4 @@ jobs: # with: # use-cross: ${{ matrix.job.use-cross }} # command: test - # args: --locked --target=${{ matrix.job.target }} ${{ steps.test-options.outputs.CARGO_TEST_OPTIONS}} \ No newline at end of file + # args: --locked --target=${{ matrix.job.target }} ${{ steps.test-options.outputs.CARGO_TEST_OPTIONS}} From 1bf80e3dd6f1fb39ac2e1599beffdd3b8ed4b214 Mon Sep 17 00:00:00 2001 From: cc-morning <90960002+cc-morning@users.noreply.github.com> Date: Fri, 22 Oct 2021 16:02:01 +0800 Subject: [PATCH 15/21] Optimize clipboard change listener --- Cargo.lock | 43 +++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/server/clipboard_service.rs | 22 ++++++++++++++++- src/server/service.rs | 34 ++++++++++++++++++++++++++ 4 files changed, 99 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index c3e139e8e..359e344bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -352,6 +352,20 @@ dependencies = [ "vec_map", ] +[[package]] +name = "clipboard-master" +version = "3.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd1cb2f0df685eb4a61c656faeb6ef391ad776943d3723afb12bdcbceff824d" +dependencies = [ + "objc", + "objc-foundation", + "objc_id", + "winapi 0.3.9", + "windows-win", + "x11-clipboard", +] + [[package]] name = "clipboard-win" version = "4.2.1" @@ -2860,6 +2874,7 @@ dependencies = [ "cc", "cfg-if 1.0.0", "clap", + "clipboard-master", "cocoa", "core-foundation 0.9.1", "core-graphics", @@ -3771,6 +3786,15 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "windows-win" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d4243ec23afe4e9b4e668b3c0a0e973f1b8265f6a46223cfcbc16fd267480c0" +dependencies = [ + "winapi 0.3.9", +] + [[package]] name = "winreg" version = "0.6.2" @@ -3814,6 +3838,15 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" +[[package]] +name = "x11-clipboard" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b397ace6e980510de59a4fe3d4c758dffab231d6d747ce9fa1aba6b6035d5f32" +dependencies = [ + "xcb", +] + [[package]] name = "x11rb" version = "0.8.1" @@ -3826,6 +3859,16 @@ dependencies = [ "winapi-wsapoll", ] +[[package]] +name = "xcb" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62056f63138b39116f82a540c983cc11f1c90cd70b3d492a70c25eaa50bd22a6" +dependencies = [ + "libc", + "log", +] + [[package]] name = "yansi" version = "0.5.0" diff --git a/Cargo.toml b/Cargo.toml index 75504a06f..b4b8ad48c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,7 @@ mac_address = "1.1" sciter-rs = { git = "https://github.com/open-trade/rust-sciter", branch = "dyn" } ctrlc = "3.2" arboard = "2.0" +clipboard-master = "3" [target.'cfg(target_os = "windows")'.dependencies] #systray = { git = "https://github.com/open-trade/systray-rs" } diff --git a/src/server/clipboard_service.rs b/src/server/clipboard_service.rs index 25597d11c..3e94d2824 100644 --- a/src/server/clipboard_service.rs +++ b/src/server/clipboard_service.rs @@ -1,3 +1,7 @@ +use std::sync::mpsc::Sender; + +use clipboard_master::{CallbackResult, ClipboardHandler, Master}; + use super::*; pub use crate::common::{ check_clipboard, ClipboardContext, CLIPBOARD_INTERVAL as INTERVAL, CLIPBOARD_NAME as NAME, @@ -27,12 +31,28 @@ impl super::service::Reset for State { } } +struct ClipHandle { + tx: Sender, +} + +impl ClipboardHandler for ClipHandle { + fn on_clipboard_change(&mut self) -> CallbackResult { + let _ = self.tx.send(true); + CallbackResult::Next + } +} + pub fn new() -> GenericService { let sp = GenericService::new(NAME, true); - sp.repeat::(INTERVAL, run); + sp.listen::(notify, run); sp } +fn notify(tx: Sender) -> ResultType<()> { + Master::new(ClipHandle { tx }).run()?; + Ok(()) +} + fn run(sp: GenericService, state: &mut State) -> ResultType<()> { if let Some(ctx) = state.ctx.as_mut() { if let Some(msg) = check_clipboard(ctx, None) { diff --git a/src/server/service.rs b/src/server/service.rs index b60f5a8d4..3e8c840a2 100644 --- a/src/server/service.rs +++ b/src/server/service.rs @@ -1,5 +1,6 @@ use super::*; use std::{ + sync::{self, mpsc::Sender}, thread::{self, JoinHandle}, time, }; @@ -153,6 +154,39 @@ impl> ServiceTmpl { } } + pub fn listen(&self, notify: N, callback: F) + where + N: 'static + FnMut(Sender) -> ResultType<()> + Send, + F: 'static + FnMut(Self, &mut S) -> ResultType<()> + Send, + S: 'static + Default + Reset, + { + let mut notify = notify; + let mut callback = callback; + let sp = self.clone(); + let (tx, rx) = sync::mpsc::channel(); + thread::spawn(move || { + let _ = notify(tx); + }); + + let thread = thread::spawn(move || { + let mut state = S::default(); + while let Ok(changed) = rx.recv() { + if changed && sp.active() { + if sp.has_subscribes() { + if let Err(err) = callback(sp.clone(), &mut state) { + log::error!("Error of {} service: {}", sp.name(), err); + #[cfg(windows)] + crate::platform::windows::try_change_desktop(); + } + } else { + state.reset(); + } + } + } + }); + self.0.write().unwrap().handle = Some(thread); + } + pub fn repeat(&self, interval_ms: u64, callback: F) where F: 'static + FnMut(Self, &mut S) -> ResultType<()> + Send, From 972ec8d79d02ed68938b0a5825ae7f6fccd42bc5 Mon Sep 17 00:00:00 2001 From: cc-morning <90960002+cc-morning@users.noreply.github.com> Date: Sun, 24 Oct 2021 23:47:02 +0800 Subject: [PATCH 16/21] Fix missing clipboard content --- src/server/clipboard_service.rs | 82 +++++++++++++++++++-------------- src/server/service.rs | 34 -------------- 2 files changed, 48 insertions(+), 68 deletions(-) diff --git a/src/server/clipboard_service.rs b/src/server/clipboard_service.rs index 3e94d2824..a0711c8d9 100644 --- a/src/server/clipboard_service.rs +++ b/src/server/clipboard_service.rs @@ -1,12 +1,11 @@ -use std::sync::mpsc::Sender; - -use clipboard_master::{CallbackResult, ClipboardHandler, Master}; - use super::*; pub use crate::common::{ check_clipboard, ClipboardContext, CLIPBOARD_INTERVAL as INTERVAL, CLIPBOARD_NAME as NAME, CONTENT, }; +use clipboard_master::{CallbackResult, ClipboardHandler, Master}; +use hbb_common::ResultType; +use std::{sync, sync::mpsc::Sender, thread}; struct State { ctx: Option, @@ -31,41 +30,56 @@ impl super::service::Reset for State { } } -struct ClipHandle { - tx: Sender, -} - -impl ClipboardHandler for ClipHandle { - fn on_clipboard_change(&mut self) -> CallbackResult { - let _ = self.tx.send(true); - CallbackResult::Next - } -} - pub fn new() -> GenericService { let sp = GenericService::new(NAME, true); - sp.listen::(notify, run); + sp.run::<_>(listen::run); sp } -fn notify(tx: Sender) -> ResultType<()> { - Master::new(ClipHandle { tx }).run()?; - Ok(()) -} +mod listen { + use super::*; -fn run(sp: GenericService, state: &mut State) -> ResultType<()> { - if let Some(ctx) = state.ctx.as_mut() { - if let Some(msg) = check_clipboard(ctx, None) { - sp.send(msg); - } - sp.snapshot(|sps| { - let txt = crate::CONTENT.lock().unwrap().clone(); - if !txt.is_empty() { - let msg_out = crate::create_clipboard_msg(txt); - sps.send_shared(Arc::new(msg_out)); - } - Ok(()) - })?; + struct ClipHandle { + tx: Sender<()>, + } + + impl ClipboardHandler for ClipHandle { + fn on_clipboard_change(&mut self) -> CallbackResult { + let _ = self.tx.send(()); + CallbackResult::Next + } + } + + fn notify(tx: Sender<()>) -> ResultType<()> { + Master::new(ClipHandle { tx }).run()?; + Ok(()) + } + + pub fn run(sp: GenericService) -> ResultType<()> { + let mut state = State::default(); + let (tx, rx) = sync::mpsc::channel::<()>(); + thread::spawn(|| { + let _ = notify(tx); + }); + + while sp.ok() { + sp.snapshot(|sps| { + let txt = crate::CONTENT.lock().unwrap().clone(); + if !txt.is_empty() { + let msg_out = crate::create_clipboard_msg(txt); + sps.send_shared(Arc::new(msg_out)); + } + Ok(()) + })?; + + if let Ok(()) = rx.recv() { + if let Some(ctx) = state.ctx.as_mut() { + if let Some(msg) = check_clipboard(ctx, None) { + sp.send(msg); + } + } + } + } + Ok(()) } - Ok(()) } diff --git a/src/server/service.rs b/src/server/service.rs index 3e8c840a2..b60f5a8d4 100644 --- a/src/server/service.rs +++ b/src/server/service.rs @@ -1,6 +1,5 @@ use super::*; use std::{ - sync::{self, mpsc::Sender}, thread::{self, JoinHandle}, time, }; @@ -154,39 +153,6 @@ impl> ServiceTmpl { } } - pub fn listen(&self, notify: N, callback: F) - where - N: 'static + FnMut(Sender) -> ResultType<()> + Send, - F: 'static + FnMut(Self, &mut S) -> ResultType<()> + Send, - S: 'static + Default + Reset, - { - let mut notify = notify; - let mut callback = callback; - let sp = self.clone(); - let (tx, rx) = sync::mpsc::channel(); - thread::spawn(move || { - let _ = notify(tx); - }); - - let thread = thread::spawn(move || { - let mut state = S::default(); - while let Ok(changed) = rx.recv() { - if changed && sp.active() { - if sp.has_subscribes() { - if let Err(err) = callback(sp.clone(), &mut state) { - log::error!("Error of {} service: {}", sp.name(), err); - #[cfg(windows)] - crate::platform::windows::try_change_desktop(); - } - } else { - state.reset(); - } - } - } - }); - self.0.write().unwrap().handle = Some(thread); - } - pub fn repeat(&self, interval_ms: u64, callback: F) where F: 'static + FnMut(Self, &mut S) -> ResultType<()> + Send, From 5164f7691949d68befb058f38485663c2e3353d9 Mon Sep 17 00:00:00 2001 From: cc-morning <90960002+cc-morning@users.noreply.github.com> Date: Mon, 25 Oct 2021 16:25:23 +0800 Subject: [PATCH 17/21] Fix lost clipboard content again --- src/server/clipboard_service.rs | 81 +++++++++++++++++---------------- 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/src/server/clipboard_service.rs b/src/server/clipboard_service.rs index a0711c8d9..f972771c3 100644 --- a/src/server/clipboard_service.rs +++ b/src/server/clipboard_service.rs @@ -4,34 +4,25 @@ pub use crate::common::{ CONTENT, }; use clipboard_master::{CallbackResult, ClipboardHandler, Master}; -use hbb_common::ResultType; -use std::{sync, sync::mpsc::Sender, thread}; - -struct State { - ctx: Option, -} - -impl Default for State { - fn default() -> Self { - let ctx = match ClipboardContext::new() { - Ok(ctx) => Some(ctx), - Err(err) => { - log::error!("Failed to start {}: {}", NAME, err); - None - } - }; - Self { ctx } - } -} - -impl super::service::Reset for State { - fn reset(&mut self) { - *CONTENT.lock().unwrap() = Default::default(); - } -} +use hbb_common::{anyhow, ResultType}; +use std::{ + sync, + sync::mpsc::{Receiver, Sender}, + thread, + time::Duration, +}; pub fn new() -> GenericService { let sp = GenericService::new(NAME, true); + + thread::spawn(|| { + let (tx, rx) = sync::mpsc::channel(); + unsafe { + listen::RECEIVER = Some(rx); + } + let _ = listen::notify(tx); + }); + sp.run::<_>(listen::run); sp } @@ -39,6 +30,10 @@ pub fn new() -> GenericService { mod listen { use super::*; + pub(super) static mut RECEIVER: Option> = None; + static mut CTX: Option = None; + static WAIT: Duration = Duration::from_millis(1000); + struct ClipHandle { tx: Sender<()>, } @@ -50,19 +45,33 @@ mod listen { } } - fn notify(tx: Sender<()>) -> ResultType<()> { + pub fn notify(tx: Sender<()>) -> ResultType<()> { Master::new(ClipHandle { tx }).run()?; Ok(()) } pub fn run(sp: GenericService) -> ResultType<()> { - let mut state = State::default(); - let (tx, rx) = sync::mpsc::channel::<()>(); - thread::spawn(|| { - let _ = notify(tx); - }); + if unsafe { CTX.as_ref() }.is_none() { + match ClipboardContext::new() { + Ok(ctx) => unsafe { + CTX = Some(ctx); + }, + Err(err) => { + log::error!("Failed to start {}: {}", NAME, err); + return Err(anyhow::Error::from(err)); + } + }; + } while sp.ok() { + if let Ok(_) = unsafe { RECEIVER.as_ref() }.unwrap().recv_timeout(WAIT) { + if let Some(mut ctx) = unsafe { CTX.as_mut() } { + if let Some(msg) = check_clipboard(&mut ctx, None) { + sp.send(msg); + } + } + } + sp.snapshot(|sps| { let txt = crate::CONTENT.lock().unwrap().clone(); if !txt.is_empty() { @@ -71,15 +80,9 @@ mod listen { } Ok(()) })?; - - if let Ok(()) = rx.recv() { - if let Some(ctx) = state.ctx.as_mut() { - if let Some(msg) = check_clipboard(ctx, None) { - sp.send(msg); - } - } - } } + + *CONTENT.lock().unwrap() = Default::default(); Ok(()) } } From 318e3cbd7d61acc4a5bd34c7173d9e5b6abf3ac9 Mon Sep 17 00:00:00 2001 From: cc-morning <90960002+cc-morning@users.noreply.github.com> Date: Tue, 26 Oct 2021 16:59:31 +0800 Subject: [PATCH 18/21] Code Format --- src/server/clipboard_service.rs | 67 +++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/src/server/clipboard_service.rs b/src/server/clipboard_service.rs index f972771c3..cc470ec7e 100644 --- a/src/server/clipboard_service.rs +++ b/src/server/clipboard_service.rs @@ -8,19 +8,22 @@ use hbb_common::{anyhow, ResultType}; use std::{ sync, sync::mpsc::{Receiver, Sender}, - thread, + thread::{self}, time::Duration, }; pub fn new() -> GenericService { let sp = GenericService::new(NAME, true); + // Listening service needs to run for a long time, + // otherwise it will cause part of the content to + // be missed during the closure of the clipboard + // (during the closure, the content copied by the + // remote machine will be missed, and the clipboard + // will not be synchronized immediately when it is + // opened again), and CONTENT will not be updated thread::spawn(|| { - let (tx, rx) = sync::mpsc::channel(); - unsafe { - listen::RECEIVER = Some(rx); - } - let _ = listen::notify(tx); + let _ = listen::notify(); }); sp.run::<_>(listen::run); @@ -30,44 +33,52 @@ pub fn new() -> GenericService { mod listen { use super::*; - pub(super) static mut RECEIVER: Option> = None; + static mut CHANNEL: Option<(Sender<()>, Receiver<()>)> = None; static mut CTX: Option = None; - static WAIT: Duration = Duration::from_millis(1000); + static WAIT: Duration = Duration::from_millis(1500); - struct ClipHandle { - tx: Sender<()>, - } + struct ClipHandle; impl ClipboardHandler for ClipHandle { fn on_clipboard_change(&mut self) -> CallbackResult { - let _ = self.tx.send(()); + if let Some((tx, _rx)) = unsafe { CHANNEL.as_ref() } { + let _ = tx.send(()); + } CallbackResult::Next } } - pub fn notify(tx: Sender<()>) -> ResultType<()> { - Master::new(ClipHandle { tx }).run()?; + pub fn notify() -> ResultType<()> { + Master::new(ClipHandle).run()?; Ok(()) } pub fn run(sp: GenericService) -> ResultType<()> { - if unsafe { CTX.as_ref() }.is_none() { - match ClipboardContext::new() { - Ok(ctx) => unsafe { - CTX = Some(ctx); - }, - Err(err) => { - log::error!("Failed to start {}: {}", NAME, err); - return Err(anyhow::Error::from(err)); - } - }; + unsafe { + if CHANNEL.is_none() { + CHANNEL = Some(sync::mpsc::channel()); + } + + if CTX.is_none() { + match ClipboardContext::new() { + Ok(ctx) => { + CTX = Some(ctx); + } + Err(err) => { + log::error!("Failed to start {}: {}", NAME, err); + return Err(anyhow::Error::from(err)); + } + }; + } } while sp.ok() { - if let Ok(_) = unsafe { RECEIVER.as_ref() }.unwrap().recv_timeout(WAIT) { - if let Some(mut ctx) = unsafe { CTX.as_mut() } { - if let Some(msg) = check_clipboard(&mut ctx, None) { - sp.send(msg); + if let Some((_tx, rx)) = unsafe { CHANNEL.as_ref() } { + if let Ok(_) = rx.recv_timeout(WAIT) { + if let Some(mut ctx) = unsafe { CTX.as_mut() } { + if let Some(msg) = check_clipboard(&mut ctx, None) { + sp.send(msg); + } } } } From 0cf2db92391ce90115a8b68b44e5d581e0963016 Mon Sep 17 00:00:00 2001 From: cc-morning <90960002+cc-morning@users.noreply.github.com> Date: Wed, 27 Oct 2021 20:02:17 +0800 Subject: [PATCH 19/21] Clipboard listener lifecycle follows service --- src/server/clipboard_service.rs | 105 +++++++++++++++++--------------- 1 file changed, 56 insertions(+), 49 deletions(-) diff --git a/src/server/clipboard_service.rs b/src/server/clipboard_service.rs index cc470ec7e..811aebb7b 100644 --- a/src/server/clipboard_service.rs +++ b/src/server/clipboard_service.rs @@ -6,26 +6,16 @@ pub use crate::common::{ use clipboard_master::{CallbackResult, ClipboardHandler, Master}; use hbb_common::{anyhow, ResultType}; use std::{ - sync, - sync::mpsc::{Receiver, Sender}, - thread::{self}, + io, sync, + sync::{ + atomic::{AtomicBool, Ordering}, + mpsc::SyncSender, + }, time::Duration, }; pub fn new() -> GenericService { let sp = GenericService::new(NAME, true); - - // Listening service needs to run for a long time, - // otherwise it will cause part of the content to - // be missed during the closure of the clipboard - // (during the closure, the content copied by the - // remote machine will be missed, and the clipboard - // will not be synchronized immediately when it is - // opened again), and CONTENT will not be updated - thread::spawn(|| { - let _ = listen::notify(); - }); - sp.run::<_>(listen::run); sp } @@ -33,53 +23,56 @@ pub fn new() -> GenericService { mod listen { use super::*; - static mut CHANNEL: Option<(Sender<()>, Receiver<()>)> = None; - static mut CTX: Option = None; + static RUNNING: AtomicBool = AtomicBool::new(true); static WAIT: Duration = Duration::from_millis(1500); - struct ClipHandle; + struct ClipHandle { + tx: SyncSender<()>, + } impl ClipboardHandler for ClipHandle { fn on_clipboard_change(&mut self) -> CallbackResult { - if let Some((tx, _rx)) = unsafe { CHANNEL.as_ref() } { - let _ = tx.send(()); + if !RUNNING.load(Ordering::SeqCst) { + return CallbackResult::Stop; } + + let _ = self.tx.send(()); CallbackResult::Next } - } - pub fn notify() -> ResultType<()> { - Master::new(ClipHandle).run()?; - Ok(()) - } - - pub fn run(sp: GenericService) -> ResultType<()> { - unsafe { - if CHANNEL.is_none() { - CHANNEL = Some(sync::mpsc::channel()); - } - - if CTX.is_none() { - match ClipboardContext::new() { - Ok(ctx) => { - CTX = Some(ctx); - } - Err(err) => { - log::error!("Failed to start {}: {}", NAME, err); - return Err(anyhow::Error::from(err)); - } - }; + fn on_clipboard_error(&mut self, error: io::Error) -> CallbackResult { + if !RUNNING.load(Ordering::SeqCst) { + CallbackResult::Stop + } else { + CallbackResult::StopWithError(error) } } + } + + #[tokio::main] + pub async fn run(sp: GenericService) -> ResultType<()> { + let mut ctx = match ClipboardContext::new() { + Ok(ctx) => ctx, + Err(err) => { + log::error!("Failed to start {}: {}", NAME, err); + return Err(anyhow::Error::from(err)); + } + }; + + if !RUNNING.load(Ordering::SeqCst) { + RUNNING.store(true, Ordering::SeqCst); + } + + let (tx, rx) = sync::mpsc::sync_channel(12); + let listener = tokio::spawn(async { + log::info!("Clipboard listener running!"); + let _ = Master::new(ClipHandle { tx }).run(); + }); while sp.ok() { - if let Some((_tx, rx)) = unsafe { CHANNEL.as_ref() } { - if let Ok(_) = rx.recv_timeout(WAIT) { - if let Some(mut ctx) = unsafe { CTX.as_mut() } { - if let Some(msg) = check_clipboard(&mut ctx, None) { - sp.send(msg); - } - } + if let Ok(_) = rx.recv_timeout(WAIT) { + if let Some(msg) = check_clipboard(&mut ctx, None) { + sp.send(msg); } } @@ -93,7 +86,21 @@ mod listen { })?; } + { + RUNNING.store(false, Ordering::SeqCst); + trigger(&mut ctx); + let _ = listener.await; + log::info!("Clipboard listener stopped!"); + } + *CONTENT.lock().unwrap() = Default::default(); Ok(()) } + + fn trigger(ctx: &mut ClipboardContext) { + let _ = match ctx.get_text() { + Ok(text) => ctx.set_text(text), + Err(_) => ctx.set_text(Default::default()), + }; + } } From 231231e51f5310c719a8c41e6abdf3d697a5d5a1 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Sat, 30 Oct 2021 14:03:33 +0800 Subject: [PATCH 20/21] refactor --- src/server/clipboard_service.rs | 10 ++++------ src/ui/file_transfer.tis | 6 ------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/server/clipboard_service.rs b/src/server/clipboard_service.rs index 811aebb7b..be496c859 100644 --- a/src/server/clipboard_service.rs +++ b/src/server/clipboard_service.rs @@ -86,12 +86,10 @@ mod listen { })?; } - { - RUNNING.store(false, Ordering::SeqCst); - trigger(&mut ctx); - let _ = listener.await; - log::info!("Clipboard listener stopped!"); - } + RUNNING.store(false, Ordering::SeqCst); + trigger(&mut ctx); + let _ = listener.await; + log::info!("Clipboard listener stopped!"); *CONTENT.lock().unwrap() = Default::default(); Ok(()) diff --git a/src/ui/file_transfer.tis b/src/ui/file_transfer.tis index 74eaf2b69..9c67d79ba 100644 --- a/src/ui/file_transfer.tis +++ b/src/ui/file_transfer.tis @@ -25,12 +25,6 @@ var svg_computer = ; -const TYPE_DIR = 1; -const TYPE_DIR_LINK = 2; -const TYPE_DIR_DRIVE = 3; -const TYPE_FILE = 4; -const TYPE_FILE_LINK = 5; - function getSize(type, size) { if (!size) { if (type <= 3) return ""; From e6bd5b06989964fb8f6dda425d727575a54f7f36 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Sun, 7 Nov 2021 10:18:10 +0800 Subject: [PATCH 21/21] pb in version --- libs/hbb_common/protos/rendezvous.proto | 3 +++ src/rendezvous_mediator.rs | 3 +++ 2 files changed, 6 insertions(+) diff --git a/libs/hbb_common/protos/rendezvous.proto b/libs/hbb_common/protos/rendezvous.proto index bd058ac4d..1a1671ce1 100644 --- a/libs/hbb_common/protos/rendezvous.proto +++ b/libs/hbb_common/protos/rendezvous.proto @@ -48,6 +48,7 @@ message PunchHoleSent { string id = 2; string relay_server = 3; NatType nat_type = 4; + string version = 5; } message RegisterPk { @@ -110,6 +111,7 @@ message RelayResponse { bytes pk = 5; } string refuse_reason = 6; + string version = 7; } message SoftwareUpdate { string url = 1; } @@ -128,6 +130,7 @@ message LocalAddr { bytes local_addr = 2; string relay_server = 3; string id = 4; + string version = 5; } message RendezvousMessage { diff --git a/src/rendezvous_mediator.rs b/src/rendezvous_mediator.rs index 13f0f605c..9e1554c6c 100644 --- a/src/rendezvous_mediator.rs +++ b/src/rendezvous_mediator.rs @@ -285,6 +285,7 @@ impl RendezvousMediator { let mut msg_out = Message::new(); let mut rr = RelayResponse { socket_addr, + version: crate::VERSION.to_owned(), ..Default::default() }; if initiate { @@ -321,6 +322,7 @@ impl RendezvousMediator { socket_addr: AddrMangle::encode(peer_addr), local_addr: AddrMangle::encode(local_addr), relay_server, + version: crate::VERSION.to_owned(), ..Default::default() }); let bytes = msg_out.write_to_bytes()?; @@ -359,6 +361,7 @@ impl RendezvousMediator { id: Config::get_id(), relay_server, nat_type: nat_type.into(), + version: crate::VERSION.to_owned(), ..Default::default() }); let bytes = msg_out.write_to_bytes()?;