Merge branch 'rustdesk:master' into master

This commit is contained in:
Sahil Yeole 2023-09-05 18:10:32 +05:30 committed by GitHub
commit 6e2132c65e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 61 additions and 35 deletions

View File

@ -46,7 +46,7 @@ android {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.carriez.flutter_hbb" applicationId "com.carriez.flutter_hbb"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 31 targetSdkVersion 33
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()
versionName flutterVersionName versionName flutterVersionName
} }

View File

@ -614,6 +614,7 @@ class OverlayDialogManager {
int _tagCount = 0; int _tagCount = 0;
OverlayEntry? _mobileActionsOverlayEntry; OverlayEntry? _mobileActionsOverlayEntry;
RxBool mobileActionsOverlayVisible = false.obs;
void setOverlayState(OverlayKeyState overlayKeyState) { void setOverlayState(OverlayKeyState overlayKeyState) {
_overlayKeyState = overlayKeyState; _overlayKeyState = overlayKeyState;
@ -780,12 +781,14 @@ class OverlayDialogManager {
}); });
overlayState.insert(overlay); overlayState.insert(overlay);
_mobileActionsOverlayEntry = overlay; _mobileActionsOverlayEntry = overlay;
mobileActionsOverlayVisible.value = true;
} }
void hideMobileActionsOverlay() { void hideMobileActionsOverlay() {
if (_mobileActionsOverlayEntry != null) { if (_mobileActionsOverlayEntry != null) {
_mobileActionsOverlayEntry!.remove(); _mobileActionsOverlayEntry!.remove();
_mobileActionsOverlayEntry = null; _mobileActionsOverlayEntry = null;
mobileActionsOverlayVisible.value = false;
return; return;
} }
} }

View File

@ -279,7 +279,10 @@ class _RemotePageState extends State<RemotePage>
_ffi.ffiModel.pi.isSet.isTrue && _ffi.ffiModel.pi.isSet.isTrue &&
_ffi.ffiModel.waitForFirstImage.isTrue _ffi.ffiModel.waitForFirstImage.isTrue
? emptyOverlay() ? emptyOverlay()
: Offstage(), : () {
_ffi.ffiModel.tryShowAndroidActionsOverlay();
return Offstage();
}(),
// Use Overlay to enable rebuild every time on menu button click. // Use Overlay to enable rebuild every time on menu button click.
_ffi.ffiModel.pi.isSet.isTrue _ffi.ffiModel.pi.isSet.isTrue
? Overlay(initialEntries: [ ? Overlay(initialEntries: [

View File

@ -101,6 +101,9 @@ class ToolbarState {
class _ToolbarTheme { class _ToolbarTheme {
static const Color blueColor = MyTheme.button; static const Color blueColor = MyTheme.button;
static const Color hoverBlueColor = MyTheme.accent; static const Color hoverBlueColor = MyTheme.accent;
static Color inactiveColor = Colors.grey[800]!;
static Color hoverInactiveColor = Colors.grey[850]!;
static const Color redColor = Colors.redAccent; static const Color redColor = Colors.redAccent;
static const Color hoverRedColor = Colors.red; static const Color hoverRedColor = Colors.red;
// kMinInteractiveDimension // kMinInteractiveDimension
@ -543,9 +546,9 @@ class _PinMenu extends StatelessWidget {
assetName: state.pin ? "assets/pinned.svg" : "assets/unpinned.svg", assetName: state.pin ? "assets/pinned.svg" : "assets/unpinned.svg",
tooltip: state.pin ? 'Unpin Toolbar' : 'Pin Toolbar', tooltip: state.pin ? 'Unpin Toolbar' : 'Pin Toolbar',
onPressed: state.switchPin, onPressed: state.switchPin,
color: state.pin ? _ToolbarTheme.blueColor : Colors.grey[800]!, color: state.pin ? _ToolbarTheme.blueColor : _ToolbarTheme.inactiveColor,
hoverColor: hoverColor:
state.pin ? _ToolbarTheme.hoverBlueColor : Colors.grey[850]!, state.pin ? _ToolbarTheme.hoverBlueColor : _ToolbarTheme.hoverInactiveColor,
), ),
); );
} }
@ -558,13 +561,15 @@ class _MobileActionMenu extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (!ffi.ffiModel.isPeerAndroid) return Offstage(); if (!ffi.ffiModel.isPeerAndroid) return Offstage();
return _IconMenuButton( return Obx(()=>_IconMenuButton(
assetName: 'assets/actions_mobile.svg', assetName: 'assets/actions_mobile.svg',
tooltip: 'Mobile Actions', tooltip: 'Mobile Actions',
onPressed: () => ffi.dialogManager.toggleMobileActionsOverlay(ffi: ffi), onPressed: () => ffi.dialogManager.toggleMobileActionsOverlay(ffi: ffi),
color: _ToolbarTheme.blueColor, color: ffi.dialogManager.mobileActionsOverlayVisible.isTrue
hoverColor: _ToolbarTheme.hoverBlueColor, ? _ToolbarTheme.blueColor : _ToolbarTheme.inactiveColor,
); hoverColor: ffi.dialogManager.mobileActionsOverlayVisible.isTrue
? _ToolbarTheme.hoverBlueColor : _ToolbarTheme.hoverInactiveColor,
));
} }
} }

