diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index 97b1a3596..1b3aad9d8 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -133,11 +133,12 @@ class MyTheme { backgroundColor: Color(0xFFFFFFFF), scaffoldBackgroundColor: Color(0xFFEEEEEE), textTheme: const TextTheme( - titleLarge: TextStyle(fontSize: 19, color: Colors.black87), - titleSmall: TextStyle(fontSize: 14, color: Colors.black87), - bodySmall: TextStyle(fontSize: 12, color: Colors.black87, height: 1.25), - bodyMedium: TextStyle(fontSize: 14, color: Colors.black87, height: 1.25), - ), + titleLarge: TextStyle(fontSize: 19, color: Colors.black87), + titleSmall: TextStyle(fontSize: 14, color: Colors.black87), + bodySmall: TextStyle(fontSize: 12, color: Colors.black87, height: 1.25), + bodyMedium: + TextStyle(fontSize: 14, color: Colors.black87, height: 1.25), + labelLarge: TextStyle(fontSize: 16.0, color: MyTheme.accent80)), hintColor: Color(0xFFAAAAAA), primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, @@ -166,7 +167,9 @@ class MyTheme { titleLarge: TextStyle(fontSize: 19), titleSmall: TextStyle(fontSize: 14), bodySmall: TextStyle(fontSize: 12, height: 1.25), - bodyMedium: TextStyle(fontSize: 14, height: 1.25)), + bodyMedium: TextStyle(fontSize: 14, height: 1.25), + labelLarge: TextStyle( + fontSize: 16.0, fontWeight: FontWeight.bold, color: accent80)), cardColor: Color(0xFF252525), primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, @@ -558,6 +561,7 @@ class CustomAlertDialog extends StatelessWidget { required this.content, this.actions, this.contentPadding, + this.contentBoxConstraints = const BoxConstraints(maxWidth: 500), this.onSubmit, this.onCancel}) : super(key: key); @@ -566,6 +570,7 @@ class CustomAlertDialog extends StatelessWidget { final Widget content; final List? actions; final double? contentPadding; + final BoxConstraints contentBoxConstraints; final Function()? onSubmit; final Function()? onCancel; @@ -597,7 +602,8 @@ class CustomAlertDialog extends StatelessWidget { title: title, contentPadding: EdgeInsets.symmetric( horizontal: contentPadding ?? 25, vertical: 10), - content: content, + content: + ConstrainedBox(constraints: contentBoxConstraints, child: content), actions: actions, ), ); @@ -642,9 +648,7 @@ void msgBox( } dialogManager.show((setState, close) => CustomAlertDialog( title: _msgBoxTitle(title), - content: ConstrainedBox( - constraints: BoxConstraints(maxWidth: 500), - child: Text(translate(text), style: const TextStyle(fontSize: 15))), + content: Text(translate(text), style: const TextStyle(fontSize: 15)), actions: buttons, onSubmit: hasOk ? submit : null, onCancel: hasCancel == true ? cancel : null, diff --git a/flutter/lib/common/widgets/dialog.dart b/flutter/lib/common/widgets/dialog.dart index cfb57a4cb..35a303c0b 100644 --- a/flutter/lib/common/widgets/dialog.dart +++ b/flutter/lib/common/widgets/dialog.dart @@ -155,3 +155,54 @@ void changeWhiteList({Function()? callback}) async { ); }); } + +Future changeDirectAccessPort( + String currentIP, String currentPort) async { + final controller = TextEditingController(text: currentPort); + await gFFI.dialogManager.show((setState, close) { + return CustomAlertDialog( + title: Text(translate("Change Local Port")), + content: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 8.0), + Row( + children: [ + Expanded( + child: TextField( + maxLines: null, + keyboardType: TextInputType.number, + decoration: InputDecoration( + hintText: '21118', + isCollapsed: true, + prefix: Text('$currentIP : '), + suffix: IconButton( + padding: EdgeInsets.zero, + icon: const Icon(Icons.clear, size: 16), + onPressed: () => controller.clear())), + inputFormatters: [ + FilteringTextInputFormatter.allow(RegExp( + r'^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$')), + ], + controller: controller, + focusNode: FocusNode()..requestFocus()), + ), + ], + ), + ], + ), + actions: [ + TextButton(onPressed: close, child: Text(translate("Cancel"))), + TextButton( + onPressed: () async { + await bind.mainSetOption( + key: 'direct-access-port', value: controller.text); + close(); + }, + child: Text(translate("OK"))), + ], + onCancel: close, + ); + }); + return controller.text; +} diff --git a/flutter/lib/common/widgets/peer_card.dart b/flutter/lib/common/widgets/peer_card.dart index 53f980a9a..e3ab82cf5 100644 --- a/flutter/lib/common/widgets/peer_card.dart +++ b/flutter/lib/common/widgets/peer_card.dart @@ -669,7 +669,7 @@ class RecentPeerCard extends BasePeerCard { _connectAction(context, peer), _transferFileAction(context, peer.id), ]; - if (isDesktop) { + if (isDesktop && peer.platform != 'Android') { menuItems.add(_tcpTunnelingAction(context, peer.id)); } menuItems.add(await _forceAlwaysRelayAction(peer.id)); @@ -701,7 +701,7 @@ class FavoritePeerCard extends BasePeerCard { _connectAction(context, peer), _transferFileAction(context, peer.id), ]; - if (isDesktop) { + if (isDesktop && peer.platform != 'Android') { menuItems.add(_tcpTunnelingAction(context, peer.id)); } menuItems.add(await _forceAlwaysRelayAction(peer.id)); @@ -735,7 +735,7 @@ class DiscoveredPeerCard extends BasePeerCard { _connectAction(context, peer), _transferFileAction(context, peer.id), ]; - if (isDesktop) { + if (isDesktop && peer.platform != 'Android') { menuItems.add(_tcpTunnelingAction(context, peer.id)); } menuItems.add(await _forceAlwaysRelayAction(peer.id)); @@ -760,7 +760,7 @@ class AddressBookPeerCard extends BasePeerCard { _connectAction(context, peer), _transferFileAction(context, peer.id), ]; - if (isDesktop) { + if (isDesktop && peer.platform != 'Android') { menuItems.add(_tcpTunnelingAction(context, peer.id)); } menuItems.add(await _forceAlwaysRelayAction(peer.id)); diff --git a/flutter/lib/desktop/pages/server_page.dart b/flutter/lib/desktop/pages/server_page.dart index f93591355..5d6805d97 100644 --- a/flutter/lib/desktop/pages/server_page.dart +++ b/flutter/lib/desktop/pages/server_page.dart @@ -529,85 +529,6 @@ class _CmControlPanel extends StatelessWidget { } } -class PaddingCard extends StatelessWidget { - PaddingCard({required this.child, this.title, this.titleIcon}); - - final String? title; - final IconData? titleIcon; - final Widget child; - - @override - Widget build(BuildContext context) { - final children = [child]; - if (title != null) { - children.insert( - 0, - Padding( - padding: EdgeInsets.symmetric(vertical: 5.0), - child: Row( - children: [ - titleIcon != null - ? Padding( - padding: EdgeInsets.only(right: 10), - child: Icon(titleIcon, - color: MyTheme.accent80, size: 30)) - : SizedBox.shrink(), - Text( - title!, - style: TextStyle( - fontFamily: 'WorkSans', - fontWeight: FontWeight.bold, - fontSize: 20, - color: MyTheme.accent80, - ), - ) - ], - ))); - } - return Container( - width: double.maxFinite, - child: Card( - margin: EdgeInsets.fromLTRB(15.0, 15.0, 15.0, 0), - child: Padding( - padding: EdgeInsets.symmetric(vertical: 15.0, horizontal: 30.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: children, - ), - ), - )); - } -} - -Widget clientInfo(Client client) { - return Padding( - padding: EdgeInsets.symmetric(vertical: 8), - child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - children: [ - Expanded( - flex: -1, - child: Padding( - padding: EdgeInsets.only(right: 12), - child: CircleAvatar( - child: Text(client.name[0]), - backgroundColor: MyTheme.border))), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text(client.name, - style: TextStyle(color: MyTheme.idColor, fontSize: 18)), - SizedBox(width: 8), - Text(client.peerId, - style: TextStyle(color: MyTheme.idColor, fontSize: 10)) - ])) - ], - ), - ])); -} - void checkClickTime(int id, Function() callback) async { var clickCallbackTime = DateTime.now().millisecondsSinceEpoch; await bind.cmCheckClickTime(connId: id); diff --git a/flutter/lib/mobile/pages/remote_page.dart b/flutter/lib/mobile/pages/remote_page.dart index 014266fb8..c5775236a 100644 --- a/flutter/lib/mobile/pages/remote_page.dart +++ b/flutter/lib/mobile/pages/remote_page.dart @@ -314,7 +314,7 @@ class _RemotePageState extends State { icon: Icon(Icons.tv), onPressed: () { setState(() => _showEdit = false); - showOptions(widget.id, gFFI.dialogManager); + showOptions(context, widget.id, gFFI.dialogManager); }, ) ] + @@ -446,8 +446,9 @@ class _RemotePageState extends State { gFFI.cursorModel.move(d.localPosition.dx, d.localPosition.dy); inputModel.sendMouse('down', MouseButtons.left); } else { - final cursorX = gFFI.cursorModel.x; - final cursorY = gFFI.cursorModel.y; + final offset = gFFI.cursorModel.offset; + final cursorX = offset.dx; + final cursorY = offset.dy; final visible = gFFI.cursorModel.getVisibleRect().inflate(1); // extend edges final size = MediaQueryData.fromWindow(ui.window).size; @@ -873,7 +874,8 @@ class ImagePainter extends CustomPainter { } } -void showOptions(String id, OverlayDialogManager dialogManager) async { +void showOptions( + BuildContext context, String id, OverlayDialogManager dialogManager) async { String quality = await bind.sessionGetImageQuality(id: id) ?? 'balanced'; if (quality == '') quality = 'balanced'; String codec = @@ -902,12 +904,16 @@ void showOptions(String id, OverlayDialogManager dialogManager) async { width: 40, height: 40, decoration: BoxDecoration( - border: Border.all(color: Colors.black87), - color: i == cur ? Colors.black87 : Colors.white), + border: Border.all(color: Theme.of(context).hintColor), + borderRadius: BorderRadius.circular(2), + color: i == cur + ? Theme.of(context).toggleableActiveColor.withOpacity(0.6) + : null), child: Center( child: Text((i + 1).toString(), style: TextStyle( - color: i == cur ? Colors.white : Colors.black87)))))); + color: i == cur ? Colors.white : Colors.black87, + fontWeight: FontWeight.bold)))))); } displays.add(Padding( padding: const EdgeInsets.only(top: 8), diff --git a/flutter/lib/mobile/pages/server_page.dart b/flutter/lib/mobile/pages/server_page.dart index 52b378681..0b2a51d40 100644 --- a/flutter/lib/mobile/pages/server_page.dart +++ b/flutter/lib/mobile/pages/server_page.dart @@ -333,14 +333,8 @@ class PermissionRow extends StatelessWidget { child: FittedBox( fit: BoxFit.scaleDown, alignment: Alignment.centerLeft, - child: Text(name, - style: TextStyle( - fontSize: 16.0, - fontWeight: - Theme.of(context).brightness == Brightness.dark - ? FontWeight.bold - : null, - color: MyTheme.accent80)))), + child: + Text(name, style: Theme.of(context).textTheme.labelLarge))), Expanded( flex: 2, child: FittedBox( @@ -387,7 +381,7 @@ class ConnectionManager extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Expanded(child: clientInfo(client)), + Expanded(child: ClientInfo(client)), Expanded( flex: -1, child: client.isFileTransfer || !client.authorized @@ -499,35 +493,42 @@ class PaddingCard extends StatelessWidget { } } -Widget clientInfo(Client client) { - return Padding( - padding: const EdgeInsets.symmetric(vertical: 8), - child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - children: [ - Expanded( - flex: -1, - child: Padding( - padding: const EdgeInsets.only(right: 12), - child: CircleAvatar( - backgroundColor: MyTheme.border, - child: Text(client.name[0])))), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text(client.name, - style: const TextStyle( - color: MyTheme.idColor, fontSize: 18)), - const SizedBox(width: 8), - Text(client.peerId, - style: - const TextStyle(color: MyTheme.idColor, fontSize: 10)) - ])) - ], - ), - ])); +class ClientInfo extends StatelessWidget { + final Client client; + ClientInfo(this.client); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + Row( + children: [ + Expanded( + flex: -1, + child: Padding( + padding: const EdgeInsets.only(right: 12), + child: CircleAvatar( + backgroundColor: + str2color(client.name).withOpacity(0.7), + child: Text(client.name[0])))), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text(client.name, + style: const TextStyle( + color: MyTheme.idColor, fontSize: 18)), + const SizedBox(width: 8), + Text(client.peerId, + style: const TextStyle( + color: MyTheme.idColor, fontSize: 10)) + ])) + ], + ), + ])); + } } void androidChannelInit() { diff --git a/flutter/lib/mobile/pages/settings_page.dart b/flutter/lib/mobile/pages/settings_page.dart index 2c16a7991..4f1640a03 100644 --- a/flutter/lib/mobile/pages/settings_page.dart +++ b/flutter/lib/mobile/pages/settings_page.dart @@ -36,6 +36,9 @@ var _ignoreBatteryOpt = false; var _enableAbr = false; var _denyLANDiscovery = false; var _onlyWhiteList = false; +var _enableDirectIPAccess = false; +var _localIP = ""; +var _directAccessPort = ""; class _SettingsState extends State with WidgetsBindingObserver { String? username; @@ -77,6 +80,26 @@ class _SettingsState extends State with WidgetsBindingObserver { _onlyWhiteList = onlyWhiteList; } + final enableDirectIPAccess = option2bool( + 'direct-server', await bind.mainGetOption(key: 'direct-server')); + if (enableDirectIPAccess != _enableDirectIPAccess) { + update = true; + _enableDirectIPAccess = enableDirectIPAccess; + } + + final localIP = await bind.mainGetOption(key: 'local-ip-addr'); + if (localIP != _localIP) { + update = true; + _localIP = localIP; + } + + final directAccessPort = + await bind.mainGetOption(key: 'direct-access-port'); + if (directAccessPort != _directAccessPort) { + update = true; + _directAccessPort = directAccessPort; + } + if (update) { setState(() {}); } @@ -113,20 +136,8 @@ class _SettingsState extends State with WidgetsBindingObserver { @override Widget build(BuildContext context) { Provider.of(context); - final enhancementsTiles = [ - SettingsTile.switchTile( - title: Text('${translate('Adaptive Bitrate')} (beta)'), - initialValue: _enableAbr, - onToggle: (v) async { - await bind.mainSetOption(key: "enable-abr", value: v ? "" : "N"); - final newValue = await bind.mainGetOption(key: "enable-abr") != "N"; - setState(() { - _enableAbr = newValue; - }); - }, - ) - ]; - final shareScreenTiles = [ + final List enhancementsTiles = []; + final List shareScreenTiles = [ SettingsTile.switchTile( title: Text(translate('Deny LAN Discovery')), initialValue: _denyLANDiscovery, @@ -143,7 +154,7 @@ class _SettingsState extends State with WidgetsBindingObserver { ), SettingsTile.switchTile( title: Row(children: [ - Text(translate('Use IP Whitelisting')), + Expanded(child: Text(translate('Use IP Whitelisting'))), Offstage( offstage: !_onlyWhiteList, child: const Icon(Icons.warning_amber_rounded, @@ -164,6 +175,58 @@ class _SettingsState extends State with WidgetsBindingObserver { changeWhiteList(callback: update); }, + ), + SettingsTile.switchTile( + title: Text('${translate('Adaptive Bitrate')} (beta)'), + initialValue: _enableAbr, + onToggle: (v) async { + await bind.mainSetOption(key: "enable-abr", value: v ? "" : "N"); + final newValue = await bind.mainGetOption(key: "enable-abr") != "N"; + setState(() { + _enableAbr = newValue; + }); + }, + ), + SettingsTile.switchTile( + title: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(translate("Direct IP Access")), + Offstage( + offstage: !_enableDirectIPAccess, + child: Text( + '${translate("Local Address")}: $_localIP${_directAccessPort.isEmpty ? "" : ":$_directAccessPort"}', + style: Theme.of(context).textTheme.bodySmall, + )), + ])), + Offstage( + offstage: !_enableDirectIPAccess, + child: IconButton( + padding: EdgeInsets.zero, + icon: Icon( + Icons.edit, + size: 20, + ), + onPressed: () async { + final port = await changeDirectAccessPort( + _localIP, _directAccessPort); + setState(() { + _directAccessPort = port; + }); + })) + ]), + initialValue: _enableDirectIPAccess, + onToggle: (_) async { + _enableDirectIPAccess = !_enableDirectIPAccess; + String value = bool2option('direct-server', _enableDirectIPAccess); + await bind.mainSetOption(key: 'direct-server', value: value); + setState(() {}); + }, ) ]; if (_hasIgnoreBattery) { @@ -171,9 +234,13 @@ class _SettingsState extends State with WidgetsBindingObserver { 0, SettingsTile.switchTile( initialValue: _ignoreBatteryOpt, - title: Text(translate('Keep RustDesk background service')), - description: - Text('* ${translate('Ignore Battery Optimizations')}'), + title: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(translate('Keep RustDesk background service')), + Text('* ${translate('Ignore Battery Optimizations')}', + style: Theme.of(context).textTheme.bodySmall), + ]), onToggle: (v) async { if (v) { PermissionManager.request("ignore_battery_optimizations"); diff --git a/flutter/lib/models/file_model.dart b/flutter/lib/models/file_model.dart index 3246346be..3fdbe7099 100644 --- a/flutter/lib/models/file_model.dart +++ b/flutter/lib/models/file_model.dart @@ -570,6 +570,8 @@ class FileModel extends ChangeNotifier { Text(title) ], ), + contentBoxConstraints: + BoxConstraints(minHeight: 100, minWidth: 400, maxWidth: 400), content: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, @@ -627,6 +629,8 @@ class FileModel extends ChangeNotifier { Text(title) ], ), + contentBoxConstraints: + BoxConstraints(minHeight: 100, minWidth: 400, maxWidth: 400), content: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, diff --git a/flutter/lib/models/input_model.dart b/flutter/lib/models/input_model.dart index 655757720..21278367f 100644 --- a/flutter/lib/models/input_model.dart +++ b/flutter/lib/models/input_model.dart @@ -110,11 +110,11 @@ class InputModel { RawKeyEventDataLinux newData = e.data as RawKeyEventDataLinux; scanCode = newData.scanCode; keyCode = newData.keyCode; - } else if (e.data is RawKeyEventDataAndroid){ + } else if (e.data is RawKeyEventDataAndroid) { RawKeyEventDataAndroid newData = e.data as RawKeyEventDataAndroid; scanCode = newData.scanCode + 8; keyCode = newData.keyCode; - }else { + } else { scanCode = -1; keyCode = -1; } @@ -357,9 +357,6 @@ class InputModel { x = 0; y = 0; } - // fix mouse out of bounds - x = min(max(0.0, x), d.width.toDouble()); - y = min(max(0.0, y), d.height.toDouble()); evt['x'] = '${x.round()}'; evt['y'] = '${y.round()}'; var buttons = ''; diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index 8790ba178..255ecb6d6 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -118,7 +118,7 @@ class FfiModel with ChangeNotifier { } else { final icon = '${secure == true ? 'secure' : 'insecure'}${direct == true ? '' : '_relay'}'; - return SvgPicture.asset('assets/$icon.png', width: 48, height: 48); + return SvgPicture.asset('assets/$icon.svg', width: 48, height: 48); } } @@ -268,9 +268,12 @@ class FfiModel with ChangeNotifier { if (isPeerAndroid) { _touchMode = true; if (parent.target != null && + parent.target!.connType == ConnType.defaultConn && parent.target!.ffiModel.permissions['keyboard'] != false) { - Timer(const Duration(milliseconds: 100), - parent.target!.dialogManager.showMobileActionsOverlay); + Timer( + const Duration(milliseconds: 100), + () => parent.target!.dialogManager + .showMobileActionsOverlay(ffi: parent.target!)); } } else { _touchMode = diff --git a/flutter/lib/models/server_model.dart b/flutter/lib/models/server_model.dart index 0e70e40ea..7a94da5ad 100644 --- a/flutter/lib/models/server_model.dart +++ b/flutter/lib/models/server_model.dart @@ -13,7 +13,7 @@ import '../desktop/widgets/tabbar_widget.dart'; import '../mobile/pages/server_page.dart'; import 'model.dart'; -const KLoginDialogTag = "LOGIN"; +const kLoginDialogTag = "LOGIN"; const kUseTemporaryPassword = "use-temporary-password"; const kUsePermanentPassword = "use-permanent-password"; @@ -433,7 +433,7 @@ class ServerModel with ChangeNotifier { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(translate("Do you accept?")), - clientInfo(client), + ClientInfo(client), Text( translate("android_new_connection_tip"), style: Theme.of(globalKey.currentContext!).textTheme.bodyMedium, @@ -578,7 +578,7 @@ class Client { } String getLoginDialogTag(int id) { - return KLoginDialogTag + id.toString(); + return kLoginDialogTag + id.toString(); } showInputWarnAlert(FFI ffi) { diff --git a/src/client.rs b/src/client.rs index 214af6cf7..e65c16f33 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1319,7 +1319,7 @@ impl LoginConfigHandler { self.conn_id = pi.conn_id; // no matter if change, for update file time self.save_config(config); - #[cfg(feature = "hwcodec")] + #[cfg(any(feature = "hwcodec", feature = "mediacodec"))] { self.supported_encoding = Some((pi.encoding.h264, pi.encoding.h265)); } diff --git a/src/common.rs b/src/common.rs index 37057b809..dd792362a 100644 --- a/src/common.rs +++ b/src/common.rs @@ -317,6 +317,7 @@ async fn test_nat_type_() -> ResultType { break; } } + Config::set_option("local-ip-addr".to_owned(), addr.ip().to_string()); let ok = port1 > 0 && port2 > 0; if ok { let t = if port1 == port2 { diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index d4c198eea..c1be51498 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -32,16 +32,15 @@ fn initialize(app_dir: &str) { ); #[cfg(feature = "mediacodec")] scrap::mediacodec::check_mediacodec(); + crate::common::test_rendezvous_server(); + crate::common::test_nat_type(); + crate::common::check_software_update(); } #[cfg(target_os = "ios")] { use hbb_common::env_logger::*; init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "debug")); } - #[cfg(target_os = "android")] - { - crate::common::check_software_update(); - } } /// FFI for rustdesk core's main entry. diff --git a/src/lang/cn.rs b/src/lang/cn.rs index 3dc5dc434..691caee52 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -153,6 +153,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Action", "动作"), ("Add", "添加"), ("Local Port", "本地端口"), + ("Local Address", "当前地址"), + ("Change Local Port", "修改本地端口"), ("setup_server_tip", "如果需要更快连接速度,你可以选择自建服务器"), ("Too short, at least 6 characters.", "太短了,至少6个字符"), ("The confirmation is not identical.", "两次输入不匹配"), diff --git a/src/lang/cs.rs b/src/lang/cs.rs index 81df20cc9..f6f1f7651 100644 --- a/src/lang/cs.rs +++ b/src/lang/cs.rs @@ -153,6 +153,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Action", "Akce"), ("Add", "Přidat"), ("Local Port", "Místní port"), + ("Local Address", ""), + ("Change Local Port", ""), ("setup_server_tip", "Rychlejší připojení získáte vytvořením si svého vlastního serveru"), ("Too short, at least 6 characters.", "Příliš krátké – alespoň 6 znaků."), ("The confirmation is not identical.", "Kontrolní zadání se neshoduje."), diff --git a/src/lang/da.rs b/src/lang/da.rs index 18e4e4949..f4173845b 100644 --- a/src/lang/da.rs +++ b/src/lang/da.rs @@ -153,6 +153,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Action", "Рandling"), ("Add", "Tilføj"), ("Local Port", "Lokal Port"), + ("Local Address", ""), + ("Change Local Port", ""), ("setup_server_tip", "For en hurtigere forbindelse skal du indstille din egen forbindelsesserver"), ("Too short, at least 6 characters.", "For kort, mindst 6 tegn."), ("The confirmation is not identical.", "Bekræftelsen er ikke identisk."), diff --git a/src/lang/de.rs b/src/lang/de.rs index df7c5f238..b7c3c45af 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -153,6 +153,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Action", "Aktion"), ("Add", "Hinzufügen"), ("Local Port", "Lokaler Port"), + ("Local Address", ""), + ("Change Local Port", ""), ("setup_server_tip", "Für eine schnellere Verbindung richten Sie bitte Ihren eigenen Verbindungsserver ein"), ("Too short, at least 6 characters.", "Zu kurz, mindestens 6 Zeichen."), ("The confirmation is not identical.", "Die Passwörter sind nicht identisch."), diff --git a/src/lang/eo.rs b/src/lang/eo.rs index 578f9cef4..b8ccb3a2d 100644 --- a/src/lang/eo.rs +++ b/src/lang/eo.rs @@ -153,6 +153,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Action", "Ago"), ("Add", "Aldoni"), ("Local Port", "Loka pordo"), + ("Local Address", ""), + ("Change Local Port", ""), ("setup_server_tip", "Se vi bezonas pli rapida konekcio, vi povas krei vian propran servilon"), ("Too short, at least 6 characters.", "Tro mallonga, almenaŭ 6 signoj."), ("The confirmation is not identical.", "Ambaŭ enigoj ne kongruas"), diff --git a/src/lang/es.rs b/src/lang/es.rs index 42470b120..fda44d4da 100644 --- a/src/lang/es.rs +++ b/src/lang/es.rs @@ -153,6 +153,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Action", "Acción"), ("Add", "Agregar"), ("Local Port", "Puerto local"), + ("Local Address", ""), + ("Change Local Port", ""), ("setup_server_tip", "Para una conexión más rápida, configure su propio servidor"), ("Too short, at least 6 characters.", "Demasiado corto, al menos 6 caracteres."), ("The confirmation is not identical.", "La confirmación no es idéntica."), diff --git a/src/lang/fr.rs b/src/lang/fr.rs index ce054a021..5e84c98c8 100644 --- a/src/lang/fr.rs +++ b/src/lang/fr.rs @@ -153,6 +153,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Action", "Action"), ("Add", "Ajouter"), ("Local Port", "Port local"), + ("Local Address", ""), + ("Change Local Port", ""), ("setup_server_tip", "Si vous avez besoin d'une vitesse de connexion plus rapide, vous pouvez choisir de créer votre propre serveur"), ("Too short, at least 6 characters.", "Trop court, au moins 6 caractères."), ("The confirmation is not identical.", "Les deux entrées ne correspondent pas"), diff --git a/src/lang/hu.rs b/src/lang/hu.rs index caf74eaaa..e636d2ae8 100644 --- a/src/lang/hu.rs +++ b/src/lang/hu.rs @@ -153,6 +153,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Action", "Akció"), ("Add", "Add"), ("Local Port", "Lokális Port"), + ("Local Address", ""), + ("Change Local Port", ""), ("setup_server_tip", "Egy gyorsabb kapcsolatért, kérlek hostolj egy saját szervert"), ("Too short, at least 6 characters.", "Túl rövid, legalább 6 karakter"), ("The confirmation is not identical.", "A megerősítés nem volt azonos"), diff --git a/src/lang/id.rs b/src/lang/id.rs index e993f2042..cc9de05cd 100644 --- a/src/lang/id.rs +++ b/src/lang/id.rs @@ -153,6 +153,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Action", "Aksi"), ("Add", "Tambah"), ("Local Port", "Port Lokal"), + ("Local Address", ""), + ("Change Local Port", ""), ("setup_server_tip", "Untuk koneksi yang lebih cepat, silakan atur server Anda sendiri"), ("Too short, at least 6 characters.", "Terlalu pendek, setidaknya 6 karekter."), ("The confirmation is not identical.", "Konfirmasi tidak identik."), diff --git a/src/lang/it.rs b/src/lang/it.rs index 2f5115171..b4fd14d26 100644 --- a/src/lang/it.rs +++ b/src/lang/it.rs @@ -153,6 +153,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Action", "Azione"), ("Add", "Aggiungi"), ("Local Port", "Porta locale"), + ("Local Address", ""), + ("Change Local Port", ""), ("setup_server_tip", "Per una connessione più veloce, configura un tuo server"), ("Too short, at least 6 characters.", "Troppo breve, almeno 6 caratteri"), ("The confirmation is not identical.", "La conferma non corrisponde"), diff --git a/src/lang/ja.rs b/src/lang/ja.rs index c5ebb9b15..4c6e84232 100644 --- a/src/lang/ja.rs +++ b/src/lang/ja.rs @@ -153,6 +153,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Action", "操作"), ("Add", "追加"), ("Local Port", "ローカルのポート"), + ("Local Address", ""), + ("Change Local Port", ""), ("setup_server_tip", "接続をより速くするには、自分のサーバーをセットアップしてください"), ("Too short, at least 6 characters.", "短すぎます。最低6文字です。"), ("The confirmation is not identical.", "確認用と一致しません。"), diff --git a/src/lang/ko.rs b/src/lang/ko.rs index 069210625..0dc7ef141 100644 --- a/src/lang/ko.rs +++ b/src/lang/ko.rs @@ -153,6 +153,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Action", "액션"), ("Add", "추가"), ("Local Port", "로컬 포트"), + ("Local Address", ""), + ("Change Local Port", ""), ("setup_server_tip", "빠른 접속을 위해, 당신의 서버를 설정하세요"), ("Too short, at least 6 characters.", "너무 짧습니다, 최소 6글자 이상 입력해주세요."), ("The confirmation is not identical.", "확인용 입력이 일치하지 않습니다."), diff --git a/src/lang/kz.rs b/src/lang/kz.rs index 45f2ecdc5..9260b67de 100644 --- a/src/lang/kz.rs +++ b/src/lang/kz.rs @@ -153,6 +153,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Action", "Әрекет"), ("Add", "Қосу"), ("Local Port", "Лақал Порт"), + ("Local Address", ""), + ("Change Local Port", ""), ("setup_server_tip", "Тез қосылым үшін өз серберіңізді орнатуды өтінеміз"), ("Too short, at least 6 characters.", "Тым қысқа, кемінде 6 таңба."), ("The confirmation is not identical.", "Растау сәйкес келмейді."), @@ -290,6 +292,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Ignore Battery Optimizations", "Бәтері Оңтайландыруларын Елемеу"), ("android_open_battery_optimizations_tip", "Егер де бұл ерекшелікті өшіруді қаласаңыз, келесі RustDesk апылқат орнатпалары бетіне барып, [Бәтері]'ні тауып кіріңіз де [Шектеусіз]'ден құсбелгіні алып тастауды өтінеміз"), ("Connection not allowed", "Қосылу рұқсат етілмеген"), + ("Legacy mode", ""), + ("Map mode", ""), + ("Translate mode", ""), ("Use temporary password", "Уақытша құпия сөзді қолдану"), ("Use permanent password", "Тұрақты құпия сөзді қолдану"), ("Use both passwords", "Қос құпия сөзді қолдану"), @@ -319,16 +324,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Insecure Connection", "Қатерлі Қосылым"), ("Scale original", "Scale original"), ("Scale adaptive", "Scale adaptive"), - ("Pin menubar", "Мәзір жолағын бекіту"), - ("Unpin menubar", "Мәзір жолағын босату"), - ("Recording", ""), - ("Directory", ""), - ("Automatically record incoming sessions", ""), - ("Change", ""), - ("Start session recording", ""), - ("Stop session recording", ""), - ("Enable Recording Session", ""), - ("Allow recording session", ""), ("General", ""), ("Security", ""), ("Account", "Есепкі"), @@ -356,6 +351,14 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Enable RDP", ""), ("Pin menubar", "Мәзір жолағын бекіту"), ("Unpin menubar", "Мәзір жолағын босату"), + ("Recording", ""), + ("Directory", ""), + ("Automatically record incoming sessions", ""), + ("Change", ""), + ("Start session recording", ""), + ("Stop session recording", ""), + ("Enable Recording Session", ""), + ("Allow recording session", ""), ("Enable LAN Discovery", ""), ("Deny LAN Discovery", ""), ("Write a message", ""), diff --git a/src/lang/pl.rs b/src/lang/pl.rs index bcef81afc..2b0892a21 100644 --- a/src/lang/pl.rs +++ b/src/lang/pl.rs @@ -153,6 +153,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Action", "Akcja"), ("Add", "Dodaj"), ("Local Port", "Lokalny port"), + ("Local Address", ""), + ("Change Local Port", ""), ("setup_server_tip", "Podpowiedź do ustawień serwera"), ("Too short, at least 6 characters.", "Za krótkie, min. 6 znaków"), ("The confirmation is not identical.", "Potwierdzenie nie jest identyczne."), diff --git a/src/lang/pt_PT.rs b/src/lang/pt_PT.rs index 3e1c505e6..a387ade70 100644 --- a/src/lang/pt_PT.rs +++ b/src/lang/pt_PT.rs @@ -153,6 +153,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Action", "Acção"), ("Add", "Adicionar"), ("Local Port", "Porta Local"), + ("Local Address", ""), + ("Change Local Port", ""), ("setup_server_tip", "Para uma ligação mais rápida, por favor configure seu próprio servidor"), ("Too short, at least 6 characters.", "Muito curto, pelo menos 6 caracteres."), ("The confirmation is not identical.", "A confirmação não é idêntica."), diff --git a/src/lang/ptbr.rs b/src/lang/ptbr.rs index 7d8ce5ac7..c858b8c22 100644 --- a/src/lang/ptbr.rs +++ b/src/lang/ptbr.rs @@ -153,6 +153,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Action", "Ação"), ("Add", "Adicionar"), ("Local Port", "Porta Local"), + ("Local Address", ""), + ("Change Local Port", ""), ("setup_server_tip", "Para uma conexão mais rápida, por favor configure seu próprio servidor"), ("Too short, at least 6 characters.", "Muito curto, pelo menos 6 caracteres."), ("The confirmation is not identical.", "A confirmação não é idêntica."), diff --git a/src/lang/ru.rs b/src/lang/ru.rs index 30bc52d95..f90f905cf 100644 --- a/src/lang/ru.rs +++ b/src/lang/ru.rs @@ -153,6 +153,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Action", "Действие"), ("Add", "Добавить"), ("Local Port", "Локальный порт"), + ("Local Address", ""), + ("Change Local Port", ""), ("setup_server_tip", "Для более быстрого подключения настройте свой собственный сервер подключения"), ("Too short, at least 6 characters.", "Слишком коротко, минимум 6 символов"), ("The confirmation is not identical.", "Подтверждение не совпадает"), diff --git a/src/lang/sk.rs b/src/lang/sk.rs index 5c3b7ef6e..96213b4f6 100644 --- a/src/lang/sk.rs +++ b/src/lang/sk.rs @@ -153,6 +153,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Action", "Akcia"), ("Add", "Pridať"), ("Local Port", "Lokálny port"), + ("Local Address", ""), + ("Change Local Port", ""), ("setup_server_tip", "Pre zrýchlenie pripojenia si nainštalujte svoj vlastný server"), ("Too short, at least 6 characters.", "Príliš krátke, vyžaduje sa aspoň 6 znakov."), ("The confirmation is not identical.", "Potvrdenie nie je zhodné."), diff --git a/src/lang/template.rs b/src/lang/template.rs index 2a2d6eb8a..4c02ab45b 100644 --- a/src/lang/template.rs +++ b/src/lang/template.rs @@ -153,6 +153,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Action", ""), ("Add", ""), ("Local Port", ""), + ("Local Address", ""), + ("Change Local Port", ""), ("setup_server_tip", ""), ("Too short, at least 6 characters.", ""), ("The confirmation is not identical.", ""), diff --git a/src/lang/tr.rs b/src/lang/tr.rs index 8daa4bb88..6bdebc24e 100644 --- a/src/lang/tr.rs +++ b/src/lang/tr.rs @@ -153,6 +153,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Action", "Eylem"), ("Add", "Ekle"), ("Local Port", "Yerel Port"), + ("Local Address", ""), + ("Change Local Port", ""), ("setup_server_tip", "Daha hızlı bağlantı için kendi sunucunuzu kurun"), ("Too short, at least 6 characters.", "Çok kısa en az 6 karakter gerekli."), ("The confirmation is not identical.", "Doğrulama yapılamadı."), diff --git a/src/lang/tw.rs b/src/lang/tw.rs index 5f9a6632c..460145cbe 100644 --- a/src/lang/tw.rs +++ b/src/lang/tw.rs @@ -153,6 +153,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Action", "操作"), ("Add", "新增"), ("Local Port", "本機連接埠"), + ("Local Address", "本機地址"), + ("Change Local Port", "修改本機連接埠"), ("setup_server_tip", "若您需要更快的連接速度,可以選擇自行建立伺服器"), ("Too short, at least 6 characters.", "過短,至少需 6 個字元。"), ("The confirmation is not identical.", "兩次輸入不相符"), diff --git a/src/lang/vn.rs b/src/lang/vn.rs index 541436331..781c9629d 100644 --- a/src/lang/vn.rs +++ b/src/lang/vn.rs @@ -153,6 +153,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Action", "Hành động"), ("Add", "Thêm"), ("Local Port", "Cổng nội bộ"), + ("Local Address", ""), + ("Change Local Port", ""), ("setup_server_tip", "Để kết nối nhanh hơn, hãy tự tạo máy chủ riêng"), ("Too short, at least 6 characters.", "Quá ngắn, độ dài phải ít nhất là 6."), ("The confirmation is not identical.", "Xác minh không khớp"), diff --git a/src/ui_interface.rs b/src/ui_interface.rs index 3e357faa7..c42a99037 100644 --- a/src/ui_interface.rs +++ b/src/ui_interface.rs @@ -765,7 +765,9 @@ pub fn is_release() -> bool { #[inline] pub fn is_root() -> bool { - crate::platform::is_root() + #[cfg(not(any(target_os = "android", target_os = "ios")))] + return crate::platform::is_root(); + false } #[inline] diff --git a/src/ui_session_interface.rs b/src/ui_session_interface.rs index 937c7e9cc..9e2a09545 100644 --- a/src/ui_session_interface.rs +++ b/src/ui_session_interface.rs @@ -146,10 +146,9 @@ impl Session { let decoder = scrap::codec::Decoder::video_codec_state(&self.id); let mut h264 = decoder.score_h264 > 0; let mut h265 = decoder.score_h265 > 0; - if let Some((encoding_264, encoding_265)) = self.lc.read().unwrap().supported_encoding { - h264 = h264 && encoding_264; - h265 = h265 && encoding_265; - } + let (encoding_264, encoding_265) = self.lc.read().unwrap().supported_encoding.unwrap_or_default(); + h264 = h264 && encoding_264; + h265 = h265 && encoding_265; return (h264, h265); } (false, false) @@ -1119,6 +1118,7 @@ impl Interface for Session { } fn handle_peer_info(&mut self, mut pi: PeerInfo) { + log::debug!("handle_peer_info :{:?}", pi); pi.username = self.lc.read().unwrap().get_username(&pi); if pi.current_display as usize >= pi.displays.len() { pi.current_display = 0;