From a211949ba42d8fa783950bd44e2d95b7df44dd0d Mon Sep 17 00:00:00 2001 From: rustdesk Date: Thu, 5 Jan 2023 15:57:59 +0800 Subject: [PATCH 01/40] add __CGPreLoginApp flag to xcode project following https://stackoverflow.com/questions/41429524/how-to-simulate-keyboard-and-mouse-events-using-cgeventpost-in-login-window-mac https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-700/IOHIDFamily.xcodeproj/project.pbxproj --- flutter/macos/Runner.xcodeproj/project.pbxproj | 12 ++++++++++++ flutter/macos/rustdesk.xcodeproj/project.pbxproj | 6 ++++++ 2 files changed, 18 insertions(+) diff --git a/flutter/macos/Runner.xcodeproj/project.pbxproj b/flutter/macos/Runner.xcodeproj/project.pbxproj index 6f49b7e19..e375623f0 100644 --- a/flutter/macos/Runner.xcodeproj/project.pbxproj +++ b/flutter/macos/Runner.xcodeproj/project.pbxproj @@ -561,6 +561,12 @@ SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; + OTHER_LDFLAGS = ( + "-sectcreate", + __CGPreLoginApp, + __cgpreloginapp, + /dev/null, + ); }; name = Release; }; @@ -614,6 +620,12 @@ PROVISIONING_PROFILE_SPECIFIER = ""; "SWIFT_OBJC_BRIDGING_HEADER[arch=*]" = Runner/bridge_generated.h; SWIFT_VERSION = 5.0; + OTHER_LDFLAGS = ( + "-sectcreate", + __CGPreLoginApp, + __cgpreloginapp, + /dev/null, + ); }; name = Release; }; diff --git a/flutter/macos/rustdesk.xcodeproj/project.pbxproj b/flutter/macos/rustdesk.xcodeproj/project.pbxproj index e334f0ac5..664f88618 100644 --- a/flutter/macos/rustdesk.xcodeproj/project.pbxproj +++ b/flutter/macos/rustdesk.xcodeproj/project.pbxproj @@ -108,6 +108,12 @@ PRODUCT_NAME = rustdesk; SDKROOT = macosx; SUPPORTS_MACCATALYST = YES; + OTHER_LDFLAGS = ( + "-sectcreate", + __CGPreLoginApp, + __cgpreloginapp, + /dev/null, + ); }; name = Release; }; From 3aa4aaea77309364948fd670351f301c7f36ea49 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Thu, 5 Jan 2023 15:59:42 +0800 Subject: [PATCH 02/40] more ignore --- flutter/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/flutter/.gitignore b/flutter/.gitignore index 3cbfc0f54..9c7e52c12 100644 --- a/flutter/.gitignore +++ b/flutter/.gitignore @@ -54,3 +54,4 @@ lib/generated_bridge.freezed.dart flutter_export_environment.sh Flutter-Generated.xcconfig key.jks +macos/rustdesk.xcodeproj/project.xcworkspace/ From 5618557bfd0ab7316c46c287b4cc050de4f8ce6f Mon Sep 17 00:00:00 2001 From: Kingtous Date: Thu, 5 Jan 2023 16:26:37 +0800 Subject: [PATCH 03/40] fix: upload race of deb and flatpak specific build --- .github/workflows/flutter-nightly.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/flutter-nightly.yml b/.github/workflows/flutter-nightly.yml index 17e338edc..e4b049a02 100644 --- a/.github/workflows/flutter-nightly.yml +++ b/.github/workflows/flutter-nightly.yml @@ -1181,6 +1181,7 @@ jobs: done - name: Publish debian package + if: ${{ matrix.job.extra-build-features == '' }} uses: softprops/action-gh-release@v1 with: prerelease: true From 5f6a2642781b85b753d029db7cab547a3454bc9d Mon Sep 17 00:00:00 2001 From: 21pages Date: Thu, 5 Jan 2023 14:27:28 +0800 Subject: [PATCH 04/40] optional software render to fix flutter render problem on some nvidia card Signed-off-by: 21pages --- Cargo.lock | 1 + Cargo.toml | 1 + .../desktop/pages/desktop_setting_page.dart | 11 ++- src/core_main.rs | 11 +++ src/lang/ca.rs | 2 + src/lang/cn.rs | 2 + src/lang/cs.rs | 2 + src/lang/da.rs | 2 + src/lang/de.rs | 2 + src/lang/en.rs | 1 + src/lang/eo.rs | 2 + src/lang/es.rs | 2 + src/lang/fa.rs | 2 + src/lang/fr.rs | 2 + src/lang/gr.rs | 2 + src/lang/hu.rs | 2 + src/lang/id.rs | 2 + src/lang/it.rs | 2 + src/lang/ja.rs | 2 + src/lang/ko.rs | 2 + src/lang/kz.rs | 2 + src/lang/pl.rs | 2 + src/lang/pt_PT.rs | 2 + src/lang/ptbr.rs | 2 + src/lang/ru.rs | 2 + src/lang/sk.rs | 2 + src/lang/sq.rs | 2 + src/lang/sr.rs | 2 + src/lang/sv.rs | 2 + src/lang/template.rs | 2 + src/lang/th.rs | 5 +- src/lang/tr.rs | 2 + src/lang/tw.rs | 2 + src/lang/ua.rs | 2 + src/lang/vn.rs | 2 + src/platform/linux.rs | 89 +++++++++++++++++++ 36 files changed, 175 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e734249de..1ec3929b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4562,6 +4562,7 @@ dependencies = [ "arboard", "async-process", "async-trait", + "backtrace", "base64", "bytes", "cc", diff --git a/Cargo.toml b/Cargo.toml index 82c35de79..2713df11d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -119,6 +119,7 @@ dbus-crossroads = "0.5" gtk = "0.15" libappindicator = "0.7" glib = "0.16.5" +backtrace = "0.3" [target.'cfg(target_os = "android")'.dependencies] android_logger = "0.11" diff --git a/flutter/lib/desktop/pages/desktop_setting_page.dart b/flutter/lib/desktop/pages/desktop_setting_page.dart index 15f78daeb..45588171b 100644 --- a/flutter/lib/desktop/pages/desktop_setting_page.dart +++ b/flutter/lib/desktop/pages/desktop_setting_page.dart @@ -274,6 +274,15 @@ class _GeneralState extends State<_General> { _OptionCheckBox(context, 'Confirm before closing multiple tabs', 'enable-confirm-closing-tabs'), _OptionCheckBox(context, 'Adaptive Bitrate', 'enable-abr'), + if (Platform.isLinux) + Tooltip( + message: translate('software_render_tip'), + child: _OptionCheckBox( + context, + "Always use software rendering", + 'allow-always-software-render', + ), + ) ]); } @@ -1223,7 +1232,7 @@ Widget _OptionCheckBox(BuildContext context, String label, String key, ref.value = option; if (reverse) option = !option; String value = bool2option(key, option); - bind.mainSetOption(key: key, value: value); + await bind.mainSetOption(key: key, value: value); update?.call(); } } diff --git a/src/core_main.rs b/src/core_main.rs index 1f42f8aad..bf6866df5 100644 --- a/src/core_main.rs +++ b/src/core_main.rs @@ -38,6 +38,17 @@ pub fn core_main() -> Option> { } i += 1; } + #[cfg(target_os = "linux")] + #[cfg(feature = "flutter")] + { + crate::platform::linux::register_breakdown_handler(); + let (k, v) = ("LIBGL_ALWAYS_SOFTWARE", "true"); + if !hbb_common::config::Config::get_option("allow-always-software-render").is_empty() { + std::env::set_var(k, v); + } else { + std::env::remove_var(k); + } + } #[cfg(feature = "flutter")] if _is_flutter_connect { return core_main_invoke_new_connection(std::env::args()); diff --git a/src/lang/ca.rs b/src/lang/ca.rs index 093f2572c..eb38cd436 100644 --- a/src/lang/ca.rs +++ b/src/lang/ca.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", ""), ("Local keyboard type", ""), ("Select local keyboard type", ""), + ("software_render_tip", ""), + ("Always use software rendering", ""), ].iter().cloned().collect(); } diff --git a/src/lang/cn.rs b/src/lang/cn.rs index 307cbfd9b..c5e4407a6 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", "被web控制台手动关闭"), ("Local keyboard type", "本地键盘类型"), ("Select local keyboard type", "请选择本地键盘类型"), + ("software_render_tip", "如果你使用英伟达显卡, 并且远程窗口在会话建立后会立刻关闭, 那么安装nouveau驱动并且选择使用软件渲染可能会有帮助。重启软件后生效。"), + ("Always use software rendering", "使用软件渲染"), ].iter().cloned().collect(); } diff --git a/src/lang/cs.rs b/src/lang/cs.rs index 027de13ba..18b2673c9 100644 --- a/src/lang/cs.rs +++ b/src/lang/cs.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", ""), ("Local keyboard type", ""), ("Select local keyboard type", ""), + ("software_render_tip", ""), + ("Always use software rendering", ""), ].iter().cloned().collect(); } diff --git a/src/lang/da.rs b/src/lang/da.rs index 3361804e8..a1e74259c 100644 --- a/src/lang/da.rs +++ b/src/lang/da.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", ""), ("Local keyboard type", ""), ("Select local keyboard type", ""), + ("software_render_tip", ""), + ("Always use software rendering", ""), ].iter().cloned().collect(); } diff --git a/src/lang/de.rs b/src/lang/de.rs index 7226550f5..44404d52f 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", "Manuell über die Webkonsole beendet"), ("Local keyboard type", "Lokaler Tastaturtyp"), ("Select local keyboard type", "Lokalen Tastaturtyp auswählen"), + ("software_render_tip", ""), + ("Always use software rendering", ""), ].iter().cloned().collect(); } diff --git a/src/lang/en.rs b/src/lang/en.rs index f351b575d..b8c8f074d 100644 --- a/src/lang/en.rs +++ b/src/lang/en.rs @@ -36,5 +36,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("hide_cm_tip", "Allow hiding only if accepting sessions via password and using permanent password"), ("wayland_experiment_tip", "Wayland support is in experimental stage, please use X11 if you require unattended access."), ("Slogan_tip", "Made with heart in this chaotic world!"), + ("software_render_tip", "If you have an Nvidia graphics card and the remote window closes immediately after connecting, installing the nouveau driver and choosing to use software rendering may help. A software restart is required.") ].iter().cloned().collect(); } diff --git a/src/lang/eo.rs b/src/lang/eo.rs index a21a2e91e..7b32c1708 100644 --- a/src/lang/eo.rs +++ b/src/lang/eo.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", ""), ("Local keyboard type", ""), ("Select local keyboard type", ""), + ("software_render_tip", ""), + ("Always use software rendering", ""), ].iter().cloned().collect(); } diff --git a/src/lang/es.rs b/src/lang/es.rs index b3276949a..4a9f9251c 100644 --- a/src/lang/es.rs +++ b/src/lang/es.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", "Cerrado manualmente por la consola web"), ("Local keyboard type", "Tipo de teclado local"), ("Select local keyboard type", "Seleccionar tipo de teclado local"), + ("software_render_tip", ""), + ("Always use software rendering", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fa.rs b/src/lang/fa.rs index 3d4579b27..8c0c426ed 100644 --- a/src/lang/fa.rs +++ b/src/lang/fa.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", ""), ("Local keyboard type", ""), ("Select local keyboard type", ""), + ("software_render_tip", ""), + ("Always use software rendering", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fr.rs b/src/lang/fr.rs index 1e3beb2e4..22b522a9d 100644 --- a/src/lang/fr.rs +++ b/src/lang/fr.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", "Fermé manuellement par la console Web"), ("Local keyboard type", "Disposition du clavier local"), ("Select local keyboard type", "Selectionner la disposition du clavier local"), + ("software_render_tip", ""), + ("Always use software rendering", ""), ].iter().cloned().collect(); } diff --git a/src/lang/gr.rs b/src/lang/gr.rs index 4b2777729..9ca035e65 100644 --- a/src/lang/gr.rs +++ b/src/lang/gr.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", ""), ("Local keyboard type", ""), ("Select local keyboard type", ""), + ("software_render_tip", ""), + ("Always use software rendering", ""), ].iter().cloned().collect(); } diff --git a/src/lang/hu.rs b/src/lang/hu.rs index 2f22ab511..2b81b90eb 100644 --- a/src/lang/hu.rs +++ b/src/lang/hu.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", ""), ("Local keyboard type", ""), ("Select local keyboard type", ""), + ("software_render_tip", ""), + ("Always use software rendering", ""), ].iter().cloned().collect(); } diff --git a/src/lang/id.rs b/src/lang/id.rs index 362a7fb85..ecc21b3f0 100644 --- a/src/lang/id.rs +++ b/src/lang/id.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", ""), ("Local keyboard type", ""), ("Select local keyboard type", ""), + ("software_render_tip", ""), + ("Always use software rendering", ""), ].iter().cloned().collect(); } diff --git a/src/lang/it.rs b/src/lang/it.rs index 390670df4..31cfd345e 100644 --- a/src/lang/it.rs +++ b/src/lang/it.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", "Chiudi manualmente dalla console Web"), ("Local keyboard type", "Tipo di tastiera locale"), ("Select local keyboard type", "Seleziona il tipo di tastiera locale"), + ("software_render_tip", ""), + ("Always use software rendering", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ja.rs b/src/lang/ja.rs index c247a7582..4673d2e41 100644 --- a/src/lang/ja.rs +++ b/src/lang/ja.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", ""), ("Local keyboard type", ""), ("Select local keyboard type", ""), + ("software_render_tip", ""), + ("Always use software rendering", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ko.rs b/src/lang/ko.rs index a4f2fde77..5d0b8c8a7 100644 --- a/src/lang/ko.rs +++ b/src/lang/ko.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", ""), ("Local keyboard type", ""), ("Select local keyboard type", ""), + ("software_render_tip", ""), + ("Always use software rendering", ""), ].iter().cloned().collect(); } diff --git a/src/lang/kz.rs b/src/lang/kz.rs index d8037ff62..0b55a79ff 100644 --- a/src/lang/kz.rs +++ b/src/lang/kz.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", ""), ("Local keyboard type", ""), ("Select local keyboard type", ""), + ("software_render_tip", ""), + ("Always use software rendering", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pl.rs b/src/lang/pl.rs index 2cf91af4a..5ca41e3ac 100644 --- a/src/lang/pl.rs +++ b/src/lang/pl.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", ""), ("Local keyboard type", ""), ("Select local keyboard type", ""), + ("software_render_tip", ""), + ("Always use software rendering", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pt_PT.rs b/src/lang/pt_PT.rs index fc95cb548..3e203a250 100644 --- a/src/lang/pt_PT.rs +++ b/src/lang/pt_PT.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", ""), ("Local keyboard type", ""), ("Select local keyboard type", ""), + ("software_render_tip", ""), + ("Always use software rendering", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ptbr.rs b/src/lang/ptbr.rs index 5a89efd4b..c17620bc1 100644 --- a/src/lang/ptbr.rs +++ b/src/lang/ptbr.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", ""), ("Local keyboard type", ""), ("Select local keyboard type", ""), + ("software_render_tip", ""), + ("Always use software rendering", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ru.rs b/src/lang/ru.rs index 82d8d357e..1fa6d7528 100644 --- a/src/lang/ru.rs +++ b/src/lang/ru.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", "Закрыто вручную через веб-консоль"), ("Local keyboard type", "Тип локальной клавиатуры"), ("Select local keyboard type", "Выберите тип локальной клавиатуры"), + ("software_render_tip", ""), + ("Always use software rendering", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sk.rs b/src/lang/sk.rs index e61ac9c58..13bbcf4f7 100644 --- a/src/lang/sk.rs +++ b/src/lang/sk.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", ""), ("Local keyboard type", ""), ("Select local keyboard type", ""), + ("software_render_tip", ""), + ("Always use software rendering", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sq.rs b/src/lang/sq.rs index c55562942..d08036bf3 100644 --- a/src/lang/sq.rs +++ b/src/lang/sq.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", ""), ("Local keyboard type", ""), ("Select local keyboard type", ""), + ("software_render_tip", ""), + ("Always use software rendering", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sr.rs b/src/lang/sr.rs index d74baf8b2..f9386004d 100644 --- a/src/lang/sr.rs +++ b/src/lang/sr.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", ""), ("Local keyboard type", ""), ("Select local keyboard type", ""), + ("software_render_tip", ""), + ("Always use software rendering", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sv.rs b/src/lang/sv.rs index 6a770c24a..9f2d1c9f4 100644 --- a/src/lang/sv.rs +++ b/src/lang/sv.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", ""), ("Local keyboard type", ""), ("Select local keyboard type", ""), + ("software_render_tip", ""), + ("Always use software rendering", ""), ].iter().cloned().collect(); } diff --git a/src/lang/template.rs b/src/lang/template.rs index b4113b91a..145cf45bb 100644 --- a/src/lang/template.rs +++ b/src/lang/template.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", ""), ("Local keyboard type", ""), ("Select local keyboard type", ""), + ("software_render_tip", ""), + ("Always use software rendering", ""), ].iter().cloned().collect(); } diff --git a/src/lang/th.rs b/src/lang/th.rs index 792f4f97a..d6bbe806d 100644 --- a/src/lang/th.rs +++ b/src/lang/th.rs @@ -280,7 +280,6 @@ lazy_static::lazy_static! { ("android_stop_service_tip", "การปิดการใช้งานเซอร์วิสจะปิดการเชื่อมต่อทั้งหมดโดยอัตโนมัติ"), ("android_version_audio_tip", "เวอร์ชั่นแอนดรอยด์ปัจจุบันของคุณไม่รองรับการบันทึกข้อมูลเสียง กรุณาอัปเกรดเป็นแอนดรอยด์เวอร์ชั่น 10 หรือสูงกว่า"), ("android_start_service_tip", "แตะ [เริ่มต้นใช้งานเซอร์วิส] หรือเปิดสิทธิ์ [การบันทึกหน้าจอ] เพื่อเริ่มเซอร์วิสการแชร์หน้าจอ"), - ("Account", "บัญชี"), ("Overwrite", "เขียนทับ"), ("This file exists, skip or overwrite this file?", "พบไฟล์ที่มีอยู่แล้ว ต้องการเขียนทับหรือไม่?"), ("Quit", "ออก"), @@ -334,6 +333,7 @@ lazy_static::lazy_static! { ("Scale adaptive", "ขนาดยืดหยุ่น"), ("General", "ทั่วไป"), ("Security", "ความปลอดภัย"), + ("Account", "บัญชี"), ("Theme", "ธีม"), ("Dark Theme", "ธีมมืด"), ("Dark", "มืด"), @@ -405,5 +405,8 @@ lazy_static::lazy_static! { ("Closed manually by the web console", "ถูกปิดโดยเว็บคอนโซล"), ("Local keyboard type", "ประเภทคีย์บอร์ด"), ("Select local keyboard type", "เลือกประเภทคีย์บอร์ด"), + ("software_render_tip", ""), + ("Always use software rendering", ""), ].iter().cloned().collect(); } + \ No newline at end of file diff --git a/src/lang/tr.rs b/src/lang/tr.rs index 60bc9dda1..00c620c34 100644 --- a/src/lang/tr.rs +++ b/src/lang/tr.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", ""), ("Local keyboard type", ""), ("Select local keyboard type", ""), + ("software_render_tip", ""), + ("Always use software rendering", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tw.rs b/src/lang/tw.rs index 0e08fa508..cb83d28ea 100644 --- a/src/lang/tw.rs +++ b/src/lang/tw.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", "被web控制台手動關閉"), ("Local keyboard type", "本地鍵盤類型"), ("Select local keyboard type", "請選擇本地鍵盤類型"), + ("software_render_tip", "如果你使用英偉達顯卡, 並且遠程窗口在會話建立後會立刻關閉, 那麼安裝nouveau驅動並且選擇使用軟件渲染可能會有幫助。重啟軟件後生效。"), + ("Always use software rendering", "使用軟件渲染"), ].iter().cloned().collect(); } diff --git a/src/lang/ua.rs b/src/lang/ua.rs index 343b62b4f..1c6ac5828 100644 --- a/src/lang/ua.rs +++ b/src/lang/ua.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", ""), ("Local keyboard type", ""), ("Select local keyboard type", ""), + ("software_render_tip", ""), + ("Always use software rendering", ""), ].iter().cloned().collect(); } diff --git a/src/lang/vn.rs b/src/lang/vn.rs index a2fc416f2..d2e067b3b 100644 --- a/src/lang/vn.rs +++ b/src/lang/vn.rs @@ -405,5 +405,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", ""), ("Local keyboard type", ""), ("Select local keyboard type", ""), + ("software_render_tip", ""), + ("Always use software rendering", ""), ].iter().cloned().collect(); } diff --git a/src/platform/linux.rs b/src/platform/linux.rs index ab436ed30..b2c2e81cb 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -717,3 +717,92 @@ pub fn get_double_click_time() -> u32 { } } +/// forever: may not work +pub fn system_message(title: &str, msg: &str, forever: bool) -> ResultType<()> { + if std::process::Command::new("notify-send") + .arg(title) + .arg(msg) + .spawn() + .is_ok() + { + return Ok(()); + } + if std::process::Command::new("zenity") + .arg("--info") + .arg("--timeout") + .arg(if forever { "0" } else { "3" }) + .arg("--title") + .arg(title) + .arg("--text") + .arg(msg) + .spawn() + .is_ok() + { + return Ok(()); + } + if std::process::Command::new("kdialog") + .arg("--title") + .arg(title) + .arg("--msgbox") + .arg(msg) + .spawn() + .is_ok() + { + return Ok(()); + } + if std::process::Command::new("xmessage") + .arg("-center") + .arg("-timeout") + .arg(if forever { "0" } else { "3" }) + .arg(title) + .arg(msg) + .spawn() + .is_ok() + { + return Ok(()); + } + bail!("failed to post system message"); +} + +extern "C" fn breakdown_signal_handler(sig: i32) { + let mut stack = vec![]; + backtrace::trace(|frame| { + backtrace::resolve_frame(frame, |symbol| { + if let Some(name) = symbol.name() { + stack.push(name.to_string()); + } + }); + true // keep going to the next frame + }); + let mut info = String::default(); + if stack.iter().any(|s| { + s.contains(&"nouveau_pushbuf_kick") + || s.to_lowercase().contains("nvidia") + || s.contains("gdk_window_end_draw_frame") + }) { + hbb_common::config::Config::set_option( + "allow-always-software-render".to_string(), + "Y".to_string(), + ); + info = "Always use software rendering will be set.".to_string(); + log::info!("{}", info); + } + log::error!( + "Got signal {} and exit. stack:\n{}", + sig, + stack.join("\n").to_string() + ); + system_message( + "RustDesk", + &format!("Got signal {} and exit.{}", sig, info), + true, + ) + .ok(); + std::process::exit(0); +} + +pub fn register_breakdown_handler() { + unsafe { + libc::signal(libc::SIGSEGV, breakdown_signal_handler as _); + } +} From adb3450d02d602b1a369c2fd4b4150ff46f1ea59 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Thu, 5 Jan 2023 17:45:41 +0800 Subject: [PATCH 05/40] more comment on code sign of mac --- build.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/build.py b/build.py index ca91b3581..19e28c416 100755 --- a/build.py +++ b/build.py @@ -481,9 +481,15 @@ def main(): version, 'rustdesk-%s.dmg' % version) if pa: os.system(''' + # https://pyoxidizer.readthedocs.io/en/apple-codesign-0.14.0/apple_codesign.html + # https://pyoxidizer.readthedocs.io/en/stable/tugger_code_signing.html + # https://developer.apple.com/developer-id/ + # goto xcode and login with apple id, manager certificates (Developer ID Application and/or Developer ID Installer) online there (only download and double click (install) cer file can not export p12 because no private key) #rcodesign sign --p12-file ~/.p12/rustdesk-developer-id.p12 --p12-password-file ~/.p12/.cert-pass --code-signature-flags runtime ./rustdesk-{1}.dmg codesign -s "Developer ID Application: {0}" --force --options runtime ./rustdesk-{1}.dmg - # https://pyoxidizer.readthedocs.io/en/latest/apple_codesign_rcodesign.html + # https://appstoreconnect.apple.com/access/api + # https://gregoryszorc.com/docs/apple-codesign/0.16.0/apple_codesign_rcodesign.html#notarizing-and-stapling + # https://documentation.onesignal.com/docs/establishing-an-apns-authentication-key#step-2-generate-a-new-p8-key rcodesign notarize --api-issuer {2} --api-key {3} --staple ./rustdesk-{1}.dmg # verify: spctl -a -t exec -v /Applications/RustDesk.app '''.format(pa, version, os.environ.get('api-issuer'), os.environ.get('api-key'))) From 97cf85d1b7d618900067a1d47d21d7011487fce9 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 5 Jan 2023 17:14:44 +0800 Subject: [PATCH 06/40] mouse forward back support on windows Signed-off-by: fufesou --- flutter/lib/models/input_model.dart | 12 +++++++++--- libs/enigo/src/lib.rs | 4 ++++ libs/enigo/src/win/win_impl.rs | 16 ++++++++++++++-- src/flutter_ffi.rs | 8 +++++--- src/server/input_service.rs | 24 ++++++++++++++++++------ 5 files changed, 50 insertions(+), 14 deletions(-) diff --git a/flutter/lib/models/input_model.dart b/flutter/lib/models/input_model.dart index 52675de41..0137b784e 100644 --- a/flutter/lib/models/input_model.dart +++ b/flutter/lib/models/input_model.dart @@ -466,15 +466,21 @@ class InputModel { evt['y'] = '${y.round()}'; var buttons = ''; switch (evt['buttons']) { - case 1: + case kPrimaryMouseButton: buttons = 'left'; break; - case 2: + case kSecondaryMouseButton: buttons = 'right'; break; - case 4: + case kMiddleMouseButton: buttons = 'wheel'; break; + case kBackMouseButton: + buttons = 'back'; + break; + case kForwardMouseButton: + buttons = 'forward'; + break; } evt['buttons'] = buttons; bind.sessionSendMouse(id: id, msg: json.encode(evt)); diff --git a/libs/enigo/src/lib.rs b/libs/enigo/src/lib.rs index caa08bd55..fcc2981fd 100644 --- a/libs/enigo/src/lib.rs +++ b/libs/enigo/src/lib.rs @@ -104,6 +104,10 @@ pub enum MouseButton { Middle, /// Right mouse button Right, + /// Back mouse button + Back, + /// Forward mouse button + Forward, /// Scroll up button ScrollUp, diff --git a/libs/enigo/src/win/win_impl.rs b/libs/enigo/src/win/win_impl.rs index 4a4fd7fc4..1b2a3f78e 100644 --- a/libs/enigo/src/win/win_impl.rs +++ b/libs/enigo/src/win/win_impl.rs @@ -134,9 +134,15 @@ impl MouseControllable for Enigo { MouseButton::Left => MOUSEEVENTF_LEFTDOWN, MouseButton::Middle => MOUSEEVENTF_MIDDLEDOWN, MouseButton::Right => MOUSEEVENTF_RIGHTDOWN, + MouseButton::Back => MOUSEEVENTF_XDOWN, + MouseButton::Forward => MOUSEEVENTF_XDOWN, _ => unimplemented!(), }, - 0, + match button { + MouseButton::Back => XBUTTON1 as _, + MouseButton::Forward => XBUTTON2 as _, + _ => 0, + }, 0, 0, ); @@ -155,9 +161,15 @@ impl MouseControllable for Enigo { MouseButton::Left => MOUSEEVENTF_LEFTUP, MouseButton::Middle => MOUSEEVENTF_MIDDLEUP, MouseButton::Right => MOUSEEVENTF_RIGHTUP, + MouseButton::Back => MOUSEEVENTF_XUP, + MouseButton::Forward => MOUSEEVENTF_XUP, _ => unimplemented!(), }, - 0, + match button { + MouseButton::Back => XBUTTON1 as _, + MouseButton::Forward => XBUTTON2 as _, + _ => 0, + }, 0, 0, ); diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index bf5ebaf4e..25161e1e3 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -885,9 +885,11 @@ pub fn session_send_mouse(id: String, msg: String) { } if let Some(buttons) = m.get("buttons") { mask |= match buttons.as_str() { - "left" => 1, - "right" => 2, - "wheel" => 4, + "left" => 0x01, + "right" => 0x02, + "wheel" => 0x04, + "back" => 0x08, + "forward" => 0x10, _ => 0, } << 3; } diff --git a/src/server/input_service.rs b/src/server/input_service.rs index bd2ad9a16..41ce8fd9e 100644 --- a/src/server/input_service.rs +++ b/src/server/input_service.rs @@ -556,27 +556,39 @@ pub fn handle_mouse_(evt: &MouseEvent) { en.mouse_move_to(evt.x, evt.y); } 1 => match buttons { - 1 => { + 0x01 => { allow_err!(en.mouse_down(MouseButton::Left)); } - 2 => { + 0x02 => { allow_err!(en.mouse_down(MouseButton::Right)); } - 4 => { + 0x04 => { allow_err!(en.mouse_down(MouseButton::Middle)); } + 0x08 => { + allow_err!(en.mouse_down(MouseButton::Back)); + } + 0x10 => { + allow_err!(en.mouse_down(MouseButton::Forward)); + } _ => {} }, 2 => match buttons { - 1 => { + 0x01 => { en.mouse_up(MouseButton::Left); } - 2 => { + 0x02 => { en.mouse_up(MouseButton::Right); } - 4 => { + 0x04 => { en.mouse_up(MouseButton::Middle); } + 0x08 => { + en.mouse_up(MouseButton::Back); + } + 0x10 => { + en.mouse_up(MouseButton::Forward); + } _ => {} }, 3 | 4 => { From b4feae33bb0891fc0dde013a04b6e1db108493d9 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 5 Jan 2023 17:45:07 +0800 Subject: [PATCH 07/40] support linux mouse back/forward Signed-off-by: fufesou --- libs/enigo/src/linux/xdo.rs | 2 ++ libs/enigo/src/macos/macos_impl.rs | 10 ++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/libs/enigo/src/linux/xdo.rs b/libs/enigo/src/linux/xdo.rs index 204420adc..2115d7283 100644 --- a/libs/enigo/src/linux/xdo.rs +++ b/libs/enigo/src/linux/xdo.rs @@ -57,6 +57,8 @@ fn mousebutton(button: MouseButton) -> c_int { MouseButton::ScrollDown => 5, MouseButton::ScrollLeft => 6, MouseButton::ScrollRight => 7, + MouseButton::Back => 8, + MouseButton::Forward => 9, } } diff --git a/libs/enigo/src/macos/macos_impl.rs b/libs/enigo/src/macos/macos_impl.rs index 68457a4a2..55f350895 100644 --- a/libs/enigo/src/macos/macos_impl.rs +++ b/libs/enigo/src/macos/macos_impl.rs @@ -226,7 +226,10 @@ impl MouseControllable for Enigo { MouseButton::Left => (CGMouseButton::Left, CGEventType::LeftMouseDown), MouseButton::Middle => (CGMouseButton::Center, CGEventType::OtherMouseDown), MouseButton::Right => (CGMouseButton::Right, CGEventType::RightMouseDown), - _ => unimplemented!(), + _ => { + log::info!("Unsupported button {:?}", button); + return Ok(()); + }, }; let dest = CGPoint::new(current_x as f64, current_y as f64); if let Some(src) = self.event_source.as_ref() { @@ -249,7 +252,10 @@ impl MouseControllable for Enigo { MouseButton::Left => (CGMouseButton::Left, CGEventType::LeftMouseUp), MouseButton::Middle => (CGMouseButton::Center, CGEventType::OtherMouseUp), MouseButton::Right => (CGMouseButton::Right, CGEventType::RightMouseUp), - _ => unimplemented!(), + _ => { + log::info!("Unsupported button {:?}", button); + return; + }, }; let dest = CGPoint::new(current_x as f64, current_y as f64); if let Some(src) = self.event_source.as_ref() { From 20ba62870e772328fa63f919c37b1e9182ee6d87 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 5 Jan 2023 17:52:57 +0800 Subject: [PATCH 08/40] remove unimplemented! Signed-off-by: fufesou --- libs/enigo/src/win/win_impl.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/libs/enigo/src/win/win_impl.rs b/libs/enigo/src/win/win_impl.rs index 1b2a3f78e..fb3b9881f 100644 --- a/libs/enigo/src/win/win_impl.rs +++ b/libs/enigo/src/win/win_impl.rs @@ -136,7 +136,10 @@ impl MouseControllable for Enigo { MouseButton::Right => MOUSEEVENTF_RIGHTDOWN, MouseButton::Back => MOUSEEVENTF_XDOWN, MouseButton::Forward => MOUSEEVENTF_XDOWN, - _ => unimplemented!(), + _ => { + log::info!("Unsupported button {:?}", button); + return Ok(()); + } }, match button { MouseButton::Back => XBUTTON1 as _, @@ -163,7 +166,10 @@ impl MouseControllable for Enigo { MouseButton::Right => MOUSEEVENTF_RIGHTUP, MouseButton::Back => MOUSEEVENTF_XUP, MouseButton::Forward => MOUSEEVENTF_XUP, - _ => unimplemented!(), + _ => { + log::info!("Unsupported button {:?}", button); + return; + } }, match button { MouseButton::Back => XBUTTON1 as _, From db5656b569ddfdcf795609c4bb2abbf893470b7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jernej=20Simon=C4=8Di=C4=8D?= Date: Thu, 5 Jan 2023 13:01:11 +0100 Subject: [PATCH 09/40] Add Slovenian translation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jernej Simončič --- src/lang.rs | 3 + src/lang/sl.rs | 409 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 412 insertions(+) create mode 100755 src/lang/sl.rs diff --git a/src/lang.rs b/src/lang.rs index 5ea408416..65505cd70 100644 --- a/src/lang.rs +++ b/src/lang.rs @@ -30,6 +30,7 @@ mod sv; mod sq; mod sr; mod th; +mod sl; lazy_static::lazy_static! { pub static ref LANGS: Value = @@ -63,6 +64,7 @@ lazy_static::lazy_static! { ("sq", "Shqip"), ("sr", "Srpski"), ("th", "ภาษาไทย"), + ("sl", "Slovenščina"), ]); } @@ -120,6 +122,7 @@ pub fn translate_locale(name: String, locale: &str) -> String { "sq" => sq::T.deref(), "sr" => sr::T.deref(), "th" => th::T.deref(), + "sl" => sl::T.deref(), _ => en::T.deref(), }; if let Some(v) = m.get(&name as &str) { diff --git a/src/lang/sl.rs b/src/lang/sl.rs new file mode 100755 index 000000000..7cd8f0c98 --- /dev/null +++ b/src/lang/sl.rs @@ -0,0 +1,409 @@ +lazy_static::lazy_static! { +pub static ref T: std::collections::HashMap<&'static str, &'static str> = + [ + ("Status", "Stanje"), + ("Your Desktop", "Vaše namizje"), + ("desk_tip", "Do vašega namizja lahko dostopate s spodnjim IDjem in geslom"), + ("Password", "Geslo"), + ("Ready", "Pripravljen"), + ("Established", "Povezava vzpostavljena"), + ("connecting_status", "Vzpostavljanje povezave z omrežjem RustDesk..."), + ("Enable Service", "Omogoči storitev"), + ("Start Service", "Zaženi storitev"), + ("Service is running", "Storitev se izvaja"), + ("Service is not running", "Storitev se ne izvaja"), + ("not_ready_status", "Ni pripravljeno, preverite vašo mrežno povezavo"), + ("Control Remote Desktop", "Nadzoruj oddaljeno namizje"), + ("Transfer File", "Prenos datotek"), + ("Connect", "Poveži"), + ("Recent Sessions", "Nedavne seje"), + ("Address Book", "Adresar"), + ("Confirmation", "Potrditev"), + ("TCP Tunneling", "TCP tuneliranje"), + ("Remove", "Odstrani"), + ("Refresh random password", "Osveži naključno geslo"), + ("Set your own password", "Nastavi lastno geslo"), + ("Enable Keyboard/Mouse", "Omogoči tipkovnico in miško"), + ("Enable Clipboard", "Omogoči odložišče"), + ("Enable File Transfer", "Omogoči prenos datotek"), + ("Enable TCP Tunneling", "Omogoči TCP tuneliranje"), + ("IP Whitelisting", "Omogoči seznam dovoljenih IPjev"), + ("ID/Relay Server", "Strežnik za ID/posredovanje"), + ("Import Server Config", "Uvozi nastavitve strežnika"), + ("Export Server Config", "Izvozi nastavitve strežnika"), + ("Import server configuration successfully", "Nastavitve strežnika uspešno uvožene"), + ("Export server configuration successfully", "Nastavitve strežnika uspešno izvožene"), + ("Invalid server configuration", "Neveljavne nastavitve strežnika"), + ("Clipboard is empty", "Odložišče je prazno"), + ("Stop service", "Ustavi storitev"), + ("Change ID", "Spremeni ID"), + ("Website", "Spletna stran"), + ("About", "O programu"), + ("Slogan_tip", ""), + ("Privacy Statement", ""), + ("Mute", "Izklopi zvok"), + ("Audio Input", "Avdio vhod"), + ("Enhancements", "Izboljšave"), + ("Hardware Codec", "Strojni kodek"), + ("Adaptive Bitrate", "Prilagodljiva bitna hitrost"), + ("ID Server", "ID strežnik"), + ("Relay Server", "Posredniški strežnik"), + ("API Server", "API strežnik"), + ("invalid_http", "mora se začeti s http:// ali https://"), + ("Invalid IP", "Neveljaven IP"), + ("id_change_tip", "Dovoljeni znaki so a-z, A-Z (brez šumnikov), 0-9 in _. Prvi znak mora biti črka, dolžina od 6 do 16 znakov."), + ("Invalid format", "Neveljavna oblika"), + ("server_not_support", "Strežnik še ne podpira"), + ("Not available", "Ni na voljo"), + ("Too frequent", "Prepogosto"), + ("Cancel", "Prekliči"), + ("Skip", "Izpusti"), + ("Close", "Zapri"), + ("Retry", "Ponovi"), + ("OK", "V redu"), + ("Password Required", "Potrebno je geslo"), + ("Please enter your password", "Vnesite vaše geslo"), + ("Remember password", "Zapomni si geslo"), + ("Wrong Password", "Napačno geslo"), + ("Do you want to enter again?", "Želite znova vnesti?"), + ("Connection Error", "Napaka pri povezavi"), + ("Error", "Napaka"), + ("Reset by the peer", "Povezava prekinjena"), + ("Connecting...", "Povezovanje..."), + ("Connection in progress. Please wait.", "Vzpostavljanje povezave, prosim počakajte."), + ("Please try 1 minute later", "Poizkusite čez 1 minuto"), + ("Login Error", "Napaka pri prijavi"), + ("Successful", "Uspešno"), + ("Connected, waiting for image...", "Povezava vzpostavljena, čakam na sliko..."), + ("Name", "Ime"), + ("Type", "Vrsta"), + ("Modified", "Čas spremembe"), + ("Size", "Velikost"), + ("Show Hidden Files", "Prikaži skrite datoteke"), + ("Receive", "Prejmi"), + ("Send", "Pošlji"), + ("Refresh File", "Osveži datoteko"), + ("Local", "Lokalno"), + ("Remote", "Oddaljeno"), + ("Remote Computer", "Lokalni računalnik"), + ("Local Computer", "Oddaljeni računalnik"), + ("Confirm Delete", "Potrdi izbris"), + ("Delete", "Izbriši"), + ("Properties", "Lastnosti"), + ("Multi Select", "Večkratna izbira"), + ("Select All", "Izberi vse"), + ("Unselect All", "Počisti vse"), + ("Empty Directory", "Prazen imenik"), + ("Not an empty directory", "Imenik ni prazen"), + ("Are you sure you want to delete this file?", "Ali res želite izbrisati to datoteko?"), + ("Are you sure you want to delete this empty directory?", "Ali res želite izbrisati to prazno mapo?"), + ("Are you sure you want to delete the file of this directory?", "Ali res želite datoteko iz mape?"), + ("Do this for all conflicts", "Naredi to za vse"), + ("This is irreversible!", "Tega dejanja ni mogoče razveljaviti!"), + ("Deleting", "Brisanje"), + ("files", "datoteke"), + ("Waiting", "Čakanje"), + ("Finished", "Opravljeno"), + ("Speed", "Hitrost"), + ("Custom Image Quality", "Kakovost slike po meri"), + ("Privacy mode", "Zasebni način"), + ("Block user input", "Onemogoči uporabnikov vnos"), + ("Unblock user input", "Omogoči uporabnikov vnos"), + ("Adjust Window", "Prilagodi okno"), + ("Original", "Originalno"), + ("Shrink", "Skrči"), + ("Stretch", "Raztegni"), + ("Scrollbar", "Drsenje z drsniki"), + ("ScrollAuto", "Samodejno drsenje"), + ("Good image quality", "Visoka kakovost slike"), + ("Balanced", "Uravnoteženo"), + ("Optimize reaction time", "Optimiraj odzivni čas"), + ("Custom", "Po meri"), + ("Show remote cursor", "Prikaži oddaljeni kazalec miške"), + ("Show quality monitor", "Prikaži nadzornik kakovosti"), + ("Disable clipboard", "Onemogoči odložišče"), + ("Lock after session end", "Zakleni ob koncu seje"), + ("Insert", "Vstavi"), + ("Insert Lock", "Zaklep vstavljanja"), + ("Refresh", "Osveži"), + ("ID does not exist", "ID ne obstaja"), + ("Failed to connect to rendezvous server", "Ni se bilo mogoče povezati na povezovalni strežnik"), + ("Please try later", "Poizkusite znova kasneje"), + ("Remote desktop is offline", "Oddaljeno namizje ni dosegljivo"), + ("Key mismatch", "Ključ ni ustrezen"), + ("Timeout", "Časovna omejitev"), + ("Failed to connect to relay server", "Ni se bilo mogoče povezati na posredniški strežnik"), + ("Failed to connect via rendezvous server", "Ni se bilo mogoče povezati preko povezovalnega strežnika"), + ("Failed to connect via relay server", "Ni se bilo mogoče povezati preko posredniškega strežnika"), + ("Failed to make direct connection to remote desktop", "Ni bilo mogoče vzpostaviti neposredne povezave z oddaljenim namizjem"), + ("Set Password", "Nastavi geslo"), + ("OS Password", "Geslo operacijskega sistema"), + ("install_tip", "Zaradi nadzora uporabniškega računa, RustDesk v nekaterih primerih na oddaljeni strani ne deluje pravilno. Temu se lahko izognete z namestitvijo RustDeska."), + ("Click to upgrade", "Klikni za nadgradnjo"), + ("Click to download", "Klikni za prenos"), + ("Click to update", "Klikni za posodobitev"), + ("Configure", "Nastavi"), + ("config_acc", "Za oddaljeni nadzor namizja morate RustDesku dodeliti pravico za dostopnost"), + ("config_screen", "Za oddaljeni dostop do namizja morate RustDesku dodeliti pravico snemanje zaslona"), + ("Installing ...", "Nameščanje..."), + ("Install", "Namesti"), + ("Installation", "Namestitev"), + ("Installation Path", "Pot za namestitev"), + ("Create start menu shortcuts", "Ustvari bližnjice v meniju Začetek"), + ("Create desktop icon", "Ustvari ikono na namizju"), + ("agreement_tip", "Z namestitvijo se strinjate z licenčno pogodbo"), + ("Accept and Install", "Sprejmi in namesti"), + ("End-user license agreement", "Licenčna pogodba za končnega uporabnika"), + ("Generating ...", "Ustvarjanje ..."), + ("Your installation is lower version.", "Vaša namestitev je starejša"), + ("not_close_tcp_tip", "Med uporabo tunela ne zaprite tega okna"), + ("Listening ...", "Poslušam ..."), + ("Remote Host", "Oddaljeni gostitelj"), + ("Remote Port", "Oddaljena vrata"), + ("Action", "Deljanje"), + ("Add", "Dodaj"), + ("Local Port", "Lokalna vrata"), + ("Local Address", "Lokalni naslov"), + ("Change Local Port", "Spremeni lokalna vrata"), + ("setup_server_tip", "Za hitrejšo povezavo uporabite lasten strežnik"), + ("Too short, at least 6 characters.", "Prekratek, mora biti najmanj 6 znakov."), + ("The confirmation is not identical.", "Potrditev ni enaka."), + ("Permissions", "Dovoljenja"), + ("Accept", "Sprejmi"), + ("Dismiss", "Opusti"), + ("Disconnect", "Prekini povezavo"), + ("Allow using keyboard and mouse", "Dovoli uporabo tipkovnice in miške"), + ("Allow using clipboard", "Dovoli uporabo odložišča"), + ("Allow hearing sound", "Dovoli prenos zvoka"), + ("Allow file copy and paste", "Dovoli kopiraj in prilepi"), + ("Connected", "Povezan"), + ("Direct and encrypted connection", "Neposredna šifrirana povezava"), + ("Relayed and encrypted connection", "Posredovana šifrirana povezava"), + ("Direct and unencrypted connection", "Neposredna nešifrirana povezava"), + ("Relayed and unencrypted connection", "Posredovana šifrirana povezava"), + ("Enter Remote ID", "Vnesi oddaljeni ID"), + ("Enter your password", "Vnesi geslo"), + ("Logging in...", "Prijavljanje..."), + ("Enable RDP session sharing", "Omogoči deljenje RDP seje"), + ("Auto Login", "Samodejna prijava"), + ("Enable Direct IP Access", "Omogoči neposredni dostop preko IP"), + ("Rename", "Preimenuj"), + ("Space", "Prazno"), + ("Create Desktop Shortcut", "Ustvari bližnjico na namizju"), + ("Change Path", "Spremeni pot"), + ("Create Folder", "Ustvari mapo"), + ("Please enter the folder name", "Vnesite ime mape"), + ("Fix it", "Popravi"), + ("Warning", "Opozorilo"), + ("Login screen using Wayland is not supported", "Prijava z Waylandom ni podprta"), + ("Reboot required", "Potreben je ponovni zagon"), + ("Unsupported display server ", "Nepodprt zaslonski strežnik"), + ("x11 expected", "Pričakovan X11"), + ("Port", "Vrata"), + ("Settings", "Nastavitve"), + ("Username", "Uporabniško ime"), + ("Invalid port", "Neveljavno geslo"), + ("Closed manually by the peer", "Povezavo ročno prekinil odjemalec"), + ("Enable remote configuration modification", "Omogoči oddaljeno spreminjanje nastavitev"), + ("Run without install", "Zaženi brez namestitve"), + ("Always connected via relay", "Vedno povezan preko posrednika"), + ("Always connect via relay", "Vedno poveži preko posrednika"), + ("whitelist_tip", "Dostop je možen samo iz dovoljenih IPjev"), + ("Login", "Prijavi"), + ("Logout", "Odjavi"), + ("Tags", "Oznake"), + ("Search ID", "Išči ID"), + ("Current Wayland display server is not supported", "Trenutni Wayland zaslonski strežnik ni podprt"), + ("whitelist_sep", "Naslovi ločeni z vejico, podpičjem, presledkom ali novo vrstico"), + ("Add ID", "Dodaj ID"), + ("Add Tag", "Dodaj oznako"), + ("Unselect all tags", ""), + ("Network error", "Omrežna napaka"), + ("Username missed", "Up. ime izpuščeno"), + ("Password missed", "Geslo izpuščeno"), + ("Wrong credentials", "Napačne poverilnice"), + ("Edit Tag", "Uredi oznako"), + ("Unremember Password", "Pozabi geslo"), + ("Favorites", "Priljubljene"), + ("Add to Favorites", "Dodaj med priljubljene"), + ("Remove from Favorites", "Odstrani iz priljubljenih"), + ("Empty", "Prazno"), + ("Invalid folder name", "Napačno ime mape"), + ("Socks5 Proxy", "Socks5 posredniški strežnik"), + ("Hostname", "Ime gostitelja"), + ("Discovered", "Odkriti"), + ("install_daemon_tip", "Za samodejni zagon ob vklopu računalnika je potrebno dodati sistemsko storitev"), + ("Remote ID", "Oddaljeni ID"), + ("Paste", "Prilepi"), + ("Paste here?", "Prilepi tu?"), + ("Are you sure to close the connection?", "Ali želite prekiniti povezavo?"), + ("Download new version", "Prenesi novo različico"), + ("Touch mode", "Način dotika"), + ("Mouse mode", "Način mišle"), + ("One-Finger Tap", "Tap z enim prstom"), + ("Left Mouse", "Leva tipka miške"), + ("One-Long Tap", "Dolg tap z enim prstom"), + ("Two-Finger Tap", "Tap z dvema prstoma"), + ("Right Mouse", "Desna tipka miške"), + ("One-Finger Move", "Premik z enim prstom"), + ("Double Tap & Move", "Dvojni tap in premik"), + ("Mouse Drag", "Vlečenje z miško"), + ("Three-Finger vertically", "Triprstno navpično"), + ("Mouse Wheel", "Miškino kolesce"), + ("Two-Finger Move", "Premik z dvema prstoma"), + ("Canvas Move", "Premik platna"), + ("Pinch to Zoom", "Povečava s približevanjem prstov"), + ("Canvas Zoom", "Povečava platna"), + ("Reset canvas", "Ponastavi platno"), + ("No permission of file transfer", "Ni pravic za prenos datotek"), + ("Note", "Opomba"), + ("Connection", "Povezava"), + ("Share Screen", "Deli zaslon"), + ("CLOSE", "ZAPRI"), + ("OPEN", "ODPRI"), + ("Chat", "Pogovor"), + ("Total", "Skupaj"), + ("items", "elementi"), + ("Selected", "Izbrano"), + ("Screen Capture", "Zajem zaslona"), + ("Input Control", "Nadzor vnosa"), + ("Audio Capture", "Zajem zvoka"), + ("File Connection", "Datotečna povezava"), + ("Screen Connection", "Zaslonska povezava"), + ("Do you accept?", "Ali sprejmete?"), + ("Open System Setting", "Odpri sistemske nastavitve"), + ("How to get Android input permission?", "Kako pridobiti dovoljenje za vnos na Androidu?"), + ("android_input_permission_tip1", "Za oddaljeni nadzor vaše naprave Android, je potrebno RustDesku dodeliti pravico za dostopnost."), + ("android_input_permission_tip2", "Pojdite v sistemske nastavitve, poiščite »Nameščene storitve« in vklopite storitev »RustDesk Input«."), + ("android_new_connection_tip", "Prejeta je bila zahteva za oddaljeni nadzor vaše naprave."), + ("android_service_will_start_tip", "Z vklopom zajema zaslona se bo samodejno zagnala storitev, ki omogoča da oddaljene naprave pošljejo zahtevo za povezavo na vašo napravo."), + ("android_stop_service_tip", "Z zaustavitvijo storitve bodo samodejno prekinjene vse oddaljene povezave."), + ("android_version_audio_tip", "Trenutna različica Androida ne omogoča zajema zvoka. Za zajem zvoka nadgradite na Android 10 ali novejši."), + ("android_start_service_tip", "Tapnite »Zaženi storitev« ali »ODPRI« pri dovoljenju za zajem zaslona da zaženete storitev deljenja zaslona."), + ("Account", "Račun"), + ("Overwrite", "Prepiši"), + ("This file exists, skip or overwrite this file?", "Datoteka obstaja, izpusti ali prepiši?"), + ("Quit", "Izhod"), + ("doc_mac_permission", "https://rustdesk.com/docs/en/manual/mac/#enable-permissions"), + ("Help", "Pomoč"), + ("Failed", "Ni uspelo"), + ("Succeeded", "Uspelo"), + ("Someone turns on privacy mode, exit", "Vklopljen je zasebni način, izhod"), + ("Unsupported", "Ni podprto"), + ("Peer denied", "Odjemalec zavrnil"), + ("Please install plugins", "Namestite vključke"), + ("Peer exit", "Odjemalec se je zaprl"), + ("Failed to turn off", "Ni bilo mogoče izklopiti"), + ("Turned off", "Izklopljeno"), + ("In privacy mode", "V zasebnem načinu"), + ("Out privacy mode", "Iz zasebnega načina"), + ("Language", "Jezik"), + ("Keep RustDesk background service", "Ohrani RustDeskovo storitev v ozadju"), + ("Ignore Battery Optimizations", "Prezri optimizacije baterije"), + ("android_open_battery_optimizations_tip", "Če želite izklopiti to možnost, pojdite v nastavitve aplikacije RustDesk, poiščite »Baterija« in izklopite »Neomejeno«"), + ("Connection not allowed", "Povezava ni dovoljena"), + ("Legacy mode", "Stari način"), + ("Map mode", "Način preslikave"), + ("Translate mode", "Način prevajanja"), + ("Use permanent password", "Uporabi stalno geslo"), + ("Use both passwords", "Uporabi obe gesli"), + ("Set permanent password", "Nastavi stalno geslo"), + ("Enable Remote Restart", "Omogoči oddaljeni ponovni zagon"), + ("Allow remote restart", "Dovoli oddaljeni ponovni zagon"), + ("Restart Remote Device", "Znova zaženi oddaljeno napravo"), + ("Are you sure you want to restart", "Ali ste prepričani, da želite znova zagnati"), + ("Restarting Remote Device", "Ponovni zagon oddaljene naprave"), + ("remote_restarting_tip", "Oddaljena naprava se znova zaganja, prosim zaprite to sporočilo in se čez nekaj časa povežite s stalnim geslom."), + ("Copied", "Kopirano"), + ("Exit Fullscreen", "Izhod iz celozaslonskega načina"), + ("Fullscreen", "Celozaslonski način"), + ("Mobile Actions", "Dejanja za prenosne naprave"), + ("Select Monitor", "Izberite zaslon"), + ("Control Actions", "Dejanja za nadzor"), + ("Display Settings", "Nastavitve zaslona"), + ("Ratio", "Razmerje"), + ("Image Quality", "Kakovost slike"), + ("Scroll Style", "Način drsenja"), + ("Show Menubar", "Prikaži meni"), + ("Hide Menubar", "Skrij meni"), + ("Direct Connection", "Neposredna povezava"), + ("Relay Connection", "Posredovana povezava"), + ("Secure Connection", "Zavarovana povezava"), + ("Insecure Connection", "Nezavarovana povezava"), + ("Scale original", "Originalna velikost"), + ("Scale adaptive", "Prilagojena velikost"), + ("General", "Splošno"), + ("Security", "Varnost"), + ("Theme", "Tema"), + ("Dark Theme", "Temna tema"), + ("Dark", "Temna"), + ("Light", "Svetla"), + ("Follow System", "Sistemska"), + ("Enable hardware codec", "Omogoči strojno pospeševanje"), + ("Unlock Security Settings", "Odkleni varnostne nastavitve"), + ("Enable Audio", "Omogoči zvok"), + ("Unlock Network Settings", "Odkleni mrežne nastavitve"), + ("Server", "Strežnik"), + ("Direct IP Access", "Neposredni dostop preko IPja"), + ("Proxy", "Posredniški strežnik"), + ("Apply", "Uveljavi"), + ("Disconnect all devices?", "Odklopi vse naprave?"), + ("Clear", "Počisti"), + ("Audio Input Device", "Vhodna naprava za zvok"), + ("Deny remote access", "Onemogoči oddaljeni dostop"), + ("Use IP Whitelisting", "Omogoči seznam dovoljenih IP naslovov"), + ("Network", "Mreža"), + ("Enable RDP", "Omogoči RDP"), + ("Pin menubar", "Pripni menijsko vrstico"), + ("Unpin menubar", "Odpni menijsko vrstico"), + ("Recording", "Snemanje"), + ("Directory", "Imenik"), + ("Automatically record incoming sessions", "Samodejno snemaj vhodne seje"), + ("Change", "Spremeni"), + ("Start session recording", "Začni snemanje seje"), + ("Stop session recording", "Ustavi snemanje seje"), + ("Enable Recording Session", "Omogoči snemanje seje"), + ("Allow recording session", "Dovoli snemanje seje"), + ("Enable LAN Discovery", "Omogoči odkrivanje lokalnega omrežja"), + ("Deny LAN Discovery", "Onemogoči odkrivanje lokalnega omrežja"), + ("Write a message", "Napiši spoorčilo"), + ("Prompt", "Poziv"), + ("Please wait for confirmation of UAC...", "Počakajte za potrditev nadzora uporabniškega računa"), + ("elevated_foreground_window_tip", "Trenutno aktivno okno na oddaljenem računalniku zahteva višje pravice za upravljanje. Oddaljenega uporabnika lahko prosite, da okno minimizira, ali pa kliknite gumb za povzdig pravic v oknu za upravljanje povezave. Če se želite izogniti temu problemu, na oddaljenem računalniku RustDesk namestite."), + ("Disconnected", "Brez povezave"), + ("Other", "Drugo"), + ("Confirm before closing multiple tabs", "Zahtevajte potrditev pred zapiranjem večih zavihkov"), + ("Keyboard Settings", "Nastavitve tipkovnice"), + ("Full Access", "Poln dostop"), + ("Screen Share", "Deljenje zaslona"), + ("Wayland requires Ubuntu 21.04 or higher version.", "Wayland zahteva Ubuntu 21.04 ali novejši"), + ("Wayland requires higher version of linux distro. Please try X11 desktop or change your OS.", "Zahtevana je novejša različica Waylanda. Posodobite vašo distribucijo ali pa uporabite X11."), + ("JumpLink", "Pogled"), + ("Please Select the screen to be shared(Operate on the peer side).", "Izberite zaslon za delitev (na oddaljeni strani)."), + ("Show RustDesk", "Prikaži RustDesk"), + ("This PC", "Ta računalnik"), + ("or", "ali"), + ("Continue with", "Nadaljuj z"), + ("Elevate", "Povzdig pravic"), + ("Zoom cursor", "Povečaj kazalec miške"), + ("Accept sessions via password", "Sprejmi seje z geslom"), + ("Accept sessions via click", "Sprejmi seje s potrditvijo"), + ("Accept sessions via both", "Sprejmi seje z geslom ali potrditvijo"), + ("Please wait for the remote side to accept your session request...", "Počakajte, da oddaljeni računalnik sprejme povezavo..."), + ("One-time Password", "Enkratno geslo"), + ("Use one-time password", "Uporabi enkratno geslo"), + ("One-time password length", "Dolžina enkratnega gesla"), + ("Request access to your device", "Zahtevaj dostop do svoje naprave"), + ("Hide connection management window", "Skrij okno za upravljanje povezave"), + ("hide_cm_tip", "Dovoli skrivanje samo pri sprejemanju sej z geslom"), + ("wayland_experiment_tip", "Podpora za Wayland je v preizkusni fazi. Uporabite X11, če rabite nespremljan dostop."), + ("Right click to select tabs", "Desno-kliknite za izbiro zavihkov"), + ("Skipped", "Izpuščeno"), + ("Add to Address Book", "Dodaj v adresar"), + ("Group", "Skupina"), + ("Search", "Iskanje"), + ("Closed manually by the web console", "Ročno zaprto iz spletne konzole"), + ("Local keyboard type", "Lokalna vrsta tipkovnice"), + ("Select local keyboard type", "Izberite lokalno vrsto tipkovnice"), + ].iter().cloned().collect(); +} From d657ba29c3a02ad3bd254652a896c58315abf5f2 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Thu, 5 Jan 2023 21:03:54 +0800 Subject: [PATCH 10/40] modify comment --- build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.py b/build.py index 19e28c416..d92c0801a 100755 --- a/build.py +++ b/build.py @@ -489,7 +489,7 @@ def main(): codesign -s "Developer ID Application: {0}" --force --options runtime ./rustdesk-{1}.dmg # https://appstoreconnect.apple.com/access/api # https://gregoryszorc.com/docs/apple-codesign/0.16.0/apple_codesign_rcodesign.html#notarizing-and-stapling - # https://documentation.onesignal.com/docs/establishing-an-apns-authentication-key#step-2-generate-a-new-p8-key + # p8 file is generated when you generate api key, download and put it under ~/.private_keys/ rcodesign notarize --api-issuer {2} --api-key {3} --staple ./rustdesk-{1}.dmg # verify: spctl -a -t exec -v /Applications/RustDesk.app '''.format(pa, version, os.environ.get('api-issuer'), os.environ.get('api-key'))) From 19c56cf977b5efa56a1dbfd05bed39fee44e344f Mon Sep 17 00:00:00 2001 From: rustdesk Date: Thu, 5 Jan 2023 21:04:40 +0800 Subject: [PATCH 11/40] add comment --- build.py | 1 + 1 file changed, 1 insertion(+) diff --git a/build.py b/build.py index d92c0801a..f0131ad27 100755 --- a/build.py +++ b/build.py @@ -469,6 +469,7 @@ def main(): if pa: os.system(''' # buggy: rcodesign sign ... path/*, have to sign one by one + # install rcodesign via cargo install apple-codesign #rcodesign sign --p12-file ~/.p12/rustdesk-developer-id.p12 --p12-password-file ~/.p12/.cert-pass --code-signature-flags runtime ./target/release/bundle/osx/RustDesk.app/Contents/MacOS/rustdesk #rcodesign sign --p12-file ~/.p12/rustdesk-developer-id.p12 --p12-password-file ~/.p12/.cert-pass --code-signature-flags runtime ./target/release/bundle/osx/RustDesk.app/Contents/MacOS/libsciter.dylib #rcodesign sign --p12-file ~/.p12/rustdesk-developer-id.p12 --p12-password-file ~/.p12/.cert-pass --code-signature-flags runtime ./target/release/bundle/osx/RustDesk.app From 4789b54460098e7b820a329be6240a1deccdb4ec Mon Sep 17 00:00:00 2001 From: kingtous Date: Thu, 29 Dec 2022 21:17:30 +0800 Subject: [PATCH 12/40] feat: add macos codesign import --- .github/workflows/flutter-nightly.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/flutter-nightly.yml b/.github/workflows/flutter-nightly.yml index e4b049a02..ed1514770 100644 --- a/.github/workflows/flutter-nightly.yml +++ b/.github/workflows/flutter-nightly.yml @@ -149,6 +149,12 @@ jobs: - name: Checkout source code uses: actions/checkout@v3 + - name: Import the codesign cert + uses: apple-actions/import-codesign-certs@v1 + with: + p12-file-base64: ${{ secrets.MACOS_P12_BASE64 }} + p12-password: ${{ secrets.MACOS_P12_PASSWORD }} + - name: Install build runtime run: | brew install llvm create-dmg nasm yasm cmake gcc wget ninja From 6156faef250f29e9189ff4e6dffe39fe221b0462 Mon Sep 17 00:00:00 2001 From: kingtous Date: Thu, 29 Dec 2022 22:18:02 +0800 Subject: [PATCH 13/40] feat: codesign recursively --- .github/workflows/flutter-nightly.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/workflows/flutter-nightly.yml b/.github/workflows/flutter-nightly.yml index ed1514770..8c31ee097 100644 --- a/.github/workflows/flutter-nightly.yml +++ b/.github/workflows/flutter-nightly.yml @@ -154,6 +154,12 @@ jobs: with: p12-file-base64: ${{ secrets.MACOS_P12_BASE64 }} p12-password: ${{ secrets.MACOS_P12_PASSWORD }} + keychain: rustdesk + + - name: Check sign + run: | + security default-keychain -s rustdesk.keychain + security find-identity -v - name: Install build runtime run: | @@ -217,6 +223,16 @@ jobs: # --hwcodec not supported on macos yet ./build.py --flutter ${{ matrix.job.extra-build-args }} + - name: Codesign app and create signed dmg + run: | + security default-keychain -s rustdesk.keychain + security unlock-keychain -p ${{ secrets.MACOS_P12_PASSWORD }} rustdesk.keychain + # start sign the rustdesk.app and dmg + rm rustdesk-${{ env.VERSION }}.dmg || true + codesign --force -s ${{ secrets.MACOS_CODESIGN_IDENTITY }} --deep ./flutter/build/macos/Build/Products/Release/rustdesk.app -v + create-dmg rustdesk-${{ env.VERSION }}.dmg ./flutter/build/macos/Build/Products/Release/rustdesk.app + codesign --force -s ${{ secrets.MACOS_CODESIGN_IDENTITY }} --deep rustdesk-${{ env.VERSION }}.dmg -v + - name: Rename rustdesk run: | for name in rustdesk*??.dmg; do From 863ba0f4fb52c0a57b131f0c6dbc338e21ebb1c2 Mon Sep 17 00:00:00 2001 From: kingtous Date: Thu, 5 Jan 2023 22:05:24 +0800 Subject: [PATCH 14/40] feat: notarize dmg support --- .github/workflows/flutter-nightly.yml | 20 +++++++++++++++- .../macos/Runner.xcodeproj/project.pbxproj | 23 +++++++++++++------ .../macos/Runner/DebugProfile.entitlements | 2 ++ flutter/macos/Runner/Release.entitlements | 4 ++++ 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/.github/workflows/flutter-nightly.yml b/.github/workflows/flutter-nightly.yml index 8c31ee097..d2a256d91 100644 --- a/.github/workflows/flutter-nightly.yml +++ b/.github/workflows/flutter-nightly.yml @@ -156,11 +156,27 @@ jobs: p12-password: ${{ secrets.MACOS_P12_PASSWORD }} keychain: rustdesk - - name: Check sign + - name: Check sign and import sign key run: | security default-keychain -s rustdesk.keychain security find-identity -v + - name: Import notarize key + uses: timheuer/base64-to-file@v1.2 + with: + fileName: rustdesk.json + fileDir: ${{ github.workspace }} + encodedString: ${{ secrets.MACOS_NOTARIZE_JSON }} + + - name: Install rcodesign tool + shell: bash + run: | + pushd /tmp + wget https://github.com/indygreg/apple-platform-rs/releases/download/apple-codesign%2F0.22.0/apple-codesign-0.22.0-macos-universal.tar.gz + tar -zxvf apple-codesign-0.22.0-macos-universal.tar.gz + mv apple-codesign-0.22.0-macos-universal/rcodesign /usr/local/bin + popd + - name: Install build runtime run: | brew install llvm create-dmg nasm yasm cmake gcc wget ninja @@ -232,6 +248,8 @@ jobs: codesign --force -s ${{ secrets.MACOS_CODESIGN_IDENTITY }} --deep ./flutter/build/macos/Build/Products/Release/rustdesk.app -v create-dmg rustdesk-${{ env.VERSION }}.dmg ./flutter/build/macos/Build/Products/Release/rustdesk.app codesign --force -s ${{ secrets.MACOS_CODESIGN_IDENTITY }} --deep rustdesk-${{ env.VERSION }}.dmg -v + # notarize the rustdesk-${{ env.VERSION }}.dmg + rcodesign notary-submit --api-key-path ${{ github.workspace }}/rustdesk.json --staple rustdesk-${{ env.VERSION }}.dmg - name: Rename rustdesk run: | diff --git a/flutter/macos/Runner.xcodeproj/project.pbxproj b/flutter/macos/Runner.xcodeproj/project.pbxproj index e375623f0..1274ec932 100644 --- a/flutter/macos/Runner.xcodeproj/project.pbxproj +++ b/flutter/macos/Runner.xcodeproj/project.pbxproj @@ -436,8 +436,11 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = ""; + ENABLE_HARDENED_RUNTIME = YES; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -558,15 +561,15 @@ MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = NO; ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; OTHER_LDFLAGS = ( "-sectcreate", __CGPreLoginApp, __cgpreloginapp, /dev/null, ); + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; }; name = Release; }; @@ -577,8 +580,11 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = ""; + ENABLE_HARDENED_RUNTIME = YES; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -604,8 +610,11 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = ""; + ENABLE_HARDENED_RUNTIME = YES; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -616,16 +625,16 @@ ../../target/release, ); MACOSX_DEPLOYMENT_TARGET = 10.14; - PRODUCT_BUNDLE_IDENTIFIER = com.carriez.rustdesk; - PROVISIONING_PROFILE_SPECIFIER = ""; - "SWIFT_OBJC_BRIDGING_HEADER[arch=*]" = Runner/bridge_generated.h; - SWIFT_VERSION = 5.0; OTHER_LDFLAGS = ( "-sectcreate", __CGPreLoginApp, __cgpreloginapp, /dev/null, ); + PRODUCT_BUNDLE_IDENTIFIER = com.carriez.rustdesk; + PROVISIONING_PROFILE_SPECIFIER = ""; + "SWIFT_OBJC_BRIDGING_HEADER[arch=*]" = Runner/bridge_generated.h; + SWIFT_VERSION = 5.0; }; name = Release; }; diff --git a/flutter/macos/Runner/DebugProfile.entitlements b/flutter/macos/Runner/DebugProfile.entitlements index 9f56413f3..b52c39df4 100644 --- a/flutter/macos/Runner/DebugProfile.entitlements +++ b/flutter/macos/Runner/DebugProfile.entitlements @@ -6,6 +6,8 @@ com.apple.security.cs.allow-jit + com.apple.security.device.audio-input + com.apple.security.network.server diff --git a/flutter/macos/Runner/Release.entitlements b/flutter/macos/Runner/Release.entitlements index 08ba3a3fa..7f588d928 100644 --- a/flutter/macos/Runner/Release.entitlements +++ b/flutter/macos/Runner/Release.entitlements @@ -4,6 +4,10 @@ com.apple.security.app-sandbox + com.apple.security.cs.allow-jit + + com.apple.security.device.audio-input + com.apple.security.network.client From 632a981a84e0b6ca5be2d1f3ca2f5c6e5fb78209 Mon Sep 17 00:00:00 2001 From: kingtous Date: Thu, 5 Jan 2023 22:47:47 +0800 Subject: [PATCH 15/40] fix: enable hardened runtime in whole project --- flutter/macos/Runner.xcodeproj/project.pbxproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/flutter/macos/Runner.xcodeproj/project.pbxproj b/flutter/macos/Runner.xcodeproj/project.pbxproj index 1274ec932..b935ab4b2 100644 --- a/flutter/macos/Runner.xcodeproj/project.pbxproj +++ b/flutter/macos/Runner.xcodeproj/project.pbxproj @@ -411,6 +411,7 @@ CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_HARDENED_RUNTIME = YES; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -495,6 +496,7 @@ CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_HARDENED_RUNTIME = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -549,6 +551,7 @@ CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_HARDENED_RUNTIME = YES; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu11; From 1083f5cfca34d3ad20f44c39f2443dfa8cd53b88 Mon Sep 17 00:00:00 2001 From: kingtous Date: Fri, 6 Jan 2023 10:23:46 +0800 Subject: [PATCH 16/40] opt: use macos latest host runner --- .github/workflows/flutter-nightly.yml | 5 ++--- build.py | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/flutter-nightly.yml b/.github/workflows/flutter-nightly.yml index d2a256d91..5fd0755fd 100644 --- a/.github/workflows/flutter-nightly.yml +++ b/.github/workflows/flutter-nightly.yml @@ -142,7 +142,7 @@ jobs: job: - { target: x86_64-apple-darwin, - os: macos-10.15, + os: macos-latest, extra-build-args: "", } steps: @@ -186,7 +186,6 @@ jobs: with: channel: "stable" flutter-version: ${{ env.FLUTTER_VERSION }} - cache: true - name: Install Rust toolchain uses: actions-rs/toolchain@v1 @@ -246,7 +245,7 @@ jobs: # start sign the rustdesk.app and dmg rm rustdesk-${{ env.VERSION }}.dmg || true codesign --force -s ${{ secrets.MACOS_CODESIGN_IDENTITY }} --deep ./flutter/build/macos/Build/Products/Release/rustdesk.app -v - create-dmg rustdesk-${{ env.VERSION }}.dmg ./flutter/build/macos/Build/Products/Release/rustdesk.app + create-dmg --icon "rustdesk.app" 200 190 --hide-extension "rustdesk.app" --window-size 800 400 --app-drop-link 600 185 rustdesk-${{ env.VERSION }}.dmg ./flutter/build/macos/Build/Products/Release/rustdesk.app codesign --force -s ${{ secrets.MACOS_CODESIGN_IDENTITY }} --deep rustdesk-${{ env.VERSION }}.dmg -v # notarize the rustdesk-${{ env.VERSION }}.dmg rcodesign notary-submit --api-key-path ${{ github.workspace }}/rustdesk.json --staple rustdesk-${{ env.VERSION }}.dmg diff --git a/build.py b/build.py index f0131ad27..75d6fcd89 100755 --- a/build.py +++ b/build.py @@ -305,7 +305,8 @@ def build_flutter_deb(version, features): def build_flutter_dmg(version, features): if not skip_cargo: - os.system(f'cargo build --features {features} --lib --release') + # set minimum osx build target, now is 10.14, which is the same as the flutter xcode project + os.system(f'MACOSX_DEPLOYMENT_TARGET=10.14 cargo build --features {features} --lib --release') # copy dylib os.system( "cp target/release/liblibrustdesk.dylib target/release/librustdesk.dylib") From 04c457aa4e35dd1d05b4a820f9de0e75527ac24c Mon Sep 17 00:00:00 2001 From: kingtous Date: Fri, 6 Jan 2023 10:40:04 +0800 Subject: [PATCH 17/40] opt: speed up macos bridge ci speed --- .github/workflows/flutter-nightly.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/flutter-nightly.yml b/.github/workflows/flutter-nightly.yml index 5fd0755fd..d7fcb19d1 100644 --- a/.github/workflows/flutter-nightly.yml +++ b/.github/workflows/flutter-nightly.yml @@ -204,8 +204,12 @@ jobs: run: | dart pub global activate ffigen --version 5.0.1 # flutter_rust_bridge - pushd /tmp && git clone https://github.com/SoLongAndThanksForAllThePizza/flutter_rust_bridge --depth=1 && popd - pushd /tmp/flutter_rust_bridge/frb_codegen && cargo install --path . && popd + pushd /tmp + wget https://github.com/Kingtous/flutter_rust_bridge/releases/download/1.32.0-rustdesk/flutter_rust_bridge_codegen-x86_64-darwin.tgz + tar -zxvf flutter_rust_bridge_codegen-x86_64-darwin.tgz + mkdir -p ~/.cargo/bin + mv flutter_rust_bridge_codegen ~/.cargo/bin; chmod +x ~/.cargo/bin/flutter_rust_bridge_codegen + popd pushd flutter && flutter pub get && popd ~/.cargo/bin/flutter_rust_bridge_codegen --rust-input ./src/flutter_ffi.rs --dart-output ./flutter/lib/generated_bridge.dart From 98dec7b2efcccb2b1d27973ca4ffa9756af310d3 Mon Sep 17 00:00:00 2001 From: kingtous Date: Fri, 6 Jan 2023 11:14:54 +0800 Subject: [PATCH 18/40] opt: codesign with runtime option --- .github/workflows/flutter-nightly.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/flutter-nightly.yml b/.github/workflows/flutter-nightly.yml index d7fcb19d1..79e7db255 100644 --- a/.github/workflows/flutter-nightly.yml +++ b/.github/workflows/flutter-nightly.yml @@ -223,10 +223,6 @@ jobs: run: | $VCPKG_ROOT/vcpkg install libvpx libyuv opus - - name: Install cargo bundle tools - run: | - cargo install cargo-bundle - - name: Show version information (Rust, cargo, Clang) shell: bash run: | @@ -248,9 +244,9 @@ jobs: security unlock-keychain -p ${{ secrets.MACOS_P12_PASSWORD }} rustdesk.keychain # start sign the rustdesk.app and dmg rm rustdesk-${{ env.VERSION }}.dmg || true - codesign --force -s ${{ secrets.MACOS_CODESIGN_IDENTITY }} --deep ./flutter/build/macos/Build/Products/Release/rustdesk.app -v + codesign --force --options runtime -s ${{ secrets.MACOS_CODESIGN_IDENTITY }} --deep ./flutter/build/macos/Build/Products/Release/rustdesk.app -v create-dmg --icon "rustdesk.app" 200 190 --hide-extension "rustdesk.app" --window-size 800 400 --app-drop-link 600 185 rustdesk-${{ env.VERSION }}.dmg ./flutter/build/macos/Build/Products/Release/rustdesk.app - codesign --force -s ${{ secrets.MACOS_CODESIGN_IDENTITY }} --deep rustdesk-${{ env.VERSION }}.dmg -v + codesign --force --options runtime -s ${{ secrets.MACOS_CODESIGN_IDENTITY }} --deep rustdesk-${{ env.VERSION }}.dmg -v # notarize the rustdesk-${{ env.VERSION }}.dmg rcodesign notary-submit --api-key-path ${{ github.workspace }}/rustdesk.json --staple rustdesk-${{ env.VERSION }}.dmg From b3c8579102ccb7ca2aa6be8d50568237d7a361a2 Mon Sep 17 00:00:00 2001 From: kingtous Date: Fri, 6 Jan 2023 11:55:48 +0800 Subject: [PATCH 19/40] opt: add notarize doc --- .github/workflows/flutter-nightly.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/flutter-nightly.yml b/.github/workflows/flutter-nightly.yml index 79e7db255..7ce940b89 100644 --- a/.github/workflows/flutter-nightly.yml +++ b/.github/workflows/flutter-nightly.yml @@ -164,6 +164,7 @@ jobs: - name: Import notarize key uses: timheuer/base64-to-file@v1.2 with: + # https://gregoryszorc.com/docs/apple-codesign/stable/apple_codesign_rcodesign.html#notarizing-and-stapling fileName: rustdesk.json fileDir: ${{ github.workspace }} encodedString: ${{ secrets.MACOS_NOTARIZE_JSON }} From b048e5b2808ee7850687f18d3c8ec8fb80e76143 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Fri, 6 Jan 2023 12:20:26 +0800 Subject: [PATCH 20/40] adding input monitoring priviledge detect for mac --- build.rs | 16 +++++++++++++--- src/flutter_ffi.rs | 4 ++++ src/platform/macos.mm | 34 ++++++++++++++++++++++++++++++++++ src/platform/macos.rs | 8 ++++++++ src/{ => platform}/windows.cc | 0 src/ui_interface.rs | 8 ++++++++ 6 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 src/platform/macos.mm rename src/{ => platform}/windows.cc (100%) diff --git a/build.rs b/build.rs index 67e40752c..ade63f0bc 100644 --- a/build.rs +++ b/build.rs @@ -1,9 +1,16 @@ #[cfg(windows)] fn build_windows() { - cc::Build::new().file("src/windows.cc").compile("windows"); + let file = "src/platform/windows.cc"; + cc::Build::new().file(file).compile("windows"); println!("cargo:rustc-link-lib=WtsApi32"); - println!("cargo:rerun-if-changed=build.rs"); - println!("cargo:rerun-if-changed=windows.cc"); + println!("cargo:rerun-if-changed={}", file); +} + +#[cfg(target_os = "macos")] +fn build_mac() { + let file = "src/platform/macos.mm"; + cc::Build::new().file(file).compile("macos"); + println!("cargo:rerun-if-changed={}", file); } #[cfg(all(windows, feature = "inline"))] @@ -117,5 +124,8 @@ fn main() { #[cfg(windows)] build_windows(); #[cfg(target_os = "macos")] + build_mac(); + #[cfg(target_os = "macos")] println!("cargo:rustc-link-lib=framework=ApplicationServices"); + println!("cargo:rerun-if-changed=build.rs"); } diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index 25161e1e3..92f1e0606 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -1113,6 +1113,10 @@ pub fn main_is_can_screen_recording(prompt: bool) -> SyncReturn { SyncReturn(is_can_screen_recording(prompt)) } +pub fn main_is_can_input_monitoring(prompt: bool) -> SyncReturn { + SyncReturn(is_can_input_monitoring(prompt)) +} + pub fn main_is_share_rdp() -> SyncReturn { SyncReturn(is_share_rdp()) } diff --git a/src/platform/macos.mm b/src/platform/macos.mm new file mode 100644 index 000000000..b82b269e2 --- /dev/null +++ b/src/platform/macos.mm @@ -0,0 +1,34 @@ +#import +#import +#import + +extern "C" bool InputMonitoringAuthStatus(bool prompt) { + if (@available(macos 10.15, *)) { + IOHIDAccessType theType = IOHIDCheckAccess(kIOHIDRequestTypeListenEvent); + NSLog(@"IOHIDCheckAccess = %d", theType); + switch (theType) { + case kIOHIDAccessTypeGranted: + return true; + break; + case kIOHIDAccessTypeDenied: { + if (prompt) { + NSString *urlString = @"x-apple.systempreferences:com.apple.preference.security?Privacy_ListenEvent"; + [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:urlString]]; + } + break; + } + case kIOHIDAccessTypeUnknown: { + if (prompt) { + bool result = IOHIDRequestAccess(kIOHIDRequestTypeListenEvent); + NSLog(@"IOHIDRequestAccess result = %d", result); + } + break; + } + default: + break; + } + } else { + return true; + } + return false; +} diff --git a/src/platform/macos.rs b/src/platform/macos.rs index 0bbec399c..62fa1ee25 100644 --- a/src/platform/macos.rs +++ b/src/platform/macos.rs @@ -32,6 +32,7 @@ extern "C" { fn CGEventGetLocation(e: *const c_void) -> CGPoint; static kAXTrustedCheckOptionPrompt: CFStringRef; fn AXIsProcessTrustedWithOptions(options: CFDictionaryRef) -> BOOL; + fn InputMonitoringAuthStatus(_: BOOL) -> BOOL; } pub fn is_process_trusted(prompt: bool) -> bool { @@ -47,6 +48,13 @@ pub fn is_process_trusted(prompt: bool) -> bool { } } +pub fn is_can_input_monitoring(prompt: bool) -> bool { + unsafe { + let value = if prompt { YES } else { NO }; + InputMonitoringAuthStatus(value) == YES + } +} + // macOS >= 10.15 // https://stackoverflow.com/questions/56597221/detecting-screen-recording-settings-on-macos-catalina/ // remove just one app from all the permissions: tccutil reset All com.carriez.rustdesk diff --git a/src/windows.cc b/src/platform/windows.cc similarity index 100% rename from src/windows.cc rename to src/platform/windows.cc diff --git a/src/ui_interface.rs b/src/ui_interface.rs index 2e4ca4ea3..3b7d1c2c0 100644 --- a/src/ui_interface.rs +++ b/src/ui_interface.rs @@ -582,6 +582,14 @@ pub fn is_installed_daemon(_prompt: bool) -> bool { return true; } +#[inline] +pub fn is_can_input_monitoring(_prompt: bool) -> bool { + #[cfg(target_os = "macos")] + return crate::platform::macos::is_can_input_monitoring(_prompt); + #[cfg(not(target_os = "macos"))] + return true; +} + #[inline] pub fn get_error() -> String { #[cfg(not(any(feature = "cli")))] From 84e4389943142441724b2df92fca76e5399321ee Mon Sep 17 00:00:00 2001 From: Amy Parker Date: Thu, 5 Jan 2023 20:32:53 -0800 Subject: [PATCH 21/40] remove unnecessary allow block Patch #2701 (609117c: "ignore style warnings in libs/scrap") was merged, but the RustDesk team decided to later instead changed is_cursor_embedded to uppercase (see discussion on the PR), thus no longer triggering the warning and no longer needing the allow block. This was changed in (b723f84: "fix linux to mac, keyboard input"). This patch removes the now unnecessary allowances. Signed-off-by: Amy Parker Cc: fufseou --- libs/scrap/src/common/wayland.rs | 1 - libs/scrap/src/common/x11.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/libs/scrap/src/common/wayland.rs b/libs/scrap/src/common/wayland.rs index 3efaed36e..e625fca7e 100644 --- a/libs/scrap/src/common/wayland.rs +++ b/libs/scrap/src/common/wayland.rs @@ -4,7 +4,6 @@ use std::{io, sync::RwLock, time::Duration}; pub struct Capturer(Display, Box, bool, Vec); -#[allow(non_upper_case_globals)] pub const IS_CURSOR_EMBEDDED: bool = true; lazy_static::lazy_static! { diff --git a/libs/scrap/src/common/x11.rs b/libs/scrap/src/common/x11.rs index ffeb1b55f..61112bff7 100644 --- a/libs/scrap/src/common/x11.rs +++ b/libs/scrap/src/common/x11.rs @@ -3,7 +3,6 @@ use std::{io, ops, time::Duration}; pub struct Capturer(x11::Capturer); -#[allow(non_upper_case_globals)] pub const IS_CURSOR_EMBEDDED: bool = false; impl Capturer { From ce5b49b7dd3c2418eaa1ccb1c53ef2fbd2e3bc4a Mon Sep 17 00:00:00 2001 From: rustdesk Date: Fri, 6 Jan 2023 12:42:16 +0800 Subject: [PATCH 22/40] add config_input --- flutter/pubspec.lock | 91 +++++++++++++++++++++++-------------------- src/lang/ca.rs | 1 + src/lang/cn.rs | 17 ++++---- src/lang/cs.rs | 1 + src/lang/da.rs | 1 + src/lang/de.rs | 1 + src/lang/en.rs | 3 +- src/lang/eo.rs | 1 + src/lang/es.rs | 1 + src/lang/fa.rs | 1 + src/lang/fr.rs | 1 + src/lang/gr.rs | 1 + src/lang/hu.rs | 1 + src/lang/id.rs | 1 + src/lang/it.rs | 1 + src/lang/ja.rs | 1 + src/lang/ko.rs | 1 + src/lang/kz.rs | 1 + src/lang/pl.rs | 1 + src/lang/pt_PT.rs | 1 + src/lang/ptbr.rs | 1 + src/lang/ru.rs | 1 + src/lang/sk.rs | 1 + src/lang/sl.rs | 3 ++ src/lang/sq.rs | 1 + src/lang/sr.rs | 1 + src/lang/sv.rs | 1 + src/lang/template.rs | 1 + src/lang/th.rs | 1 + src/lang/tr.rs | 1 + src/lang/tw.rs | 1 + src/lang/ua.rs | 1 + src/lang/vn.rs | 1 + src/platform/macos.mm | 2 + 34 files changed, 94 insertions(+), 51 deletions(-) diff --git a/flutter/pubspec.lock b/flutter/pubspec.lock index bcbad530c..807f932bb 100644 --- a/flutter/pubspec.lock +++ b/flutter/pubspec.lock @@ -35,7 +35,7 @@ packages: name: archive url: "https://pub.dartlang.org" source: hosted - version: "3.3.1" + version: "3.3.5" args: dependency: transitive description: @@ -63,7 +63,7 @@ packages: name: back_button_interceptor url: "https://pub.dartlang.org" source: hosted - version: "6.0.1" + version: "6.0.2" bot_toast: dependency: "direct main" description: @@ -84,7 +84,7 @@ packages: name: build_config url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.1" build_daemon: dependency: transitive description: @@ -105,14 +105,14 @@ packages: name: build_runner url: "https://pub.dartlang.org" source: hosted - version: "2.2.1" + version: "2.3.3" build_runner_core: dependency: transitive description: name: build_runner_core url: "https://pub.dartlang.org" source: hosted - version: "7.2.4" + version: "7.2.7" built_collection: dependency: transitive description: @@ -126,7 +126,7 @@ packages: name: built_value url: "https://pub.dartlang.org" source: hosted - version: "8.4.1" + version: "8.4.2" cached_network_image: dependency: transitive description: @@ -154,7 +154,7 @@ packages: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.2.1" + version: "1.2.0" charcode: dependency: transitive description: @@ -175,14 +175,14 @@ packages: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.1.1" + version: "1.1.0" code_builder: dependency: transitive description: name: code_builder url: "https://pub.dartlang.org" source: hosted - version: "4.3.0" + version: "4.4.0" collection: dependency: transitive description: @@ -203,7 +203,7 @@ packages: name: convert url: "https://pub.dartlang.org" source: hosted - version: "3.0.2" + version: "3.1.0" cross_file: dependency: transitive description: @@ -352,7 +352,7 @@ packages: name: file_picker url: "https://pub.dartlang.org" source: hosted - version: "5.2.3" + version: "5.2.4" fixnum: dependency: transitive description: @@ -441,7 +441,7 @@ packages: name: flutter_svg url: "https://pub.dartlang.org" source: hosted - version: "1.1.5" + version: "1.1.6" flutter_web_plugins: dependency: transitive description: flutter @@ -467,7 +467,7 @@ packages: name: frontend_server_client url: "https://pub.dartlang.org" source: hosted - version: "2.1.3" + version: "3.2.0" get: dependency: "direct main" description: @@ -481,21 +481,21 @@ packages: name: glob url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.1.1" graphs: dependency: transitive description: name: graphs url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.2.0" html: dependency: transitive description: name: html url: "https://pub.dartlang.org" source: hosted - version: "0.15.0" + version: "0.15.1" http: dependency: "direct main" description: @@ -516,7 +516,7 @@ packages: name: http_parser url: "https://pub.dartlang.org" source: hosted - version: "4.0.1" + version: "4.0.2" icons_launcher: dependency: "direct dev" description: @@ -530,7 +530,7 @@ packages: name: image url: "https://pub.dartlang.org" source: hosted - version: "3.2.0" + version: "3.2.2" image_picker: dependency: "direct main" description: @@ -544,7 +544,7 @@ packages: name: image_picker_android url: "https://pub.dartlang.org" source: hosted - version: "0.8.5+3" + version: "0.8.5+4" image_picker_for_web: dependency: transitive description: @@ -558,7 +558,7 @@ packages: name: image_picker_ios url: "https://pub.dartlang.org" source: hosted - version: "0.8.6+1" + version: "0.8.6+3" image_picker_platform_interface: dependency: transitive description: @@ -600,7 +600,7 @@ packages: name: lints url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.0.1" logging: dependency: transitive description: @@ -621,14 +621,14 @@ packages: name: material_color_utilities url: "https://pub.dartlang.org" source: hosted - version: "0.1.5" + version: "0.1.4" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.8.0" + version: "1.7.0" mime: dependency: transitive description: @@ -705,7 +705,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.2" + version: "1.8.1" path_drawing: dependency: transitive description: @@ -733,7 +733,7 @@ packages: name: path_provider_android url: "https://pub.dartlang.org" source: hosted - version: "2.0.20" + version: "2.0.22" path_provider_ios: dependency: transitive description: @@ -797,6 +797,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.3" + pointycastle: + dependency: transitive + description: + name: pointycastle + url: "https://pub.dartlang.org" + source: hosted + version: "3.6.2" pool: dependency: transitive description: @@ -817,14 +824,14 @@ packages: name: provider url: "https://pub.dartlang.org" source: hosted - version: "6.0.3" + version: "6.0.5" pub_semver: dependency: transitive description: name: pub_semver url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" + version: "2.1.3" pubspec_parse: dependency: transitive description: @@ -845,7 +852,7 @@ packages: name: rxdart url: "https://pub.dartlang.org" source: hosted - version: "0.27.5" + version: "0.27.7" screen_retriever: dependency: transitive description: @@ -882,7 +889,7 @@ packages: name: shelf_web_socket url: "https://pub.dartlang.org" source: hosted - version: "1.0.2" + version: "1.0.3" simple_observable: dependency: transitive description: @@ -901,7 +908,7 @@ packages: name: source_gen url: "https://pub.dartlang.org" source: hosted - version: "1.2.5" + version: "1.2.6" source_span: dependency: transitive description: @@ -922,7 +929,7 @@ packages: name: sqflite_common url: "https://pub.dartlang.org" source: hosted - version: "2.3.0" + version: "2.4.0" stack_trace: dependency: transitive description: @@ -943,7 +950,7 @@ packages: name: stream_transform url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" + version: "2.1.0" string_scanner: dependency: transitive description: @@ -1034,14 +1041,14 @@ packages: name: url_launcher url: "https://pub.dartlang.org" source: hosted - version: "6.1.6" + version: "6.1.7" url_launcher_android: dependency: transitive description: name: url_launcher_android url: "https://pub.dartlang.org" source: hosted - version: "6.0.19" + version: "6.0.22" url_launcher_ios: dependency: transitive description: @@ -1090,7 +1097,7 @@ packages: name: uuid url: "https://pub.dartlang.org" source: hosted - version: "3.0.6" + version: "3.0.7" vector_math: dependency: transitive description: @@ -1104,35 +1111,35 @@ packages: name: video_player url: "https://pub.dartlang.org" source: hosted - version: "2.4.9" + version: "2.4.10" video_player_android: dependency: transitive description: name: video_player_android url: "https://pub.dartlang.org" source: hosted - version: "2.3.9" + version: "2.3.10" video_player_avfoundation: dependency: transitive description: name: video_player_avfoundation url: "https://pub.dartlang.org" source: hosted - version: "2.3.7" + version: "2.3.8" video_player_platform_interface: dependency: transitive description: name: video_player_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "5.1.4" + version: "6.0.1" video_player_web: dependency: transitive description: name: video_player_web url: "https://pub.dartlang.org" source: hosted - version: "2.0.12" + version: "2.0.13" visibility_detector: dependency: "direct main" description: @@ -1181,7 +1188,7 @@ packages: name: watcher url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "1.0.2" web_socket_channel: dependency: transitive description: @@ -1195,7 +1202,7 @@ packages: name: win32 url: "https://pub.dartlang.org" source: hosted - version: "3.0.0" + version: "3.1.3" win32_registry: dependency: transitive description: diff --git a/src/lang/ca.rs b/src/lang/ca.rs index eb38cd436..4c85bbf0c 100644 --- a/src/lang/ca.rs +++ b/src/lang/ca.rs @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", ""), ("software_render_tip", ""), ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/lang/cn.rs b/src/lang/cn.rs index c5e4407a6..4b7bda3ea 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -7,7 +7,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Password", "密码"), ("Ready", "就绪"), ("Established", "已建立"), - ("connecting_status", "正在接入RustDesk网络..."), + ("connecting_status", "正在接入 RustDesk 网络..."), ("Enable Service", "允许服务"), ("Start Service", "启动服务"), ("Service is running", "服务正在运行"), @@ -138,13 +138,13 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Failed to make direct connection to remote desktop", "无法建立直接连接"), ("Set Password", "设置密码"), ("OS Password", "操作系统密码"), - ("install_tip", "你正在运行未安装版本,由于UAC限制,作为被控端,会在某些情况下无法控制鼠标键盘,或者录制屏幕,请点击下面的按钮将RustDesk安装到系统,从而规避上述问题。"), + ("install_tip", "你正在运行未安装版本,由于UAC限制,作为被控端,会在某些情况下无法控制鼠标键盘,或者录制屏幕,请点击下面的按钮将 RustDesk 安装到系统,从而规避上述问题。"), ("Click to upgrade", "点击这里升级"), ("Click to download", "点击这里下载"), ("Click to update", "点击这里更新"), ("Configure", "配置"), - ("config_acc", "为了能够远程控制你的桌面, 请给予RustDesk\"辅助功能\" 权限。"), - ("config_screen", "为了能够远程访问你的桌面, 请给予RustDesk\"屏幕录制\" 权限。"), + ("config_acc", "为了能够远程控制你的桌面, 请给予 RustDesk \"辅助功能\" 权限。"), + ("config_screen", "为了能够远程访问你的桌面, 请给予 RustDesk \"屏幕录制\" 权限。"), ("Installing ...", "安装 ..."), ("Install", "安装"), ("Installation", "安装"), @@ -273,7 +273,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Do you accept?", "是否接受?"), ("Open System Setting", "打开系统设置"), ("How to get Android input permission?", "如何获取安卓的输入权限?"), - ("android_input_permission_tip1", "為了讓遠程設備通過鼠標或者觸屏控制您的安卓設備,你需要允許RustDesk使用\"無障礙\"服務。"), + ("android_input_permission_tip1", "為了讓遠程設備通過鼠標或者觸屏控制您的安卓設備,你需要允許 RustDesk 使用\"無障礙\"服務。"), ("android_input_permission_tip2", "请在接下来的系统设置页面里,找到并进入 [已安装的服务] 页面,将 [RustDesk Input] 服务开启。"), ("android_new_connection_tip", "收到新的连接控制请求,对方想要控制你当前的设备。"), ("android_service_will_start_tip", "开启录屏权限将自动开启服务,允许其他设备向此设备请求建立连接。"), @@ -298,9 +298,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("In privacy mode", "进入隐私模式"), ("Out privacy mode", "退出隐私模式"), ("Language", "语言"), - ("Keep RustDesk background service", "保持RustDesk后台服务"), + ("Keep RustDesk background service", "保持 RustDesk 后台服务"), ("Ignore Battery Optimizations", "忽略电池优化"), - ("android_open_battery_optimizations_tip", "如需关闭此功能,请在接下来的RustDesk应用设置页面中,找到并进入 [电源] 页面,取消勾选 [不受限制]"), + ("android_open_battery_optimizations_tip", "如需关闭此功能,请在接下来的 RustDesk 应用设置页面中,找到并进入 [电源] 页面,取消勾选 [不受限制]"), ("Connection not allowed", "对方不允许连接"), ("Legacy mode", "传统模式"), ("Map mode", "1:1传输"), @@ -380,7 +380,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Wayland requires higher version of linux distro. Please try X11 desktop or change your OS.", "Wayland 需要更高版本的 linux 发行版。 请尝试 X11 桌面或更改您的操作系统。"), ("JumpLink", "查看"), ("Please Select the screen to be shared(Operate on the peer side).", "请选择要分享的画面(对端操作)。"), - ("Show RustDesk", "显示rustdesk"), + ("Show RustDesk", "显示 RustDesk"), ("This PC", "此电脑"), ("or", "或"), ("Continue with", "使用"), @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", "请选择本地键盘类型"), ("software_render_tip", "如果你使用英伟达显卡, 并且远程窗口在会话建立后会立刻关闭, 那么安装nouveau驱动并且选择使用软件渲染可能会有帮助。重启软件后生效。"), ("Always use software rendering", "使用软件渲染"), + ("config_input", "为了能够通过键盘控制远程桌面, 请给予 RustDesk \"输入监控\" 权限。"), ].iter().cloned().collect(); } diff --git a/src/lang/cs.rs b/src/lang/cs.rs index 18b2673c9..741dd284f 100644 --- a/src/lang/cs.rs +++ b/src/lang/cs.rs @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", ""), ("software_render_tip", ""), ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/lang/da.rs b/src/lang/da.rs index a1e74259c..1783fd16c 100644 --- a/src/lang/da.rs +++ b/src/lang/da.rs @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", ""), ("software_render_tip", ""), ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/lang/de.rs b/src/lang/de.rs index 44404d52f..6ee9fdaf6 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", "Lokalen Tastaturtyp auswählen"), ("software_render_tip", ""), ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/lang/en.rs b/src/lang/en.rs index b8c8f074d..6675ee172 100644 --- a/src/lang/en.rs +++ b/src/lang/en.rs @@ -36,6 +36,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("hide_cm_tip", "Allow hiding only if accepting sessions via password and using permanent password"), ("wayland_experiment_tip", "Wayland support is in experimental stage, please use X11 if you require unattended access."), ("Slogan_tip", "Made with heart in this chaotic world!"), - ("software_render_tip", "If you have an Nvidia graphics card and the remote window closes immediately after connecting, installing the nouveau driver and choosing to use software rendering may help. A software restart is required.") + ("software_render_tip", "If you have an Nvidia graphics card and the remote window closes immediately after connecting, installing the nouveau driver and choosing to use software rendering may help. A software restart is required."), + ("config_input", "In order to control remote desktop with keyboard, you need to grant RustDesk \"Input Monitoring\" permissions."), ].iter().cloned().collect(); } diff --git a/src/lang/eo.rs b/src/lang/eo.rs index 7b32c1708..a4da577c8 100644 --- a/src/lang/eo.rs +++ b/src/lang/eo.rs @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", ""), ("software_render_tip", ""), ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/lang/es.rs b/src/lang/es.rs index 4a9f9251c..56453bd8c 100644 --- a/src/lang/es.rs +++ b/src/lang/es.rs @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", "Seleccionar tipo de teclado local"), ("software_render_tip", ""), ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fa.rs b/src/lang/fa.rs index 8c0c426ed..8d4ba5cb1 100644 --- a/src/lang/fa.rs +++ b/src/lang/fa.rs @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", ""), ("software_render_tip", ""), ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fr.rs b/src/lang/fr.rs index 22b522a9d..d48d5cfae 100644 --- a/src/lang/fr.rs +++ b/src/lang/fr.rs @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", "Selectionner la disposition du clavier local"), ("software_render_tip", ""), ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/lang/gr.rs b/src/lang/gr.rs index 9ca035e65..1ac063cd5 100644 --- a/src/lang/gr.rs +++ b/src/lang/gr.rs @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", ""), ("software_render_tip", ""), ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/lang/hu.rs b/src/lang/hu.rs index 2b81b90eb..be3028283 100644 --- a/src/lang/hu.rs +++ b/src/lang/hu.rs @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", ""), ("software_render_tip", ""), ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/lang/id.rs b/src/lang/id.rs index ecc21b3f0..14eff9458 100644 --- a/src/lang/id.rs +++ b/src/lang/id.rs @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", ""), ("software_render_tip", ""), ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/lang/it.rs b/src/lang/it.rs index 31cfd345e..e82da1d66 100644 --- a/src/lang/it.rs +++ b/src/lang/it.rs @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", "Seleziona il tipo di tastiera locale"), ("software_render_tip", ""), ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ja.rs b/src/lang/ja.rs index 4673d2e41..dc3d81448 100644 --- a/src/lang/ja.rs +++ b/src/lang/ja.rs @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", ""), ("software_render_tip", ""), ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ko.rs b/src/lang/ko.rs index 5d0b8c8a7..11536f0a5 100644 --- a/src/lang/ko.rs +++ b/src/lang/ko.rs @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", ""), ("software_render_tip", ""), ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/lang/kz.rs b/src/lang/kz.rs index 0b55a79ff..b0dd2ff70 100644 --- a/src/lang/kz.rs +++ b/src/lang/kz.rs @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", ""), ("software_render_tip", ""), ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pl.rs b/src/lang/pl.rs index 5ca41e3ac..2641d8358 100644 --- a/src/lang/pl.rs +++ b/src/lang/pl.rs @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", ""), ("software_render_tip", ""), ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pt_PT.rs b/src/lang/pt_PT.rs index 3e203a250..c96aed8b6 100644 --- a/src/lang/pt_PT.rs +++ b/src/lang/pt_PT.rs @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", ""), ("software_render_tip", ""), ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ptbr.rs b/src/lang/ptbr.rs index c17620bc1..03d451662 100644 --- a/src/lang/ptbr.rs +++ b/src/lang/ptbr.rs @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", ""), ("software_render_tip", ""), ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ru.rs b/src/lang/ru.rs index 1fa6d7528..14e04b940 100644 --- a/src/lang/ru.rs +++ b/src/lang/ru.rs @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", "Выберите тип локальной клавиатуры"), ("software_render_tip", ""), ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sk.rs b/src/lang/sk.rs index 13bbcf4f7..1cfff5beb 100644 --- a/src/lang/sk.rs +++ b/src/lang/sk.rs @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", ""), ("software_render_tip", ""), ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sl.rs b/src/lang/sl.rs index 7cd8f0c98..8761db113 100755 --- a/src/lang/sl.rs +++ b/src/lang/sl.rs @@ -405,5 +405,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", "Ročno zaprto iz spletne konzole"), ("Local keyboard type", "Lokalna vrsta tipkovnice"), ("Select local keyboard type", "Izberite lokalno vrsto tipkovnice"), + ("software_render_tip", ""), + ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sq.rs b/src/lang/sq.rs index d08036bf3..b277c6f2d 100644 --- a/src/lang/sq.rs +++ b/src/lang/sq.rs @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", ""), ("software_render_tip", ""), ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sr.rs b/src/lang/sr.rs index f9386004d..cc418d305 100644 --- a/src/lang/sr.rs +++ b/src/lang/sr.rs @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", ""), ("software_render_tip", ""), ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sv.rs b/src/lang/sv.rs index 9f2d1c9f4..0a41387c7 100644 --- a/src/lang/sv.rs +++ b/src/lang/sv.rs @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", ""), ("software_render_tip", ""), ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/lang/template.rs b/src/lang/template.rs index 145cf45bb..87a1563d7 100644 --- a/src/lang/template.rs +++ b/src/lang/template.rs @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", ""), ("software_render_tip", ""), ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/lang/th.rs b/src/lang/th.rs index d6bbe806d..6a98613ed 100644 --- a/src/lang/th.rs +++ b/src/lang/th.rs @@ -407,6 +407,7 @@ lazy_static::lazy_static! { ("Select local keyboard type", "เลือกประเภทคีย์บอร์ด"), ("software_render_tip", ""), ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } \ No newline at end of file diff --git a/src/lang/tr.rs b/src/lang/tr.rs index 00c620c34..931bcec6d 100644 --- a/src/lang/tr.rs +++ b/src/lang/tr.rs @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", ""), ("software_render_tip", ""), ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tw.rs b/src/lang/tw.rs index cb83d28ea..847edb599 100644 --- a/src/lang/tw.rs +++ b/src/lang/tw.rs @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", "請選擇本地鍵盤類型"), ("software_render_tip", "如果你使用英偉達顯卡, 並且遠程窗口在會話建立後會立刻關閉, 那麼安裝nouveau驅動並且選擇使用軟件渲染可能會有幫助。重啟軟件後生效。"), ("Always use software rendering", "使用軟件渲染"), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ua.rs b/src/lang/ua.rs index 1c6ac5828..65ae32d68 100644 --- a/src/lang/ua.rs +++ b/src/lang/ua.rs @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", ""), ("software_render_tip", ""), ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/lang/vn.rs b/src/lang/vn.rs index d2e067b3b..eab0b3497 100644 --- a/src/lang/vn.rs +++ b/src/lang/vn.rs @@ -407,5 +407,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Select local keyboard type", ""), ("software_render_tip", ""), ("Always use software rendering", ""), + ("config_input", ""), ].iter().cloned().collect(); } diff --git a/src/platform/macos.mm b/src/platform/macos.mm index b82b269e2..e6e1723a7 100644 --- a/src/platform/macos.mm +++ b/src/platform/macos.mm @@ -2,6 +2,8 @@ #import #import +// https://github.com/codebytere/node-mac-permissions/blob/main/permissions.mm + extern "C" bool InputMonitoringAuthStatus(bool prompt) { if (@available(macos 10.15, *)) { IOHIDAccessType theType = IOHIDCheckAccess(kIOHIDRequestTypeListenEvent); From 584295f3fadcb065ab9e63bb11f6ddfade99bdc5 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Fri, 6 Jan 2023 13:19:08 +0800 Subject: [PATCH 23/40] config_input not well tested yet --- flutter/lib/desktop/pages/desktop_home_page.dart | 13 +++++++++++++ src/platform/macos.mm | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/flutter/lib/desktop/pages/desktop_home_page.dart b/flutter/lib/desktop/pages/desktop_home_page.dart index 1e8512b2e..43ffbd1e3 100644 --- a/flutter/lib/desktop/pages/desktop_home_page.dart +++ b/flutter/lib/desktop/pages/desktop_home_page.dart @@ -42,6 +42,7 @@ class _DesktopHomePageState extends State var svcStopped = false.obs; var watchIsCanScreenRecording = false; var watchIsProcessTrust = false; + var watchIsInputMonitoring = false; Timer? _updateTimer; @override @@ -334,6 +335,12 @@ class _DesktopHomePageState extends State bind.mainIsProcessTrusted(prompt: true); watchIsProcessTrust = true; }, help: 'Help', link: translate("doc_mac_permission")); + } else if (!bind.mainIsCanInputMonitoring(prompt: false)) { + return buildInstallCard("Permissions", "config_input", "Configure", + () async { + bind.mainIsCanInputMonitoring(prompt: true); + watchIsInputMonitoring = true; + }, help: 'Help', link: translate("doc_mac_permission")); } else if (!svcStopped.value && bind.mainIsInstalled() && !bind.mainIsInstalledDaemon(prompt: false)) { @@ -467,6 +474,12 @@ class _DesktopHomePageState extends State setState(() {}); } } + if (watchIsInputMonitoring) { + if (bind.mainIsCanInputMonitoring(prompt: false)) { + watchIsInputMonitoring = false; + setState(() {}); + } + } }); Get.put(svcStopped, tag: 'stop-service'); rustDeskWinManager.registerActiveWindowListener(onActiveWindowChanged); diff --git a/src/platform/macos.mm b/src/platform/macos.mm index e6e1723a7..05653ec33 100644 --- a/src/platform/macos.mm +++ b/src/platform/macos.mm @@ -7,7 +7,7 @@ extern "C" bool InputMonitoringAuthStatus(bool prompt) { if (@available(macos 10.15, *)) { IOHIDAccessType theType = IOHIDCheckAccess(kIOHIDRequestTypeListenEvent); - NSLog(@"IOHIDCheckAccess = %d", theType); + NSLog(@"IOHIDCheckAccess = %d, kIOHIDAccessTypeGranted = %d", theType, kIOHIDAccessTypeGranted); switch (theType) { case kIOHIDAccessTypeGranted: return true; From 5a91701d3d44f1312b68c8a575d28ae5e4563bf4 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Fri, 6 Jan 2023 15:37:15 +0800 Subject: [PATCH 24/40] fix ci --- src/platform/macos.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/macos.mm b/src/platform/macos.mm index 05653ec33..c25a854cc 100644 --- a/src/platform/macos.mm +++ b/src/platform/macos.mm @@ -5,7 +5,7 @@ // https://github.com/codebytere/node-mac-permissions/blob/main/permissions.mm extern "C" bool InputMonitoringAuthStatus(bool prompt) { - if (@available(macos 10.15, *)) { + if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_15) { IOHIDAccessType theType = IOHIDCheckAccess(kIOHIDRequestTypeListenEvent); NSLog(@"IOHIDCheckAccess = %d, kIOHIDAccessTypeGranted = %d", theType, kIOHIDAccessTypeGranted); switch (theType) { From 56e699a5e63f2a0156d12a53ba10fecabb16c162 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Fri, 6 Jan 2023 17:10:38 +0800 Subject: [PATCH 25/40] adjust input style of "enter id" --- flutter/lib/desktop/pages/connection_page.dart | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index 7500fe99e..939acfbc5 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -6,7 +6,6 @@ import 'dart:io'; import 'package:auto_size_text/auto_size_text.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_hbb/common/widgets/address_book.dart'; import 'package:flutter_hbb/consts.dart'; import 'package:flutter_hbb/desktop/widgets/scroll_wrapper.dart'; import 'package:get/get.dart'; @@ -16,7 +15,6 @@ import 'package:window_manager/window_manager.dart'; import '../../common.dart'; import '../../common/formatter/id_formatter.dart'; import '../../common/widgets/peer_tab_page.dart'; -import '../../common/widgets/peers_view.dart'; import '../../models/platform_model.dart'; import '../widgets/button.dart'; @@ -172,6 +170,7 @@ class _ConnectionPageState extends State Expanded( child: Obx( () => TextField( + maxLength: 90, autocorrect: false, enableSuggestions: false, keyboardType: TextInputType.visiblePassword, @@ -179,7 +178,7 @@ class _ConnectionPageState extends State style: const TextStyle( fontFamily: 'WorkSans', fontSize: 22, - height: 1, + height: 1.25, ), maxLines: 1, cursorColor: From c5e39f4bbbc9be670b793fb3dd01e68c87dd44ad Mon Sep 17 00:00:00 2001 From: sj6219 Date: Fri, 6 Jan 2023 20:07:43 +0900 Subject: [PATCH 26/40] windows extended key --- libs/enigo/src/win/win_impl.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/libs/enigo/src/win/win_impl.rs b/libs/enigo/src/win/win_impl.rs index fb3b9881f..2e1108b9e 100644 --- a/libs/enigo/src/win/win_impl.rs +++ b/libs/enigo/src/win/win_impl.rs @@ -56,6 +56,20 @@ fn keybd_event(flags: u32, vk: u16, scan: u16) -> DWORD { input.type_ = INPUT_KEYBOARD; unsafe { let dst_ptr = (&mut input.u as *mut _) as *mut u8; + let flags = match vk as _ { + winapi::um::winuser::VK_HOME | + winapi::um::winuser::VK_UP | + winapi::um::winuser::VK_PRIOR | + winapi::um::winuser::VK_LEFT | + winapi::um::winuser::VK_RIGHT | + winapi::um::winuser::VK_END | + winapi::um::winuser::VK_DOWN | + winapi::um::winuser::VK_NEXT | + winapi::um::winuser::VK_INSERT | + winapi::um::winuser::VK_DELETE => flags | winapi::um::winuser::KEYEVENTF_EXTENDEDKEY, + _ => flags, + }; + let k = KEYBDINPUT { wVk: vk, wScan: scan, From bdfc429247543d0302c0bcb39ab2dad10aba4e59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jernej=20Simon=C4=8Di=C4=8D?= <1800143+jernejs@users.noreply.github.com> Date: Fri, 6 Jan 2023 13:02:15 +0100 Subject: [PATCH 27/40] Slovenian translation fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jernej Simončič --- src/lang/sl.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/lang/sl.rs b/src/lang/sl.rs index 8761db113..754c25868 100755 --- a/src/lang/sl.rs +++ b/src/lang/sl.rs @@ -85,8 +85,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Refresh File", "Osveži datoteko"), ("Local", "Lokalno"), ("Remote", "Oddaljeno"), - ("Remote Computer", "Lokalni računalnik"), - ("Local Computer", "Oddaljeni računalnik"), + ("Remote Computer", "Oddaljeni računalnik"), + ("Local Computer", "Lokalni računalnik"), ("Confirm Delete", "Potrdi izbris"), ("Delete", "Izbriši"), ("Properties", "Lastnosti"), @@ -124,7 +124,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Disable clipboard", "Onemogoči odložišče"), ("Lock after session end", "Zakleni ob koncu seje"), ("Insert", "Vstavi"), - ("Insert Lock", "Zaklep vstavljanja"), + ("Insert Lock", "Zakleni oddaljeni računalnik"), ("Refresh", "Osveži"), ("ID does not exist", "ID ne obstaja"), ("Failed to connect to rendezvous server", "Ni se bilo mogoče povezati na povezovalni strežnik"), @@ -138,7 +138,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Failed to make direct connection to remote desktop", "Ni bilo mogoče vzpostaviti neposredne povezave z oddaljenim namizjem"), ("Set Password", "Nastavi geslo"), ("OS Password", "Geslo operacijskega sistema"), - ("install_tip", "Zaradi nadzora uporabniškega računa, RustDesk v nekaterih primerih na oddaljeni strani ne deluje pravilno. Temu se lahko izognete z namestitvijo RustDeska."), + ("install_tip", "Zaradi nadzora uporabniškega računa, RustDesk v nekaterih primerih na oddaljeni strani ne deluje pravilno. Temu se lahko izognete z namestitvijo."), ("Click to upgrade", "Klikni za nadgradnjo"), ("Click to download", "Klikni za prenos"), ("Click to update", "Klikni za posodobitev"), @@ -160,7 +160,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Listening ...", "Poslušam ..."), ("Remote Host", "Oddaljeni gostitelj"), ("Remote Port", "Oddaljena vrata"), - ("Action", "Deljanje"), + ("Action", "Dejanje"), ("Add", "Dodaj"), ("Local Port", "Lokalna vrata"), ("Local Address", "Lokalni naslov"), @@ -175,7 +175,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Allow using keyboard and mouse", "Dovoli uporabo tipkovnice in miške"), ("Allow using clipboard", "Dovoli uporabo odložišča"), ("Allow hearing sound", "Dovoli prenos zvoka"), - ("Allow file copy and paste", "Dovoli kopiraj in prilepi"), + ("Allow file copy and paste", "Dovoli kopiranje in lepljenje datotek"), ("Connected", "Povezan"), ("Direct and encrypted connection", "Neposredna šifrirana povezava"), ("Relayed and encrypted connection", "Posredovana šifrirana povezava"), @@ -385,7 +385,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("or", "ali"), ("Continue with", "Nadaljuj z"), ("Elevate", "Povzdig pravic"), - ("Zoom cursor", "Povečaj kazalec miške"), + ("Zoom cursor", "Prilagodi velikost miškinega kazalca"), ("Accept sessions via password", "Sprejmi seje z geslom"), ("Accept sessions via click", "Sprejmi seje s potrditvijo"), ("Accept sessions via both", "Sprejmi seje z geslom ali potrditvijo"), From 921b049e1e6468dd469d8f7e1d46ca69fd253ad1 Mon Sep 17 00:00:00 2001 From: fufesou Date: Fri, 6 Jan 2023 18:14:31 +0800 Subject: [PATCH 28/40] ignore dpi while scale original Signed-off-by: fufesou --- flutter/lib/consts.dart | 2 + flutter/lib/desktop/pages/remote_page.dart | 69 ++++++++----------- .../lib/desktop/widgets/remote_menubar.dart | 22 +++--- flutter/lib/models/model.dart | 34 +++++---- 4 files changed, 61 insertions(+), 66 deletions(-) diff --git a/flutter/lib/consts.dart b/flutter/lib/consts.dart index 50e7f594b..7aa200ae9 100644 --- a/flutter/lib/consts.dart +++ b/flutter/lib/consts.dart @@ -100,6 +100,8 @@ const kRemoteImageQualityLow = 'low'; /// [kRemoteImageQualityCustom] Custom image quality. const kRemoteImageQualityCustom = 'custom'; +const kIgnoreDpi = true; + /// flutter/packages/flutter/lib/src/services/keyboard_key.dart -> _keyLabels /// see [LogicalKeyboardKey.keyLabel] const Map logicalKeyMap = { diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart index 102dc784a..21728ee38 100644 --- a/flutter/lib/desktop/pages/remote_page.dart +++ b/flutter/lib/desktop/pages/remote_page.dart @@ -402,35 +402,38 @@ class _ImagePaintState extends State { onHover: (evt) {}, child: child)); - if (c.scrollStyle == ScrollStyle.scrollbar) { - final imageWidth = c.getDisplayWidth() * s; - final imageHeight = c.getDisplayHeight() * s; + final imageWidth = c.getDisplayWidth() * s; + final imageHeight = c.getDisplayHeight() * s; + final imageSize = Size(imageWidth, imageHeight); + bool overflow = + c.size.width < imageSize.width || c.size.height < imageSize.height; + if (overflow && c.scrollStyle == ScrollStyle.scrollbar) { final imageWidget = CustomPaint( - size: Size(imageWidth, imageHeight), + size: imageSize, painter: ImagePainter(image: m.image, x: 0, y: 0, scale: s), ); return NotificationListener( - onNotification: (notification) { - final percentX = _horizontal.hasClients - ? _horizontal.position.extentBefore / - (_horizontal.position.extentBefore + - _horizontal.position.extentInside + - _horizontal.position.extentAfter) - : 0.0; - final percentY = _vertical.hasClients - ? _vertical.position.extentBefore / - (_vertical.position.extentBefore + - _vertical.position.extentInside + - _vertical.position.extentAfter) - : 0.0; - c.setScrollPercent(percentX, percentY); - return false; - }, - child: mouseRegion( - child: _buildCrossScrollbar(context, _buildListener(imageWidget), - Size(imageWidth, imageHeight))), - ); + onNotification: (notification) { + final percentX = _horizontal.hasClients + ? _horizontal.position.extentBefore / + (_horizontal.position.extentBefore + + _horizontal.position.extentInside + + _horizontal.position.extentAfter) + : 0.0; + final percentY = _vertical.hasClients + ? _vertical.position.extentBefore / + (_vertical.position.extentBefore + + _vertical.position.extentInside + + _vertical.position.extentAfter) + : 0.0; + c.setScrollPercent(percentX, percentY); + return false; + }, + child: mouseRegion( + child: Obx(() => _buildCrossScrollbarFromLayout( + context, _buildListener(imageWidget), c.size, imageSize)), + )); } else { final imageWidget = CustomPaint( size: Size(c.size.width, c.size.height), @@ -565,24 +568,6 @@ class _ImagePaintState extends State { return widget; } - Widget _buildCrossScrollbar(BuildContext context, Widget child, Size size) { - var layoutSize = MediaQuery.of(context).size; - // If minimized, w or h may be negative here. - final w = layoutSize.width - kWindowBorderWidth * 2; - final h = - layoutSize.height - kWindowBorderWidth * 2 - kDesktopRemoteTabBarHeight; - layoutSize = Size( - w < 0 ? 0 : w, - h < 0 ? 0 : h, - ); - bool overflow = - layoutSize.width < size.width || layoutSize.height < size.height; - return overflow - ? Obx(() => - _buildCrossScrollbarFromLayout(context, child, layoutSize, size)) - : _buildCrossScrollbarFromLayout(context, child, layoutSize, size); - } - Widget _buildListener(Widget child) { if (listenerBuilder != null) { return listenerBuilder!(child); diff --git a/flutter/lib/desktop/widgets/remote_menubar.dart b/flutter/lib/desktop/widgets/remote_menubar.dart index 1aa2647ee..2a7a26d08 100644 --- a/flutter/lib/desktop/widgets/remote_menubar.dart +++ b/flutter/lib/desktop/widgets/remote_menubar.dart @@ -699,7 +699,7 @@ class _RemoteMenubarState extends State { if (_screen == null) { return false; } - double scale = _screen!.scaleFactor; + final scale = kIgnoreDpi ? 1.0 : _screen!.scaleFactor; double selfWidth = _screen!.visibleFrame.width; double selfHeight = _screen!.visibleFrame.height; if (isFullscreen) { @@ -986,15 +986,17 @@ class _RemoteMenubarState extends State { wndRect.bottom - wndRect.top - mediaSize.height * scale; final canvasModel = widget.ffi.canvasModel; - final width = (canvasModel.getDisplayWidth() + - canvasModel.windowBorderWidth * 2) * - scale + - magicWidth; - final height = (canvasModel.getDisplayHeight() + - canvasModel.tabBarHeight + - canvasModel.windowBorderWidth * 2) * - scale + - magicHeight; + final width = + (canvasModel.getDisplayWidth() * canvasModel.scale + + canvasModel.windowBorderWidth * 2) * + scale + + magicWidth; + final height = + (canvasModel.getDisplayHeight() * canvasModel.scale + + canvasModel.tabBarHeight + + canvasModel.windowBorderWidth * 2) * + scale + + magicHeight; double left = wndRect.left + (wndRect.width - width) / 2; double top = wndRect.top + (wndRect.height - height) / 2; diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index 0f7099bc8..39e78cd6b 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -528,6 +528,7 @@ class CanvasModel with ChangeNotifier { double _y = 0; // image scale double _scale = 1.0; + Size _size = Size.zero; // the tabbar over the image // double tabBarHeight = 0.0; // the window border's width @@ -548,6 +549,7 @@ class CanvasModel with ChangeNotifier { double get x => _x; double get y => _y; double get scale => _scale; + Size get size => _size; ScrollStyle get scrollStyle => _scrollStyle; ViewStyle get viewStyle => _lastViewStyle; @@ -562,18 +564,26 @@ class CanvasModel with ChangeNotifier { double get scrollY => _scrollY; updateViewStyle() async { + Size getSize() { + final size = MediaQueryData.fromWindow(ui.window).size; + // If minimized, w or h may be negative here. + double w = size.width - windowBorderWidth * 2; + double h = size.height - tabBarHeight - windowBorderWidth * 2; + return Size(w < 0 ? 0 : w, h < 0 ? 0 : h); + } + final style = await bind.sessionGetViewStyle(id: id); if (style == null) { return; } - final sizeWidth = size.width; - final sizeHeight = size.height; + + _size = getSize(); final displayWidth = getDisplayWidth(); final displayHeight = getDisplayHeight(); final viewStyle = ViewStyle( style: style, - width: sizeWidth, - height: sizeHeight, + width: size.width, + height: size.height, displayWidth: displayWidth, displayHeight: displayHeight, ); @@ -585,8 +595,12 @@ class CanvasModel with ChangeNotifier { } _lastViewStyle = viewStyle; _scale = viewStyle.scale; - _x = (sizeWidth - displayWidth * _scale) / 2; - _y = (sizeHeight - displayHeight * _scale) / 2; + + if (kIgnoreDpi && style == kRemoteViewStyleOriginal) { + _scale = 1.0 / ui.window.devicePixelRatio; + } + _x = (size.width - displayWidth * _scale) / 2; + _y = (size.height - displayHeight * _scale) / 2; notifyListeners(); } @@ -628,14 +642,6 @@ class CanvasModel with ChangeNotifier { double get windowBorderWidth => stateGlobal.windowBorderWidth.value; double get tabBarHeight => stateGlobal.tabBarHeight; - Size get size { - final size = MediaQueryData.fromWindow(ui.window).size; - // If minimized, w or h may be negative here. - double w = size.width - windowBorderWidth * 2; - double h = size.height - tabBarHeight - windowBorderWidth * 2; - return Size(w < 0 ? 0 : w, h < 0 ? 0 : h); - } - moveDesktopMouse(double x, double y) { // On mobile platforms, move the canvas with the cursor. final dw = getDisplayWidth() * _scale; From 947b7c9a4d4c2c4ad433b2404ec0b26c61e14120 Mon Sep 17 00:00:00 2001 From: fufesou Date: Fri, 6 Jan 2023 20:25:18 +0800 Subject: [PATCH 29/40] disable scroll options when image is wrapped by window Signed-off-by: fufesou --- flutter/lib/desktop/pages/remote_page.dart | 10 +- flutter/lib/desktop/widgets/popup_menu.dart | 138 ++++++++++-------- .../lib/desktop/widgets/remote_menubar.dart | 3 +- flutter/lib/models/model.dart | 5 + 4 files changed, 90 insertions(+), 66 deletions(-) diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart index 21728ee38..55a5bbaef 100644 --- a/flutter/lib/desktop/pages/remote_page.dart +++ b/flutter/lib/desktop/pages/remote_page.dart @@ -402,12 +402,10 @@ class _ImagePaintState extends State { onHover: (evt) {}, child: child)); - final imageWidth = c.getDisplayWidth() * s; - final imageHeight = c.getDisplayHeight() * s; - final imageSize = Size(imageWidth, imageHeight); - bool overflow = - c.size.width < imageSize.width || c.size.height < imageSize.height; - if (overflow && c.scrollStyle == ScrollStyle.scrollbar) { + if (c.imageOverflow.isTrue && c.scrollStyle == ScrollStyle.scrollbar) { + final imageWidth = c.getDisplayWidth() * s; + final imageHeight = c.getDisplayHeight() * s; + final imageSize = Size(imageWidth, imageHeight); final imageWidget = CustomPaint( size: imageSize, painter: ImagePainter(image: m.image, x: 0, y: 0, scale: s), diff --git a/flutter/lib/desktop/widgets/popup_menu.dart b/flutter/lib/desktop/widgets/popup_menu.dart index 20ab31ed9..0cbdad929 100644 --- a/flutter/lib/desktop/widgets/popup_menu.dart +++ b/flutter/lib/desktop/widgets/popup_menu.dart @@ -118,6 +118,15 @@ abstract class MenuEntryBase { this.enabled, }); List> build(BuildContext context, MenuConfig conf); + + enabledStyle(BuildContext context) => TextStyle( + color: Theme.of(context).textTheme.titleLarge?.color, + fontSize: MenuConfig.fontSize, + fontWeight: FontWeight.normal); + disabledStyle() => TextStyle( + color: Colors.grey, + fontSize: MenuConfig.fontSize, + fontWeight: FontWeight.normal); } class MenuEntryDivider extends MenuEntryBase { @@ -189,54 +198,76 @@ class MenuEntryRadios extends MenuEntryBase { mod_menu.PopupMenuEntry _buildMenuItem( BuildContext context, MenuConfig conf, MenuEntryRadioOption opt) { + Widget getTextChild() { + final enabledTextChild = Text( + opt.text, + style: enabledStyle(context), + ); + final disabledTextChild = Text( + opt.text, + style: disabledStyle(), + ); + if (opt.enabled == null) { + return enabledTextChild; + } else { + return Obx( + () => opt.enabled!.isTrue ? enabledTextChild : disabledTextChild); + } + } + + final child = Container( + padding: padding, + alignment: AlignmentDirectional.centerStart, + constraints: + BoxConstraints(minHeight: conf.height, maxHeight: conf.height), + child: Row( + children: [ + getTextChild(), + Expanded( + child: Align( + alignment: Alignment.centerRight, + child: Transform.scale( + scale: MenuConfig.iconScale, + child: Obx(() => opt.value == curOption.value + ? IconButton( + padding: + const EdgeInsets.fromLTRB(8.0, 0.0, 8.0, 0.0), + hoverColor: Colors.transparent, + focusColor: Colors.transparent, + onPressed: () {}, + icon: Icon( + Icons.check, + color: (opt.enabled ?? true.obs).isTrue + ? conf.commonColor + : Colors.grey, + )) + : const SizedBox.shrink()), + ))), + ], + ), + ); + onPressed() { + if (opt.dismissOnClicked && Navigator.canPop(context)) { + Navigator.pop(context); + } + setOption(opt.value); + } + return mod_menu.PopupMenuItem( padding: EdgeInsets.zero, height: conf.height, child: Container( - width: conf.boxWidth, - child: TextButton( - child: Container( - padding: padding, - alignment: AlignmentDirectional.centerStart, - constraints: BoxConstraints( - minHeight: conf.height, maxHeight: conf.height), - child: Row( - children: [ - Text( - opt.text, - style: TextStyle( - color: Theme.of(context).textTheme.titleLarge?.color, - fontSize: MenuConfig.fontSize, - fontWeight: FontWeight.normal), - ), - Expanded( - child: Align( - alignment: Alignment.centerRight, - child: Transform.scale( - scale: MenuConfig.iconScale, - child: Obx(() => opt.value == curOption.value - ? IconButton( - padding: const EdgeInsets.fromLTRB( - 8.0, 0.0, 8.0, 0.0), - hoverColor: Colors.transparent, - focusColor: Colors.transparent, - onPressed: () {}, - icon: Icon( - Icons.check, - color: conf.commonColor, - )) - : const SizedBox.shrink()), - ))), - ], - ), - ), - onPressed: () { - if (opt.dismissOnClicked && Navigator.canPop(context)) { - Navigator.pop(context); - } - setOption(opt.value); - }, - )), + width: conf.boxWidth, + child: opt.enabled == null + ? TextButton( + child: child, + onPressed: onPressed, + ) + : Obx(() => TextButton( + child: child, + onPressed: opt.enabled!.isTrue ? onPressed : null, + )), + ), ); } @@ -567,12 +598,9 @@ class MenuEntrySubMenu extends MenuEntryBase { const SizedBox(width: MenuConfig.midPadding), Obx(() => Text( text, - style: TextStyle( - color: super.enabled!.value - ? Theme.of(context).textTheme.titleLarge?.color - : Colors.grey, - fontSize: MenuConfig.fontSize, - fontWeight: FontWeight.normal), + style: super.enabled!.value + ? enabledStyle(context) + : disabledStyle(), )), Expanded( child: Align( @@ -605,14 +633,6 @@ class MenuEntryButton extends MenuEntryBase { ); Widget _buildChild(BuildContext context, MenuConfig conf) { - final enabledStyle = TextStyle( - color: Theme.of(context).textTheme.titleLarge?.color, - fontSize: MenuConfig.fontSize, - fontWeight: FontWeight.normal); - const disabledStyle = TextStyle( - color: Colors.grey, - fontSize: MenuConfig.fontSize, - fontWeight: FontWeight.normal); super.enabled ??= true.obs; return Obx(() => Container( width: conf.boxWidth, @@ -631,7 +651,7 @@ class MenuEntryButton extends MenuEntryBase { constraints: BoxConstraints(minHeight: conf.height, maxHeight: conf.height), child: childBuilder( - super.enabled!.value ? enabledStyle : disabledStyle), + super.enabled!.value ? enabledStyle(context) : disabledStyle()), ), ))); } diff --git a/flutter/lib/desktop/widgets/remote_menubar.dart b/flutter/lib/desktop/widgets/remote_menubar.dart index 2a7a26d08..b69c73091 100644 --- a/flutter/lib/desktop/widgets/remote_menubar.dart +++ b/flutter/lib/desktop/widgets/remote_menubar.dart @@ -936,11 +936,13 @@ class _RemoteMenubarState extends State { text: translate('ScrollAuto'), value: kRemoteScrollStyleAuto, dismissOnClicked: true, + enabled: widget.ffi.canvasModel.imageOverflow, ), MenuEntryRadioOption( text: translate('Scrollbar'), value: kRemoteScrollStyleBar, dismissOnClicked: true, + enabled: widget.ffi.canvasModel.imageOverflow, ), ], curOptionGetter: () async => @@ -1200,7 +1202,6 @@ class _RemoteMenubarState extends State { }, optionSetter: (String oldValue, String newValue) async { await bind.sessionSetKeyboardMode(id: widget.id, value: newValue); - widget.ffi.canvasModel.updateViewStyle(); }, ) ]; diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index 39e78cd6b..1cdecbd03 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -22,6 +22,7 @@ import 'package:tuple/tuple.dart'; import 'package:image/image.dart' as img2; import 'package:flutter_custom_cursor/cursor_manager.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; import '../common.dart'; import '../common/shared_state.dart'; @@ -542,6 +543,8 @@ class CanvasModel with ChangeNotifier { ScrollStyle _scrollStyle = ScrollStyle.scrollauto; ViewStyle _lastViewStyle = ViewStyle(); + final _imageOverflow = false.obs; + WeakReference parent; CanvasModel(this.parent); @@ -552,6 +555,7 @@ class CanvasModel with ChangeNotifier { Size get size => _size; ScrollStyle get scrollStyle => _scrollStyle; ViewStyle get viewStyle => _lastViewStyle; + RxBool get imageOverflow => _imageOverflow; _resetScroll() => setScrollPercent(0.0, 0.0); @@ -601,6 +605,7 @@ class CanvasModel with ChangeNotifier { } _x = (size.width - displayWidth * _scale) / 2; _y = (size.height - displayHeight * _scale) / 2; + _imageOverflow.value = _x < 0 || y < 0; notifyListeners(); } From c1f983a952e8b94dd31f5c897f8c86e1390a8261 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Fri, 6 Jan 2023 21:33:01 +0800 Subject: [PATCH 30/40] remove ENABLE_HARDENED_RUNTIME in debug to make flutter run -d macos works under m1 --- flutter/macos/Runner.xcodeproj/project.pbxproj | 2 -- 1 file changed, 2 deletions(-) diff --git a/flutter/macos/Runner.xcodeproj/project.pbxproj b/flutter/macos/Runner.xcodeproj/project.pbxproj index b935ab4b2..a8b5306be 100644 --- a/flutter/macos/Runner.xcodeproj/project.pbxproj +++ b/flutter/macos/Runner.xcodeproj/project.pbxproj @@ -496,7 +496,6 @@ CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_HARDENED_RUNTIME = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -587,7 +586,6 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; DEVELOPMENT_TEAM = ""; - ENABLE_HARDENED_RUNTIME = YES; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", From 40e946267948b27fdebfe2e5a08171179e62f325 Mon Sep 17 00:00:00 2001 From: Kingtous Date: Fri, 6 Jan 2023 20:40:29 -0800 Subject: [PATCH 31/40] fix: save/restore window position on macos also hide on launch --- flutter/lib/common.dart | 2 +- .../lib/desktop/pages/desktop_home_page.dart | 4 ++-- .../lib/desktop/widgets/tabbar_widget.dart | 14 ++++++++++---- flutter/lib/main.dart | 2 ++ flutter/lib/utils/multi_window_manager.dart | 19 ++++++++++--------- flutter/macos/Runner/MainFlutterWindow.swift | 7 ++++--- flutter/pubspec.yaml | 2 +- 7 files changed, 30 insertions(+), 20 deletions(-) diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index 8d047dd0d..4ea494fc5 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -1418,7 +1418,7 @@ bool isRunningInPortableMode() { } /// Window status callback -void onActiveWindowChanged() async { +Future onActiveWindowChanged() async { print( "[MultiWindowHandler] active window changed: ${rustDeskWinManager.getActiveWindows()}"); if (rustDeskWinManager.getActiveWindows().isEmpty) { diff --git a/flutter/lib/desktop/pages/desktop_home_page.dart b/flutter/lib/desktop/pages/desktop_home_page.dart index 43ffbd1e3..fd9814cc2 100644 --- a/flutter/lib/desktop/pages/desktop_home_page.dart +++ b/flutter/lib/desktop/pages/desktop_home_page.dart @@ -513,9 +513,9 @@ class _DesktopHomePageState extends State } else if (call.method == kWindowActionRebuild) { reloadCurrentWindow(); } else if (call.method == kWindowEventShow) { - rustDeskWinManager.registerActiveWindow(call.arguments["id"]); + await rustDeskWinManager.registerActiveWindow(call.arguments["id"]); } else if (call.method == kWindowEventHide) { - rustDeskWinManager.unregisterActiveWindow(call.arguments["id"]); + await rustDeskWinManager.unregisterActiveWindow(call.arguments["id"]); } else if (call.method == kWindowConnect) { await connectMainDesktop( call.arguments['id'], diff --git a/flutter/lib/desktop/widgets/tabbar_widget.dart b/flutter/lib/desktop/widgets/tabbar_widget.dart index f6a5da819..91ce6cce6 100644 --- a/flutter/lib/desktop/widgets/tabbar_widget.dart +++ b/flutter/lib/desktop/widgets/tabbar_widget.dart @@ -527,13 +527,19 @@ class WindowActionPanelState extends State void onWindowClose() async { // hide window on close if (widget.isMainWindow) { + await rustDeskWinManager.unregisterActiveWindow(0); + // `hide` must be placed after unregisterActiveWindow, because once all windows are hidden, + // flutter closes the application on macOS. We should ensure the post-run logic has ran successfully. + // e.g.: saving window position. await windowManager.hide(); - rustDeskWinManager.unregisterActiveWindow(0); } else { - widget.onClose?.call(); + // it's safe to hide the subwindow await WindowController.fromWindowId(windowId!).hide(); - rustDeskWinManager - .call(WindowType.Main, kWindowEventHide, {"id": windowId!}); + await Future.wait([ + rustDeskWinManager + .call(WindowType.Main, kWindowEventHide, {"id": windowId!}), + widget.onClose?.call() ?? Future.microtask(() => null) + ]); } super.onWindowClose(); } diff --git a/flutter/lib/main.dart b/flutter/lib/main.dart index 6d09ef139..6fd205a22 100644 --- a/flutter/lib/main.dart +++ b/flutter/lib/main.dart @@ -196,6 +196,8 @@ void runMultiWindow( // no such appType exit(0); } + // show window from hidden status + WindowController.fromWindowId(windowId!).show(); } void runConnectionManagerScreen(bool hide) async { diff --git a/flutter/lib/utils/multi_window_manager.dart b/flutter/lib/utils/multi_window_manager.dart index de6750a3f..cf6d78cd2 100644 --- a/flutter/lib/utils/multi_window_manager.dart +++ b/flutter/lib/utils/multi_window_manager.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'package:desktop_multi_window/desktop_multi_window.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_hbb/common.dart'; @@ -34,7 +35,7 @@ class RustDeskMultiWindowManager { static final instance = RustDeskMultiWindowManager._(); final List _activeWindows = List.empty(growable: true); - final List _windowActiveCallbacks = List.empty(growable: true); + final List _windowActiveCallbacks = List.empty(growable: true); int? _remoteDesktopWindowId; int? _fileTransferWindowId; int? _portForwardWindowId; @@ -191,19 +192,19 @@ class RustDeskMultiWindowManager { return _activeWindows; } - void _notifyActiveWindow() { + Future _notifyActiveWindow() async { for (final callback in _windowActiveCallbacks) { - callback.call(); + await callback.call(); } } - void registerActiveWindow(int windowId) { + Future registerActiveWindow(int windowId) async { if (_activeWindows.contains(windowId)) { // ignore } else { _activeWindows.add(windowId); } - _notifyActiveWindow(); + await _notifyActiveWindow(); } /// Remove active window which has [`windowId`] @@ -212,20 +213,20 @@ class RustDeskMultiWindowManager { /// This function should only be called from main window. /// For other windows, please post a unregister(hide) event to main window handler: /// `rustDeskWinManager.call(WindowType.Main, kWindowEventHide, {"id": windowId!});` - void unregisterActiveWindow(int windowId) { + Future unregisterActiveWindow(int windowId) async { if (!_activeWindows.contains(windowId)) { // ignore } else { _activeWindows.remove(windowId); } - _notifyActiveWindow(); + await _notifyActiveWindow(); } - void registerActiveWindowListener(VoidCallback callback) { + void registerActiveWindowListener(AsyncCallback callback) { _windowActiveCallbacks.add(callback); } - void unregisterActiveWindowListener(VoidCallback callback) { + void unregisterActiveWindowListener(AsyncCallback callback) { _windowActiveCallbacks.remove(callback); } } diff --git a/flutter/macos/Runner/MainFlutterWindow.swift b/flutter/macos/Runner/MainFlutterWindow.swift index 1d16763ee..540cd9ab9 100644 --- a/flutter/macos/Runner/MainFlutterWindow.swift +++ b/flutter/macos/Runner/MainFlutterWindow.swift @@ -49,7 +49,8 @@ class MainFlutterWindow: NSWindow { super.awakeFromNib() } -// override func bitsdojo_window_configure() -> UInt { -// return BDW_CUSTOM_FRAME | BDW_HIDE_ON_STARTUP -// } + override public func order(_ place: NSWindow.OrderingMode, relativeTo otherWin: Int) { + super.order(place, relativeTo: otherWin) + hiddenWindowAtLaunch() + } } diff --git a/flutter/pubspec.yaml b/flutter/pubspec.yaml index a87727f7b..4826f6198 100644 --- a/flutter/pubspec.yaml +++ b/flutter/pubspec.yaml @@ -63,7 +63,7 @@ dependencies: desktop_multi_window: git: url: https://github.com/Kingtous/rustdesk_desktop_multi_window - ref: 82f9eab81cb2c7bfb938def7a1b399a6279bbc75 + ref: e6d30bde98bd0f4ff50a130e5b1068138307bd03 freezed_annotation: ^2.0.3 flutter_custom_cursor: ^0.0.2 window_size: From 6ebe25a6ba5c4041007614f123b40ce3002773b2 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Sat, 7 Jan 2023 13:12:51 +0800 Subject: [PATCH 32/40] remove counter https://stackoverflow.com/questions/51893926/how-can-i-hide-letter-counter-from-bottom-of-textfield-in-flutter --- flutter/lib/desktop/pages/connection_page.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index 939acfbc5..85749a256 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -184,6 +184,7 @@ class _ConnectionPageState extends State cursorColor: Theme.of(context).textTheme.titleLarge?.color, decoration: InputDecoration( + counterText: '', hintText: _idInputFocused.value ? null : translate('Enter Remote ID'), From f2cc993e1b661a2c71e40d45d097e584b407e280 Mon Sep 17 00:00:00 2001 From: solokot Date: Sat, 7 Jan 2023 12:19:27 +0300 Subject: [PATCH 33/40] update ru.rs --- src/lang/ru.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lang/ru.rs b/src/lang/ru.rs index 14e04b940..cb53b363e 100644 --- a/src/lang/ru.rs +++ b/src/lang/ru.rs @@ -206,7 +206,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the peer", "Закрыто удалённым узлом вручную"), ("Enable remote configuration modification", "Разрешить удалённое изменение конфигурации"), ("Run without install", "Запустить без установки"), - ("Always connected via relay", "Всегда подключён через ретрансляционный сервер"), + ("Always connected via relay", "Всегда подключается через ретрансляционный сервер"), ("Always connect via relay", "Всегда подключаться через ретрансляционный сервер"), ("whitelist_tip", "Только IP-адреса из белого списка могут получить доступ ко мне"), ("Login", "Войти"), @@ -405,8 +405,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", "Закрыто вручную через веб-консоль"), ("Local keyboard type", "Тип локальной клавиатуры"), ("Select local keyboard type", "Выберите тип локальной клавиатуры"), - ("software_render_tip", ""), - ("Always use software rendering", ""), - ("config_input", ""), + ("software_render_tip", "Если у вас видеокарта Nvidia и удалённое окно закрывается сразу после подключения, может помочь установка драйвера Nouveau и выбор использования программной визуализации. Потребуется перезапуск."), + ("Always use software rendering", "Использовать программную визуализацию"), + ("config_input", "Чтобы управлять удалённым рабочим столом с помощью клавиатуры, необходимо предоставить RustDesk разрешения \"Мониторинг ввода\"."), ].iter().cloned().collect(); } From 85e4e0fe4e9c652ab0c234f7a1c45b12f6a80dce Mon Sep 17 00:00:00 2001 From: Kingtous Date: Sat, 7 Jan 2023 23:55:41 +0800 Subject: [PATCH 34/40] feat: add appimage build for flutter --- appimage/AppImageBuilder.yml | 90 +++++++++++++++++++++++++++++++++ flutter/linux/my_application.cc | 10 +++- 2 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 appimage/AppImageBuilder.yml diff --git a/appimage/AppImageBuilder.yml b/appimage/AppImageBuilder.yml new file mode 100644 index 000000000..e5e424d0b --- /dev/null +++ b/appimage/AppImageBuilder.yml @@ -0,0 +1,90 @@ +# appimage-builder recipe see https://appimage-builder.readthedocs.io for details +version: 1 +script: + - rm -rf ./AppDir || true + - bsdtar -zxvf ../rustdesk-1.2.0.deb + - tar -xvf ./data.tar.xz + - mkdir ./AppDir + - mv ./usr ./AppDir/usr + # 32x32 icon + - for i in {32,64,128}; do mkdir -p ./AppDir/usr/share/icons/hicolor/$i\x$i/apps/; cp ../res/$i\x$i.png ./AppDir/usr/share/icons/hicolor/$i\x$i/apps/rustdesk.png; done + # desktop file + # - sed -i "s/Icon=\/usr\/share\/rustdesk\/files\/rustdesk.png/Icon=rustdesk/g" ./AppDir/usr/share/applications/rustdesk.desktop + - rm -rf ./AppDir/usr/share/applications +AppDir: + path: ./AppDir + app_info: + id: rustdesk + name: rustdesk + icon: rustdesk + version: 1.2.0 + exec: usr/lib/rustdesk/rustdesk + exec_args: $@ + apt: + arch: + - amd64 + allow_unauthenticated: true + sources: + - sourceline: deb http://mirrors.ustc.edu.cn/ubuntu/ bionic main restricted + - sourceline: deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-updates main restricted + - sourceline: deb http://mirrors.ustc.edu.cn/ubuntu/ bionic universe + - sourceline: deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-updates universe + - sourceline: deb http://mirrors.ustc.edu.cn/ubuntu/ bionic multiverse + - sourceline: deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-updates multiverse + - sourceline: deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-backports main restricted + universe multiverse + - sourceline: deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-security main restricted + - sourceline: deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-security universe + - sourceline: deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-security multiverse + - sourceline: deb http://ppa.launchpad.net/pipewire-debian/pipewire-upstream/ubuntu + bionic main + include: + - libc6:amd64 + - libgtk-3-0 + - libxcb-randr0 + - libxdo3 + - libxfixes3 + - libxcb-shape0 + - libxcb-xfixes0 + - libasound2 + - libsystemd0 + - curl + - libva-drm2 + - libva-x11-2 + - libvdpau1 + - libgstreamer-plugins-base1.0-0 + exclude: + - humanity-icon-theme + - hicolor-icon-theme + - adwaita-icon-theme + - ubuntu-mono + files: + include: [] + exclude: + - usr/share/man + - usr/share/doc/*/README.* + - usr/share/doc/*/changelog.* + - usr/share/doc/*/NEWS.* + - usr/share/doc/*/TODO.* + runtime: + env: + GIO_MODULE_DIR: $APPDIR/usr/lib/x86_64-linux-gnu/gio/modules/ + test: + fedora-30: + image: appimagecrafters/tests-env:fedora-30 + command: ./AppRun + debian-stable: + image: appimagecrafters/tests-env:debian-stable + command: ./AppRun + archlinux-latest: + image: appimagecrafters/tests-env:archlinux-latest + command: ./AppRun + centos-7: + image: appimagecrafters/tests-env:centos-7 + command: ./AppRun + ubuntu-xenial: + image: appimagecrafters/tests-env:ubuntu-xenial + command: ./AppRun +AppImage: + arch: x86_64 + update-information: guess diff --git a/flutter/linux/my_application.cc b/flutter/linux/my_application.cc index 215c6f0ee..21e25fa28 100644 --- a/flutter/linux/my_application.cc +++ b/flutter/linux/my_application.cc @@ -23,7 +23,15 @@ static void my_application_activate(GApplication* application) { GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); // we have custom window frame gtk_window_set_decorated(window, FALSE); - + // try setting icon for rustdesk, which uses the system cache + GtkIconTheme* theme = gtk_icon_theme_get_default(); + gint icons[4] = {256, 128, 64, 32}; + for (int i = 0; i < 4; i++) { + GdkPixbuf* icon = gtk_icon_theme_load_icon(theme, "rustdesk", icons[i], GTK_ICON_LOOKUP_NO_SVG, NULL); + if (icon != nullptr) { + gtk_window_set_icon(window, icon); + } + } // Use a header bar when running in GNOME as this is the common style used // by applications and is the setup most users will be using (e.g. Ubuntu // desktop). From b28e4b0e608ce2af7ece861275ea0ca6227aad16 Mon Sep 17 00:00:00 2001 From: Kingtous Date: Sun, 8 Jan 2023 00:22:15 +0800 Subject: [PATCH 35/40] feat: appimage nightly ci --- .github/workflows/flutter-nightly.yml | 26 ++++++++++++++++++++++++-- appimage/AppImageBuilder.yml | 17 +++++++---------- flutter/pubspec.yaml | 2 +- res/64x64.png | Bin 0 -> 2264 bytes 4 files changed, 32 insertions(+), 13 deletions(-) create mode 100644 res/64x64.png diff --git a/.github/workflows/flutter-nightly.yml b/.github/workflows/flutter-nightly.yml index 7ce940b89..1be4bb001 100644 --- a/.github/workflows/flutter-nightly.yml +++ b/.github/workflows/flutter-nightly.yml @@ -1162,7 +1162,7 @@ jobs: - name: Prepare env run: | sudo apt update -y - sudo apt-get -qq install -y git curl wget nasm yasm libgtk-3-dev + sudo apt-get -qq install -y git curl wget nasm yasm libgtk-3-dev libarchive-tools mkdir -p ./target/release/ - name: Restore the rustdesk lib file @@ -1217,7 +1217,8 @@ jobs: shell: bash run: | for name in rustdesk*??.deb; do - mv "$name" "${name%%.deb}-${{ matrix.job.target }}-${{ matrix.job.os }}.deb" + # use cp to duplicate deb files to fit other packages. + cp "$name" "${name%%.deb}-${{ matrix.job.target }}-${{ matrix.job.os }}.deb" done - name: Publish debian package @@ -1285,6 +1286,27 @@ jobs: files: | res/rustdesk*.zst + - name: Build appimage package + if: ${{ matrix.job.extra-build-features == '' }} + shell: bash + run: | + # set-up appimage-builder + wget -O appimage-builder-x86_64.AppImage https://github.com/AppImageCrafters/appimage-builder/releases/download/v1.1.0/appimage-builder-1.1.0-x86_64.AppImage + chmod +x appimage-builder-x86_64.AppImage + sudo mv appimage-builder-x86_64.AppImage /usr/local/bin/appimage-builder + # run appimage-builder + pushd appimage + appimage-builder --skip-tests + + - name: Publish appimage package + if: ${{ matrix.job.extra-build-features == '' }} + uses: softprops/action-gh-release@v1 + with: + prerelease: true + tag_name: ${{ env.TAG_NAME }} + files: | + ./appimage/rustdesk-${{ env.VERSION }}-*.AppImage + - name: Publish fedora28/centos8 package if: ${{ matrix.job.extra-build-features == '' }} uses: softprops/action-gh-release@v1 diff --git a/appimage/AppImageBuilder.yml b/appimage/AppImageBuilder.yml index e5e424d0b..ae95fd2ce 100644 --- a/appimage/AppImageBuilder.yml +++ b/appimage/AppImageBuilder.yml @@ -25,17 +25,14 @@ AppDir: - amd64 allow_unauthenticated: true sources: - - sourceline: deb http://mirrors.ustc.edu.cn/ubuntu/ bionic main restricted - - sourceline: deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-updates main restricted - - sourceline: deb http://mirrors.ustc.edu.cn/ubuntu/ bionic universe - - sourceline: deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-updates universe - - sourceline: deb http://mirrors.ustc.edu.cn/ubuntu/ bionic multiverse - - sourceline: deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-updates multiverse - - sourceline: deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-backports main restricted + - sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic main restricted + - sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic-updates main restricted + - sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic universe + - sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic-updates universe + - sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic multiverse + - sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic-updates multiverse + - sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic-backports main restricted universe multiverse - - sourceline: deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-security main restricted - - sourceline: deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-security universe - - sourceline: deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-security multiverse - sourceline: deb http://ppa.launchpad.net/pipewire-debian/pipewire-upstream/ubuntu bionic main include: diff --git a/flutter/pubspec.yaml b/flutter/pubspec.yaml index 4826f6198..705f4650c 100644 --- a/flutter/pubspec.yaml +++ b/flutter/pubspec.yaml @@ -63,7 +63,7 @@ dependencies: desktop_multi_window: git: url: https://github.com/Kingtous/rustdesk_desktop_multi_window - ref: e6d30bde98bd0f4ff50a130e5b1068138307bd03 + ref: 057e6eb1bc7dcbcf9dafd1384274a611e4fe7124 freezed_annotation: ^2.0.3 flutter_custom_cursor: ^0.0.2 window_size: diff --git a/res/64x64.png b/res/64x64.png new file mode 100644 index 0000000000000000000000000000000000000000..d93638e6eb1d82b24807d7b3d0a6ec5c72e0bd86 GIT binary patch literal 2264 zcmZ{mc`($E8^=G+bwsXBQ6Wdv((Wq6y1vdWSJqYJT4${*i(T}kB}e4Uy;jFYuH0<0 zlv}$JQqGlgNx6?u{Cwv(^PBnoW`6U`^So!?&%EaS=kvr{m>Kc$i17dbz=t%}w>(mv zf0~Q)XqI>fFpfkLZER@@0HJaK5E%^sdq-B}0ssU-0pPnc0H|jJfT%yQ@dn~(!RdP4 zNFO--r=C)a(vKVv7HMh#VzPh)guuRvMPo+}1*xxVg&X}jcGur}2n<@Cq^fdDMYD73 zn~3NNaNrGI-DJd>OmT2EnwO@JIY($DE!sc!cPe*n0I2Br3!&5MF}~l2Y!XG z736y_FuqC0Q*ojZt!S@axxaL^)k)D#=m71Xu{^NEP6v9sXMl!S&BSKF>D@gr?xZc> zmA9wYWPGvR!UH(ndRTb*H=0Db9dTOVkqN8Sj93Atp)ZCY68qhOJzJ3rXQWX`rW~`2 z^d>wN;!7j+l&I?2!-EVG21K%IyJs15sfgw*J7Rz=y~K@f?8sDqx;rzp#<@1oxLi=mQVQX)Zzo#v#Xn%H&MziYA+3TrCT zA1gN5_3>^sH9r26pUNdTs<+9aggn=obN=4UO@~minGaf+>IISI(iiTRhUVzn@qz~L zuhc);P2c@E(zL1)fy-#@#cu5tK&a2bl0CzzF~m%N#Om9OriSyOg3pB|dlGq;8=ugamML7SrtQhA@^S9-mzxvElswF?gdk{3 zV=ur`xzKbsGuh*}J2E!l>9NZss}wzZ(TSVqA|Ra|%J|tkCr)1)$T=6ml4hb215#p+ zqxM5+`)?N(3=_-4hU;1)c7{x*8*HIF!wdS|=8-aU(!WN|DP^ZlG`-0my)wQb3*rDY%YUybWf_isb?Io0G92KO9?qfsgJ3k_hB{;d`aQ?vZeUahnk=>XS?#LzYq9G zj(w+w!e7MDJUD7}Pc}mnBrsFUbBkZCqoj4xMlyb{A`C@hvSo@(nWB9)uDqI>tOfgC z0tx+%1x%IIucnYaRqYm;U!#jDae;qW?=0bc@|p;)AN3^9&g9~W2r1(40o6CY+(CH@ zJ@wTI96v#!cJ(B`KRI(N(Rl?H?}IiJ=*o}gg2U1l!45FhaW@0D1}#0bJ->N;O<|6G zR#os_%80vij+U8Ym82(&QuYUOz+ztBC}jh$vYhrdtP>xovD4h$oU|!7gucooO9?nz z35uF(ROjx?lWv*bM!%-+=q7r8-PnoQ?2T9BJ&$rwtMuIvmPBrO&684^@k~dO-5E&m zx*?=nEUOvJnEWww3I*}J)QyZB>4IyKEkAu~ANA;0v_+R;$ijJT?I0=&@~)Zffqh|{!i>ThsR0)Y8xax1foC;&6Z@PuBQt~fV{q@uYgQTj zWi5%ua8K5*hg_9Qz?Q}w;s>XaPGXR$?sg{s5Sn1^YIQcnnBCy>jgG~!hT4JgKEk!j ztj^ap{8}UiT!$6n=Ok=HwpT}n-f9J^oF}9b3V08pai2)9pdDlJI7kzr-=*f&> zdPQc zPy9J-+ha`JWIYsZ;dbAbZQ{AKL_To8d;IVkRLjrtBzs-IHvw%cN>vz;z_OFl`B&t!en1^xO|ogYc03O!UJt}voPDrHq^d^Tt;B%73*S`wR@UB^ZEUf z7>!RjP+r_jjxq0V1{c57`be{Cm7Iov-}<-z$10qBPa2 zaP;0bSEXu)><_SBm7)KtS_FCf55H3tOFc6-1m(a9d8dL<0^^b`u|;YaUgd5THtnRM z*j$6NIQ0%Gkwp%*dnJw5{RMcV0>dLAYp-^=wR4@8d?tcM3es10#`2P>UN4$<+4M6@s30Q9*_du+R dkN^KNYU*& Date: Sun, 8 Jan 2023 08:23:06 +0800 Subject: [PATCH 36/40] fix: use tmp folder to download appimage-builder --- .github/workflows/flutter-nightly.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/flutter-nightly.yml b/.github/workflows/flutter-nightly.yml index 1be4bb001..57a9b2eac 100644 --- a/.github/workflows/flutter-nightly.yml +++ b/.github/workflows/flutter-nightly.yml @@ -1291,9 +1291,11 @@ jobs: shell: bash run: | # set-up appimage-builder + pushd /tmp wget -O appimage-builder-x86_64.AppImage https://github.com/AppImageCrafters/appimage-builder/releases/download/v1.1.0/appimage-builder-1.1.0-x86_64.AppImage chmod +x appimage-builder-x86_64.AppImage sudo mv appimage-builder-x86_64.AppImage /usr/local/bin/appimage-builder + popd # run appimage-builder pushd appimage appimage-builder --skip-tests From 3bf2d749fe44d41db48a1122846d909d8d3d66ab Mon Sep 17 00:00:00 2001 From: Kingtous Date: Sun, 8 Jan 2023 08:58:30 +0800 Subject: [PATCH 37/40] add: sudo priviledge --- .github/workflows/flutter-nightly.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/flutter-nightly.yml b/.github/workflows/flutter-nightly.yml index 57a9b2eac..b6f82cf2b 100644 --- a/.github/workflows/flutter-nightly.yml +++ b/.github/workflows/flutter-nightly.yml @@ -1298,7 +1298,7 @@ jobs: popd # run appimage-builder pushd appimage - appimage-builder --skip-tests + sudo appimage-builder --skip-tests - name: Publish appimage package if: ${{ matrix.job.extra-build-features == '' }} From 9245e13057fca11a4509994b56cc0db00c3383c6 Mon Sep 17 00:00:00 2001 From: Kingtous Date: Sun, 8 Jan 2023 10:27:00 +0800 Subject: [PATCH 38/40] fix: use appimage feature --- .github/workflows/flutter-nightly.yml | 16 ++++++++++++++-- build.py | 7 +++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/.github/workflows/flutter-nightly.yml b/.github/workflows/flutter-nightly.yml index b6f82cf2b..eb13edf15 100644 --- a/.github/workflows/flutter-nightly.yml +++ b/.github/workflows/flutter-nightly.yml @@ -599,6 +599,12 @@ jobs: os: ubuntu-20.04, extra-build-features: "flatpak", } + - { + arch: x86_64, + target: x86_64-unknown-linux-gnu, + os: ubuntu-20.04, + extra-build-features: "appimage", + } # - { target: x86_64-unknown-linux-musl , os: ubuntu-20.04, use-cross: true } steps: - name: Maximize build space @@ -1148,6 +1154,12 @@ jobs: os: ubuntu-18.04, extra-build-features: "flatpak", } + - { + arch: x86_64, + target: x86_64-unknown-linux-gnu, + os: ubuntu-18.04, + extra-build-features: "appimage", + } # - { target: x86_64-unknown-linux-musl , os: ubuntu-20.04, use-cross: true } steps: - name: Checkout source code @@ -1287,7 +1299,7 @@ jobs: res/rustdesk*.zst - name: Build appimage package - if: ${{ matrix.job.extra-build-features == '' }} + if: ${{ matrix.job.extra-build-features == 'appimage' }} shell: bash run: | # set-up appimage-builder @@ -1301,7 +1313,7 @@ jobs: sudo appimage-builder --skip-tests - name: Publish appimage package - if: ${{ matrix.job.extra-build-features == '' }} + if: ${{ matrix.job.extra-build-features == 'appimage' }} uses: softprops/action-gh-release@v1 with: prerelease: true diff --git a/build.py b/build.py index 75d6fcd89..6b107ff4b 100755 --- a/build.py +++ b/build.py @@ -99,6 +99,11 @@ def make_parser(): action='store_true', help='Build rustdesk libs with the flatpak feature enabled' ) + parser.add_argument( + '--appimage', + action='store_true', + help='Build rustdesk libs with the appimage feature enabled' + ) parser.add_argument( '--skip-cargo', action='store_true', @@ -236,6 +241,8 @@ def get_features(args): features.append('flutter') if args.flatpak: features.append('flatpak') + if args.appimage: + features.append('appimage') print("features:", features) return features From 6d1ca1e69ede54de36914bf3fd8923431acdab3c Mon Sep 17 00:00:00 2001 From: "Miguel F. G" <116861809+flusheDData@users.noreply.github.com> Date: Sun, 8 Jan 2023 20:16:03 +0100 Subject: [PATCH 39/40] Update es.rs New terms added. --- src/lang/es.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lang/es.rs b/src/lang/es.rs index 56453bd8c..9252f8f14 100644 --- a/src/lang/es.rs +++ b/src/lang/es.rs @@ -39,7 +39,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Change ID", "Cambiar ID"), ("Website", "Sitio web"), ("About", "Acerca de"), - ("Slogan_tip", ""), + ("Slogan_tip", "Hecho con corazón en este mundo caótico!"), ("Privacy Statement", ""), ("Mute", "Silenciar"), ("Audio Input", "Entrada de audio"), @@ -405,8 +405,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", "Cerrado manualmente por la consola web"), ("Local keyboard type", "Tipo de teclado local"), ("Select local keyboard type", "Seleccionar tipo de teclado local"), - ("software_render_tip", ""), - ("Always use software rendering", ""), - ("config_input", ""), + ("software_render_tip", "Si tienes una gráfica Nvidia y la ventana remota se cierra inmediatamente, instalar el driver nouveau y elegir renderizado por software podría ayudar. Se requiere reiniciar la aplicación."), + ("Always use software rendering", "Usar siempre renderizado por software"), + ("config_input", "Para controlar el escritorio remoto con el teclado necesitas dar a RustDesk permisos de \"Monitorización de entrada\"."), ].iter().cloned().collect(); } From 36a2765cfa7fe4ef58e7bed8c14fc91132642c55 Mon Sep 17 00:00:00 2001 From: Mr-Update <37781396+Mr-Update@users.noreply.github.com> Date: Sun, 8 Jan 2023 22:03:47 +0100 Subject: [PATCH 40/40] Update de.rs --- src/lang/de.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/lang/de.rs b/src/lang/de.rs index 6ee9fdaf6..29081da63 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -9,7 +9,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Established", "Verbunden"), ("connecting_status", "Verbinden mit dem RustDesk-Netzwerk..."), ("Enable Service", "Vermittlungsdienst aktivieren"), - ("Start Service", "Starte Vermittlungsdienst"), + ("Start Service", "Vermittlungsdienst starten"), ("Service is running", "Vermittlungsdienst aktiv"), ("Service is not running", "Vermittlungsdienst deaktiviert"), ("not_ready_status", "Nicht bereit. Bitte überprüfen Sie Ihre Netzwerkverbindung."), @@ -35,7 +35,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Export server configuration successfully", "Serverkonfiguration erfolgreich exportiert"), ("Invalid server configuration", "Ungültige Serverkonfiguration"), ("Clipboard is empty", "Zwischenablage ist leer"), - ("Stop service", "Vermittlungsdienst deaktivieren"), + ("Stop service", "Vermittlungsdienst stoppen"), ("Change ID", "ID ändern"), ("Website", "Webseite"), ("About", "Über"), @@ -165,7 +165,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Local Port", "Lokaler Port"), ("Local Address", "Lokale Adresse"), ("Change Local Port", "Lokalen Port ändern"), - ("setup_server_tip", "für eine schnellere Verbindung richten Sie bitte Ihren eigenen Verbindungsserver ein."), + ("setup_server_tip", "für eine schnellere Verbindung richten Sie bitte Ihren eigenen Server ein."), ("Too short, at least 6 characters.", "Zu kurz, mindestens 6 Zeichen."), ("The confirmation is not identical.", "Die Passwörter stimmen nicht überein."), ("Permissions", "Berechtigungen"), @@ -239,7 +239,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Are you sure to close the connection?", "Möchten Sie diese Verbindung wirklich trennen?"), ("Download new version", "Neue Version herunterladen"), ("Touch mode", "Touch-Modus"), - ("Mouse mode", "Maus-Modus"), + ("Mouse mode", "Mausmodus"), ("One-Finger Tap", "1-Finger-Tipp"), ("Left Mouse", "Linksklick"), ("One-Long Tap", "1-Finger-Halten"), @@ -255,8 +255,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Pinch to Zoom", "2-Finger-Zoom"), ("Canvas Zoom", "Sichtfeld-Zoom"), ("Reset canvas", "Sichtfeld zurücksetzen"), - ("No permission of file transfer", "Keine Berechtigung für den Dateizugriff"), - ("Note", "Anmerkung"), + ("No permission of file transfer", "Keine Berechtigung für die Dateiübertragung"), + ("Note", "Hinweis"), ("Connection", "Verbindung"), ("Share Screen", "Bildschirm freigeben"), ("CLOSE", "DEAKTIV."), @@ -273,7 +273,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Do you accept?", "Verbindung zulassen?"), ("Open System Setting", "Systemeinstellung öffnen"), ("How to get Android input permission?", "Wie erhalte ich eine Android-Eingabeberechtigung?"), - ("android_input_permission_tip1", "Damit ein Remote-Gerät Ihr Android-Gerät steuern kann, müssen Sie RustDesk erlauben, den Dienst \"Barrierefreiheit\" zu verwenden."), + ("android_input_permission_tip1", "Damit ein entferntes Gerät Ihr Android-Gerät steuern kann, müssen Sie RustDesk erlauben, den Dienst \"Barrierefreiheit\" zu verwenden."), ("android_input_permission_tip2", "Bitte gehen Sie zur nächsten Systemeinstellungsseite, suchen Sie [Installierte Dienste] und schalten Sie den Dienst [RustDesk Input] ein."), ("android_new_connection_tip", "möchte ihr Gerät steuern."), ("android_service_will_start_tip", "Durch das Aktivieren der Bildschirmfreigabe wird der Dienst automatisch gestartet, sodass andere Geräte dieses Android-Gerät steuern können."), @@ -290,9 +290,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Succeeded", "Erfolgreich"), ("Someone turns on privacy mode, exit", "Jemand hat den Datenschutzmodus aktiviert, beende..."), ("Unsupported", "Nicht unterstützt"), - ("Peer denied", "Die Gegenstelle hat die Verbindung abgelehnt"), + ("Peer denied", "Die Gegenstelle hat die Verbindung abgelehnt."), ("Please install plugins", "Bitte installieren Sie Plugins"), - ("Peer exit", "Die Gegenstelle hat die Verbindung getrennt"), + ("Peer exit", "Die Gegenstelle hat die Verbindung getrennt."), ("Failed to turn off", "Ausschalten fehlgeschlagen"), ("Turned off", "Ausgeschaltet"), ("In privacy mode", "Datenschutzmodus aktivieren"), @@ -405,8 +405,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Closed manually by the web console", "Manuell über die Webkonsole beendet"), ("Local keyboard type", "Lokaler Tastaturtyp"), ("Select local keyboard type", "Lokalen Tastaturtyp auswählen"), - ("software_render_tip", ""), - ("Always use software rendering", ""), - ("config_input", ""), + ("software_render_tip", "Wenn Sie eine Nvidia-Grafikkarte haben und sich das entfernte Fenster sofort nach dem Herstellen der Verbindung schließt, kann es helfen, den Nouveau-Treiber zu installieren und Software-Rendering zu verwenden. Ein Neustart der Software ist erforderlich."), + ("Always use software rendering", "Software-Rendering immer verwenden"), + ("config_input", "Um den entfernten Desktop mit der Tastatur steuern zu können, müssen Sie RustDesk \"Input Monitoring\"-Rechte erteilen."), ].iter().cloned().collect(); }