From 420dd9c9db50bd6088257cfdbe5d9ad8e34b40e4 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Tue, 29 Nov 2022 22:00:27 +0800 Subject: [PATCH] mac help cards two mac issues: 1) windows position not saved, position not got, win manager issue? 2) freeCache not found from custom cursor channel --- .../lib/desktop/pages/connection_page.dart | 7 +- .../lib/desktop/pages/desktop_home_page.dart | 165 +++++++++++++----- .../desktop/pages/desktop_setting_page.dart | 2 +- .../macos/Runner.xcodeproj/project.pbxproj | 10 +- flutter/windows/runner/main.cpp | 2 +- src/flutter.rs | 2 +- src/flutter_ffi.rs | 4 + src/lang.rs | 2 +- 8 files changed, 136 insertions(+), 58 deletions(-) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index 83e57dba8..a1e87b418 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -42,7 +42,7 @@ class _ConnectionPageState extends State final RxBool _idInputFocused = false.obs; final FocusNode _idFocusNode = FocusNode(); - var svcStopped = false.obs; + var svcStopped = Get.find(tag: 'stop-service'); var svcStatusCode = 0.obs; var svcIsUsingPublicServer = true.obs; @@ -67,7 +67,6 @@ class _ConnectionPageState extends State _idFocusNode.addListener(() { _idInputFocused.value = _idFocusNode.hasFocus; }); - Get.put(svcStopped, tag: 'service-stop'); windowManager.addListener(this); } @@ -75,7 +74,6 @@ class _ConnectionPageState extends State void dispose() { _idController.dispose(); _updateTimer?.cancel(); - Get.delete(tag: 'service-stop'); windowManager.removeListener(this); super.dispose(); } @@ -296,7 +294,7 @@ class _ConnectionPageState extends State // stop Offstage( offstage: !svcStopped.value, - child: GestureDetector( + child: InkWell( onTap: () async { bool checked = !bind.mainIsInstalled() || await bind.mainCheckSuperUserPermission(); @@ -357,7 +355,6 @@ class _ConnectionPageState extends State } updateStatus() async { - svcStopped.value = await bind.mainGetOption(key: "stop-service") == "Y"; final status = jsonDecode(await bind.mainGetConnectStatus()) as Map; svcStatusCode.value = status["status_num"]; diff --git a/flutter/lib/desktop/pages/desktop_home_page.dart b/flutter/lib/desktop/pages/desktop_home_page.dart index 4be64eee0..a6d4691ce 100644 --- a/flutter/lib/desktop/pages/desktop_home_page.dart +++ b/flutter/lib/desktop/pages/desktop_home_page.dart @@ -40,7 +40,12 @@ class _DesktopHomePageState extends State @override bool get wantKeepAlive => true; var updateUrl = ''; + var systemError = ''; StreamSubscription? _uniLinksSubscription; + var svcStopped = false.obs; + var watchIsCanScreenRecording = false; + var watchIsProcessTrust = false; + Timer? _updateTimer; @override Widget build(BuildContext context) { @@ -317,13 +322,37 @@ class _DesktopHomePageState extends State await launchUrl(url); }); } - if (Platform.isMacOS) {} + if (systemError.isNotEmpty) { + return buildInstallCard("", systemError, "", () {}); + } + if (Platform.isMacOS) { + if (!bind.mainIsCanScreenRecording(prompt: false)) { + return buildInstallCard("Permissions", "config_screen", "Configure", + () async { + bind.mainIsCanScreenRecording(prompt: true); + watchIsCanScreenRecording = true; + }, help: 'Help', link: translate("doc_mac_permission")); + } else if (!bind.mainIsProcessTrusted(prompt: false)) { + return buildInstallCard("Permissions", "config_acc", "Configure", + () async { + bind.mainIsProcessTrusted(prompt: true); + watchIsProcessTrust = true; + }, help: 'Help', link: translate("doc_mac_permission")); + } else if (!svcStopped.value && + bind.mainIsInstalled() && + !bind.mainIsInstalledDaemon(prompt: false)) { + return buildInstallCard("", "install_daemon_tip", "Install", () async { + bind.mainIsInstalledDaemon(prompt: true); + }); + } + } if (bind.mainIsInstalledLowerVersion()) {} return Container(); } Widget buildInstallCard(String title, String content, String btnText, - GestureTapCallback onPressed) { + GestureTapCallback onPressed, + {String? help, String? link}) { return Container( margin: EdgeInsets.only(top: 20), child: Container( @@ -338,44 +367,64 @@ class _DesktopHomePageState extends State )), padding: EdgeInsets.all(20), child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: (title.isNotEmpty - ? [ - Center( - child: Text( - translate(title), - style: TextStyle( - color: Colors.white, - fontWeight: FontWeight.bold, - fontSize: 15), - ).marginOnly(bottom: 6)), - ] - : []) + - [ - Text( - translate(content), - style: TextStyle( - height: 1.5, - color: Colors.white, - fontWeight: FontWeight.normal, - fontSize: 13), - ).marginOnly(bottom: 20), - Row(mainAxisAlignment: MainAxisAlignment.center, children: [ - FixedWidthButton( - width: 150, - padding: 8, - isOutline: true, - text: translate(btnText), - textColor: Colors.white, - borderColor: Colors.white, - textSize: 20, - radius: 10, - onTap: onPressed, - ) - ]), - ], - )), + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: (title.isNotEmpty + ? [ + Center( + child: Text( + translate(title), + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 15), + ).marginOnly(bottom: 6)), + ] + : []) + + [ + Text( + translate(content), + style: TextStyle( + height: 1.5, + color: Colors.white, + fontWeight: FontWeight.normal, + fontSize: 13), + ).marginOnly(bottom: 20) + ] + + (btnText.isNotEmpty + ? [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + FixedWidthButton( + width: 150, + padding: 8, + isOutline: true, + text: translate(btnText), + textColor: Colors.white, + borderColor: Colors.white, + textSize: 20, + radius: 10, + onTap: onPressed, + ) + ]) + ] + : []) + + (help != null + ? [ + Center( + child: InkWell( + onTap: () async => + await launchUrl(Uri.parse(link!)), + child: Text( + translate(help), + style: TextStyle( + decoration: TextDecoration.underline, + color: Colors.white, + fontSize: 12), + )).marginOnly(top: 6)), + ] + : []))), ); } @@ -412,16 +461,42 @@ class _DesktopHomePageState extends State void initState() { super.initState(); bind.mainStartGrabKeyboard(); - Timer(const Duration(seconds: 5), () async { - updateUrl = await bind.mainGetSoftwareUpdateUrl(); - if (updateUrl.isNotEmpty) setState(() {}); + _updateTimer = Timer.periodic(const Duration(seconds: 1), (timer) async { + final url = await bind.mainGetSoftwareUpdateUrl(); + if (updateUrl != url) { + updateUrl = url; + setState(() {}); + } + final error = await bind.mainGetError(); + if (systemError != error) { + systemError = error; + setState(() {}); + } + final v = await bind.mainGetOption(key: "stop-service") == "Y"; + if (v != svcStopped.value) { + svcStopped.value = v; + setState(() {}); + } + if (watchIsCanScreenRecording) { + if (bind.mainIsCanScreenRecording(prompt: false)) { + watchIsCanScreenRecording = false; + setState(() {}); + } + } + if (watchIsProcessTrust) { + if (bind.mainIsProcessTrusted(prompt: false)) { + watchIsProcessTrust = false; + setState(() {}); + } + } }); + Get.put(svcStopped, tag: 'stop-service'); // disable this tray because we use tray function provided by rust now // initTray(); trayManager.addListener(this); rustDeskWinManager.registerActiveWindowListener(onActiveWindowChanged); // main window may be hidden because of the initial uni link or arguments. - // note that we must wrap this active window registration in future because + // note that we must wrap this active window registration in future because // we must ensure the execution is after `windowManager.hide/show()`. Future.delayed(Duration.zero, () { windowManager.isVisible().then((visibility) { @@ -475,6 +550,8 @@ class _DesktopHomePageState extends State // rustDeskWinManager.unregisterActiveWindowListener(onActiveWindowChanged); trayManager.removeListener(this); _uniLinksSubscription?.cancel(); + Get.delete(tag: 'stop-service'); + _updateTimer?.cancel(); super.dispose(); } } diff --git a/flutter/lib/desktop/pages/desktop_setting_page.dart b/flutter/lib/desktop/pages/desktop_setting_page.dart index 056b1028b..a51b4d035 100644 --- a/flutter/lib/desktop/pages/desktop_setting_page.dart +++ b/flutter/lib/desktop/pages/desktop_setting_page.dart @@ -434,7 +434,7 @@ class _SafetyState extends State<_Safety> with AutomaticKeepAliveClientMixin { bool get wantKeepAlive => true; bool locked = bind.mainIsInstalled(); final scrollController = ScrollController(); - final RxBool serviceStop = Get.find(tag: 'service-stop'); + final RxBool serviceStop = Get.find(tag: 'stop-service'); @override Widget build(BuildContext context) { diff --git a/flutter/macos/Runner.xcodeproj/project.pbxproj b/flutter/macos/Runner.xcodeproj/project.pbxproj index 5f369ea9e..ec4baf141 100644 --- a/flutter/macos/Runner.xcodeproj/project.pbxproj +++ b/flutter/macos/Runner.xcodeproj/project.pbxproj @@ -439,7 +439,7 @@ "$(inherited)", ../../target/profile, ); - MACOSX_DEPLOYMENT_TARGET = 10.15; + MACOSX_DEPLOYMENT_TARGET = 10.14; PRODUCT_BUNDLE_IDENTIFIER = com.carriez.rustdesk; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 5.0; @@ -499,7 +499,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.15; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -547,7 +547,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.15; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = NO; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -574,7 +574,7 @@ "$(inherited)", ../../target/debug, ); - MACOSX_DEPLOYMENT_TARGET = 10.15; + MACOSX_DEPLOYMENT_TARGET = 10.14; PRODUCT_BUNDLE_IDENTIFIER = com.carriez.rustdesk; PROVISIONING_PROFILE_SPECIFIER = ""; "SWIFT_OBJC_BRIDGING_HEADER[arch=*]" = Runner/bridge_generated.h; @@ -601,7 +601,7 @@ "$(inherited)", ../../target/release, ); - MACOSX_DEPLOYMENT_TARGET = 10.15; + MACOSX_DEPLOYMENT_TARGET = 10.14; PRODUCT_BUNDLE_IDENTIFIER = com.carriez.rustdesk; PROVISIONING_PROFILE_SPECIFIER = ""; "SWIFT_OBJC_BRIDGING_HEADER[arch=*]" = Runner/bridge_generated.h; diff --git a/flutter/windows/runner/main.cpp b/flutter/windows/runner/main.cpp index 5680ab5d3..9b75aa086 100644 --- a/flutter/windows/runner/main.cpp +++ b/flutter/windows/runner/main.cpp @@ -25,7 +25,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, return EXIT_FAILURE; } FUNC_RUSTDESK_CORE_MAIN rustdesk_core_main = - (FUNC_RUSTDESK_CORE_MAIN)GetProcAddress(hInstance, "rustdesk_core_main"); + (FUNC_RUSTDESK_CORE_MAIN)GetProcAddress(hInstance, "rustdesk_core_main_args"); if (!rustdesk_core_main) { std::cout << "Failed to get rustdesk_core_main" << std::endl; diff --git a/src/flutter.rs b/src/flutter.rs index 9c4208625..27d12860b 100644 --- a/src/flutter.rs +++ b/src/flutter.rs @@ -40,7 +40,7 @@ pub extern "C" fn rustdesk_core_main() -> bool { #[cfg(windows)] #[no_mangle] -pub extern "C" fn rustdesk_core_main(args_len: *mut c_int) -> *mut *mut c_char { +pub extern "C" fn rustdesk_core_main_args(args_len: *mut c_int) -> *mut *mut c_char { unsafe { std::ptr::write(args_len, 0) }; #[cfg(not(any(target_os = "android", target_os = "ios")))] { diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index 00f9b51e6..0f3fb5ef6 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -483,6 +483,10 @@ pub fn main_get_option(key: String) -> String { get_option(key) } +pub fn main_get_error() -> String { + get_error() +} + pub fn main_set_option(key: String, value: String) { if key.eq("custom-rendezvous-server") { set_option(key, value); diff --git a/src/lang.rs b/src/lang.rs index de0fed0b8..6254e988a 100644 --- a/src/lang.rs +++ b/src/lang.rs @@ -110,7 +110,7 @@ pub fn translate_locale(name: String, locale: &str) -> String { "fa" => fa::T.deref(), "ca" => ca::T.deref(), "gr" => gr::T.deref(), - "gr" => sv::T.deref(), + "sv" => sv::T.deref(), _ => en::T.deref(), }; if let Some(v) = m.get(&name as &str) {