diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index fb36d3aae..d115156de 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -92,7 +92,7 @@ typedef DialogBuilder = CustomAlertDialog Function( class Dialog { OverlayEntry? entry; - Completer completer = Completer(); + Completer completer = Completer(); Dialog(); @@ -101,9 +101,10 @@ class Dialog { if (!completer.isCompleted) { completer.complete(res); } - entry?.remove(); } catch (e) { debugPrint("Dialog complete catch error: $e"); + } finally { + entry?.remove(); } } } diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart index 02060dee5..6be097854 100644 --- a/flutter/lib/desktop/pages/remote_page.dart +++ b/flutter/lib/desktop/pages/remote_page.dart @@ -589,11 +589,10 @@ class _RemotePageState extends State more.add(PopupMenuItem( child: Row( children: ([ - Container(width: 100.0, child: Text(translate('OS Password'))), + Text(translate('OS Password')), TextButton( style: flatButtonStyle, onPressed: () { - Navigator.pop(context); showSetOSPassword(widget.id, false, _ffi.dialogManager); }, child: Icon(Icons.edit, color: MyTheme.accent), @@ -625,6 +624,13 @@ class _RemotePageState extends State value: 'block-input')); } } + if (gFFI.ffiModel.permissions["restart"] != false && + (pi.platform == "Linux" || + pi.platform == "Windows" || + pi.platform == "Mac OS")) { + more.add(PopupMenuItem( + child: Text(translate('Restart Remote Device')), value: 'restart')); + } () async { var value = await showMenu( context: context, @@ -652,6 +658,7 @@ class _RemotePageState extends State }(); } else if (value == 'enter_os_password') { // FIXME: + // TODO icon diff // null means no session of id // empty string means no password var password = await bind.getSessionOption(id: id, arg: "os-password"); @@ -662,6 +669,8 @@ class _RemotePageState extends State } } else if (value == 'reset_canvas') { _ffi.cursorModel.reset(); + } else if (value == 'restart') { + showRestartRemoteDevice(pi, widget.id, gFFI.dialogManager); } }(); } diff --git a/flutter/lib/mobile/pages/remote_page.dart b/flutter/lib/mobile/pages/remote_page.dart index d64c83707..c7d4202f2 100644 --- a/flutter/lib/mobile/pages/remote_page.dart +++ b/flutter/lib/mobile/pages/remote_page.dart @@ -670,7 +670,6 @@ class _RemotePageState extends State { TextButton( style: flatButtonStyle, onPressed: () { - Navigator.pop(context); showSetOSPassword(id, false, gFFI.dialogManager); }, child: Icon(Icons.edit, color: MyTheme.accent), @@ -1110,28 +1109,6 @@ void showOptions(String id, OverlayDialogManager dialogManager) async { }, clickMaskDismiss: true, backDismiss: true); } -void showRestartRemoteDevice( - PeerInfo pi, String id, OverlayDialogManager dialogManager) async { - final res = - await dialogManager.show((setState, close) => CustomAlertDialog( - title: Row(children: [ - Icon(Icons.warning_amber_sharp, - color: Colors.redAccent, size: 28), - SizedBox(width: 10), - Text(translate("Restart Remote Device")), - ]), - content: Text( - "${translate('Are you sure you want to restart')} \n${pi.username}@${pi.hostname}($id) ?"), - actions: [ - TextButton( - onPressed: () => close(), child: Text(translate("Cancel"))), - ElevatedButton( - onPressed: () => close(true), child: Text(translate("OK"))), - ], - )); - if (res == true) bind.sessionRestartRemoteDevice(id: id); -} - void showSetOSPassword( String id, bool login, OverlayDialogManager dialogManager) async { final controller = TextEditingController(); diff --git a/flutter/lib/mobile/widgets/dialog.dart b/flutter/lib/mobile/widgets/dialog.dart index 098f8d912..e0f98443b 100644 --- a/flutter/lib/mobile/widgets/dialog.dart +++ b/flutter/lib/mobile/widgets/dialog.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; import '../../common.dart'; +import '../../models/model.dart'; import '../../models/platform_model.dart'; void clientClose(OverlayDialogManager dialogManager) { @@ -16,6 +17,28 @@ void showError() { showToast(translate("Error")); } +void showRestartRemoteDevice( + PeerInfo pi, String id, OverlayDialogManager dialogManager) async { + final res = + await dialogManager.show((setState, close) => CustomAlertDialog( + title: Row(children: [ + Icon(Icons.warning_amber_sharp, + color: Colors.redAccent, size: 28), + SizedBox(width: 10), + Text(translate("Restart Remote Device")), + ]), + content: Text( + "${translate('Are you sure you want to restart')} \n${pi.username}@${pi.hostname}($id) ?"), + actions: [ + TextButton( + onPressed: () => close(), child: Text(translate("Cancel"))), + ElevatedButton( + onPressed: () => close(true), child: Text(translate("OK"))), + ], + )); + if (res == true) bind.sessionRestartRemoteDevice(id: id); +} + void setPermanentPasswordDialog(OverlayDialogManager dialogManager) async { final pw = await bind.mainGetPermanentPassword(); final p0 = TextEditingController(text: pw); diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index c4b10b377..18fe6a7f9 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -1050,7 +1050,6 @@ class FFI { await for (final message in stream) { if (message is Event) { try { - debugPrint("event:${message.field0}"); Map event = json.decode(message.field0); cb(event); } catch (e) { diff --git a/src/flutter.rs b/src/flutter.rs index bb8881c58..418abc8af 100644 --- a/src/flutter.rs +++ b/src/flutter.rs @@ -31,9 +31,10 @@ use hbb_common::{ Stream, }; -use crate::common::{ - self, check_clipboard, make_fd_to_json, update_clipboard, ClipboardContext, CLIPBOARD_INTERVAL, -}; +use crate::common::{self, make_fd_to_json, CLIPBOARD_INTERVAL}; + +#[cfg(not(any(target_os = "android", target_os = "ios")))] +use crate::common::{check_clipboard, update_clipboard, ClipboardContext}; use crate::{client::*, flutter_ffi::EventToUI, make_fd_flutter}; @@ -127,26 +128,18 @@ impl Session { } lc.set_option(name, value); } - // TODO - // input_os_password - // restart_remote_device /// Input the OS password. pub fn input_os_password(&self, pass: String, activate: bool) { input_os_password(pass, activate, self.clone()); } - // impl Interface - /// Send message to the remote session. - /// - /// # Arguments - /// - /// * `data` - The data to send. See [`Data`] for more details. - // fn send(data: Data) { - // if let Some(session) = SESSION.read().unwrap().as_ref() { - // session.send(data); - // } - // } + pub fn restart_remote_device(&self) { + let mut lc = self.lc.write().unwrap(); + lc.restarting_remote_device = true; + let msg = lc.restart_remote_device(); + self.send_msg(msg); + } /// Toggle an option. pub fn toggle_option(&self, name: &str) { @@ -670,6 +663,7 @@ impl Connection { lc: Arc>, ) -> Option> { let (tx, rx) = std::sync::mpsc::channel(); + #[cfg(not(any(target_os = "android", target_os = "ios")))] match ClipboardContext::new() { Ok(mut ctx) => { let old_clipboard: Arc> = Default::default(); diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index 4d062ab11..686111715 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -696,8 +696,9 @@ pub fn session_send_mouse(id: String, msg: String) { } pub fn session_restart_remote_device(id: String) { - // TODO - // Session::restart_remote_device(); + if let Some(session) = SESSIONS.read().unwrap().get(&id) { + session.restart_remote_device(); + } } pub fn main_set_home_dir(home: String) {