View File

@ -92,12 +92,16 @@ class _RemotePageState extends State<RemotePage> {
removeSharedStates(widget.id); removeSharedStates(widget.id);
} }
Widget emptyOverlay() => BlockableOverlay( // to-do: It should be better to use transparent color instead of the bgColor.
// But for now, the transparent color will cause the canvas to be white.
// I'm sure that the white color is caused by the Overlay widget in BlockableOverlay.
// But I don't know why and how to fix it.
Widget emptyOverlay(Color bgColor) => BlockableOverlay(
/// the Overlay key will be set with _blockableOverlayState in BlockableOverlay /// the Overlay key will be set with _blockableOverlayState in BlockableOverlay
/// see override build() in [BlockableOverlay] /// see override build() in [BlockableOverlay]
state: _blockableOverlayState, state: _blockableOverlayState,
underlying: Container( underlying: Container(
color: Colors.transparent, color: bgColor,
), ),
); );
@ -265,10 +269,13 @@ class _RemotePageState extends State<RemotePage> {
children: [ children: [
gFFI.ffiModel.pi.isSet.isTrue && gFFI.ffiModel.pi.isSet.isTrue &&
gFFI.ffiModel.waitForFirstImage.isTrue gFFI.ffiModel.waitForFirstImage.isTrue
? emptyOverlay() ? emptyOverlay(MyTheme.canvasColor)
: Offstage(), : () {
gFFI.ffiModel.tryShowAndroidActionsOverlay();
return Offstage();
}(),
_bottomWidget(), _bottomWidget(),
gFFI.ffiModel.pi.isSet.isFalse ? emptyOverlay() : Offstage(), gFFI.ffiModel.pi.isSet.isFalse ? emptyOverlay(MyTheme.canvasColor) : Offstage(),
], ],
)), )),
body: Overlay( body: Overlay(

View File

@ -554,23 +554,13 @@ class FfiModel with ChangeNotifier {
} }
final connType = parent.target?.connType; final connType = parent.target?.connType;
if (isPeerAndroid) { if (isPeerAndroid) {
_touchMode = true; _touchMode = true;
if (connType == ConnType.defaultConn &&
parent.target != null &&
parent.target!.ffiModel.permissions['keyboard'] != false) {
Timer(
const Duration(milliseconds: 100),
() => parent.target!.dialogManager
.showMobileActionsOverlay(ffi: parent.target!));
}
} else { } else {
_touchMode = await bind.sessionGetOption( _touchMode = await bind.sessionGetOption(
sessionId: sessionId, arg: 'touch-mode') != sessionId: sessionId, arg: 'touch-mode') !=
''; '';
} }
if (connType == ConnType.fileTransfer) { if (connType == ConnType.fileTransfer) {
parent.target?.fileModel.onReady(); parent.target?.fileModel.onReady();
} else if (connType == ConnType.defaultConn) { } else if (connType == ConnType.defaultConn) {
@ -616,6 +606,19 @@ class FfiModel with ChangeNotifier {
notifyListeners(); notifyListeners();
} }
tryShowAndroidActionsOverlay({int delayMSecs = 10}) {
if (isPeerAndroid) {
if (parent.target?.connType == ConnType.defaultConn &&
parent.target != null &&
parent.target!.ffiModel.permissions['keyboard'] != false) {
Timer(
Duration(milliseconds: delayMSecs),
() => parent.target!.dialogManager
.showMobileActionsOverlay(ffi: parent.target!));
}
}
}
handleResolutions(String id, dynamic resolutions) { handleResolutions(String id, dynamic resolutions) {
try { try {
final List<dynamic> dynamicArray = jsonDecode(resolutions as String); final List<dynamic> dynamicArray = jsonDecode(resolutions as String);

View File

@ -40,6 +40,8 @@ class ServerModel with ChangeNotifier {
late String _emptyIdShow; late String _emptyIdShow;
late final IDTextEditingController _serverId; late final IDTextEditingController _serverId;
final _serverPasswd =
TextEditingController(text: translate("Generating ..."));
final tabController = DesktopTabController(tabType: DesktopTabType.cm); final tabController = DesktopTabController(tabType: DesktopTabType.cm);
@ -61,9 +63,6 @@ class ServerModel with ChangeNotifier {
int get connectStatus => _connectStatus; int get connectStatus => _connectStatus;
TextEditingController get _serverPasswd =>
TextEditingController(text: translate("Generating ..."));
String get verificationMethod { String get verificationMethod {
final index = [ final index = [
kUseTemporaryPassword, kUseTemporaryPassword,

View File

@ -779,12 +779,18 @@ pub fn get_sysinfo() -> serde_json::Value {
os = format!("{os} - {}", system.os_version().unwrap_or_default()); os = format!("{os} - {}", system.os_version().unwrap_or_default());
} }
let hostname = hostname(); // sys.hostname() return localhost on android in my test let hostname = hostname(); // sys.hostname() return localhost on android in my test
serde_json::json!({ use serde_json::json;
let mut out = json!({
"cpu": format!("{cpu}{num_cpus}/{num_pcpus} cores"), "cpu": format!("{cpu}{num_cpus}/{num_pcpus} cores"),
"memory": format!("{memory}GB"), "memory": format!("{memory}GB"),
"os": os, "os": os,
"hostname": hostname, "hostname": hostname,
}) });
#[cfg(not(any(target_os = "android", target_os = "ios")))]
{
out["username"] = json!(crate::platform::get_active_username());
}
out
} }
#[inline] #[inline]

View File

@ -222,6 +222,8 @@ pub fn core_main() -> Option<Vec<String>> {
log::info!("start --uninstall-service"); log::info!("start --uninstall-service");
crate::platform::uninstall_service(false); crate::platform::uninstall_service(false);
} else if args[0] == "--service" { } else if args[0] == "--service" {
#[cfg(target_os = "macos")]
crate::platform::macos::hide_dock();
log::info!("start --service"); log::info!("start --service");
crate::start_os_service(); crate::start_os_service();
return None; return None;

View File

@ -240,6 +240,11 @@ pub fn uninstall_service(show_new_window: bool) -> bool {
uninstalled uninstalled
); );
if uninstalled { if uninstalled {
if !show_new_window {
let _ = crate::ipc::close_all_instances();
// leave ipc a little time
std::thread::sleep(std::time::Duration::from_millis(300));
}
crate::ipc::set_option("stop-service", "Y"); crate::ipc::set_option("stop-service", "Y");
std::process::Command::new("launchctl") std::process::Command::new("launchctl")
.args(&["remove", &format!("{}_server", crate::get_full_name())]) .args(&["remove", &format!("{}_server", crate::get_full_name())])
@ -255,13 +260,6 @@ pub fn uninstall_service(show_new_window: bool) -> bool {
.spawn() .spawn()
.ok(); .ok();
} }
std::process::Command::new("pkill")
.arg(crate::get_app_name())
.status()
.ok();
let _ = crate::ipc::close_all_instances();
// leave ipc a little time
std::thread::sleep(std::time::Duration::from_millis(300));
quit_gui(); quit_gui();
} }
} }