From ccb60ace8fde3fde2d4bd9bde93b90e3994a8674 Mon Sep 17 00:00:00 2001 From: csf Date: Tue, 13 Sep 2022 16:28:22 +0800 Subject: [PATCH 1/7] fix mouse out of bounds --- flutter/lib/models/model.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index c37ae1046..c6f38534a 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -1240,8 +1240,8 @@ class FFI { return; } evt['type'] = type; - var x = evt['x']; - var y = max(0.0, (evt['y'] as double) - tabBarHeight); + double x = evt['x']; + double y = max(0.0, (evt['y'] as double) - tabBarHeight); if (isMove) { canvasModel.moveDesktopMouse(x, y); } @@ -1264,9 +1264,6 @@ class FFI { y -= canvasModel.y; } - if (!isMove && (x < 0 || x > d.width || y < 0 || y > d.height)) { - return; - } x /= canvasModel.scale; y /= canvasModel.scale; x += d.x; @@ -1275,6 +1272,9 @@ class FFI { 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 = ''; From d3eac8539d46167b885d6c0945179c1f79189878 Mon Sep 17 00:00:00 2001 From: csf Date: Tue, 13 Sep 2022 17:39:24 +0800 Subject: [PATCH 2/7] fix android no input permission --- flutter/lib/models/server_model.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/flutter/lib/models/server_model.dart b/flutter/lib/models/server_model.dart index 33ce7e707..737d0b22b 100644 --- a/flutter/lib/models/server_model.dart +++ b/flutter/lib/models/server_model.dart @@ -133,8 +133,6 @@ class ServerModel with ChangeNotifier { _fileOk = fileOption.isEmpty; } - // input (mouse control) false by default - bind.mainSetOption(key: "enable-keyboard", value: "N"); notifyListeners(); } From a28fd5d772dc95adac2102216e3feffd1b7f7e6f Mon Sep 17 00:00:00 2001 From: csf Date: Tue, 13 Sep 2022 21:36:38 +0800 Subject: [PATCH 3/7] refactor: del unused or dead code and optimize reusable code --- flutter/lib/common.dart | 11 + flutter/lib/consts.dart | 230 +++++++++++ .../lib/desktop/pages/connection_page.dart | 210 +--------- .../lib/desktop/pages/file_manager_page.dart | 140 +------ .../lib/desktop/pages/port_forward_page.dart | 2 +- flutter/lib/desktop/pages/remote_page.dart | 373 +----------------- flutter/lib/desktop/pages/server_page.dart | 7 - .../lib/desktop/widgets/peercard_widget.dart | 16 +- flutter/lib/mobile/pages/connection_page.dart | 9 - flutter/lib/mobile/pages/remote_page.dart | 235 +---------- 10 files changed, 259 insertions(+), 974 deletions(-) diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index 9c3a5724f..aed6d6fd8 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -898,3 +898,14 @@ Future>? matchPeers(String searchText, List peers) async { } return filteredList; } + +/// Get the image for the current [platform]. +Widget getPlatformImage(String platform, {double size = 50}) { + platform = platform.toLowerCase(); + if (platform == 'mac os') { + platform = 'mac'; + } else if (platform != 'linux' && platform != 'android') { + platform = 'win'; + } + return Image.asset('assets/$platform.png', height: size, width: size); +} diff --git a/flutter/lib/consts.dart b/flutter/lib/consts.dart index 70fc9f065..8986f05ec 100644 --- a/flutter/lib/consts.dart +++ b/flutter/lib/consts.dart @@ -16,3 +16,233 @@ const int kDesktopDefaultDisplayWidth = 1080; const int kDesktopDefaultDisplayHeight = 720; const kInvalidValueStr = "InvalidValueStr"; + +/// flutter/packages/flutter/lib/src/services/keyboard_key.dart -> _keyLabels +/// see [LogicalKeyboardKey.keyLabel] +const Map logicalKeyMap = { + 0x00000000020: 'VK_SPACE', + 0x00000000022: 'VK_QUOTE', + 0x0000000002c: 'VK_COMMA', + 0x0000000002d: 'VK_MINUS', + 0x0000000002f: 'VK_SLASH', + 0x00000000030: 'VK_0', + 0x00000000031: 'VK_1', + 0x00000000032: 'VK_2', + 0x00000000033: 'VK_3', + 0x00000000034: 'VK_4', + 0x00000000035: 'VK_5', + 0x00000000036: 'VK_6', + 0x00000000037: 'VK_7', + 0x00000000038: 'VK_8', + 0x00000000039: 'VK_9', + 0x0000000003b: 'VK_SEMICOLON', + 0x0000000003d: 'VK_PLUS', // it is = + 0x0000000005b: 'VK_LBRACKET', + 0x0000000005c: 'VK_BACKSLASH', + 0x0000000005d: 'VK_RBRACKET', + 0x00000000061: 'VK_A', + 0x00000000062: 'VK_B', + 0x00000000063: 'VK_C', + 0x00000000064: 'VK_D', + 0x00000000065: 'VK_E', + 0x00000000066: 'VK_F', + 0x00000000067: 'VK_G', + 0x00000000068: 'VK_H', + 0x00000000069: 'VK_I', + 0x0000000006a: 'VK_J', + 0x0000000006b: 'VK_K', + 0x0000000006c: 'VK_L', + 0x0000000006d: 'VK_M', + 0x0000000006e: 'VK_N', + 0x0000000006f: 'VK_O', + 0x00000000070: 'VK_P', + 0x00000000071: 'VK_Q', + 0x00000000072: 'VK_R', + 0x00000000073: 'VK_S', + 0x00000000074: 'VK_T', + 0x00000000075: 'VK_U', + 0x00000000076: 'VK_V', + 0x00000000077: 'VK_W', + 0x00000000078: 'VK_X', + 0x00000000079: 'VK_Y', + 0x0000000007a: 'VK_Z', + 0x00100000008: 'VK_BACK', + 0x00100000009: 'VK_TAB', + 0x0010000000d: 'VK_ENTER', + 0x0010000001b: 'VK_ESCAPE', + 0x0010000007f: 'VK_DELETE', + 0x00100000104: 'VK_CAPITAL', + 0x00100000301: 'VK_DOWN', + 0x00100000302: 'VK_LEFT', + 0x00100000303: 'VK_RIGHT', + 0x00100000304: 'VK_UP', + 0x00100000305: 'VK_END', + 0x00100000306: 'VK_HOME', + 0x00100000307: 'VK_NEXT', + 0x00100000308: 'VK_PRIOR', + 0x00100000401: 'VK_CLEAR', + 0x00100000407: 'VK_INSERT', + 0x00100000504: 'VK_CANCEL', + 0x00100000506: 'VK_EXECUTE', + 0x00100000508: 'VK_HELP', + 0x00100000509: 'VK_PAUSE', + 0x0010000050c: 'VK_SELECT', + 0x00100000608: 'VK_PRINT', + 0x00100000705: 'VK_CONVERT', + 0x00100000706: 'VK_FINAL', + 0x00100000711: 'VK_HANGUL', + 0x00100000712: 'VK_HANJA', + 0x00100000713: 'VK_JUNJA', + 0x00100000718: 'VK_KANA', + 0x00100000719: 'VK_KANJI', + 0x00100000801: 'VK_F1', + 0x00100000802: 'VK_F2', + 0x00100000803: 'VK_F3', + 0x00100000804: 'VK_F4', + 0x00100000805: 'VK_F5', + 0x00100000806: 'VK_F6', + 0x00100000807: 'VK_F7', + 0x00100000808: 'VK_F8', + 0x00100000809: 'VK_F9', + 0x0010000080a: 'VK_F10', + 0x0010000080b: 'VK_F11', + 0x0010000080c: 'VK_F12', + 0x00100000d2b: 'Apps', + 0x00200000002: 'VK_SLEEP', + 0x00200000100: 'VK_CONTROL', + 0x00200000101: 'RControl', + 0x00200000102: 'VK_SHIFT', + 0x00200000103: 'RShift', + 0x00200000104: 'VK_MENU', + 0x00200000105: 'RAlt', + 0x002000001f0: 'VK_CONTROL', + 0x002000001f2: 'VK_SHIFT', + 0x002000001f4: 'VK_MENU', + 0x002000001f6: 'Meta', + 0x0020000022a: 'VK_MULTIPLY', + 0x0020000022b: 'VK_ADD', + 0x0020000022d: 'VK_SUBTRACT', + 0x0020000022e: 'VK_DECIMAL', + 0x0020000022f: 'VK_DIVIDE', + 0x00200000230: 'VK_NUMPAD0', + 0x00200000231: 'VK_NUMPAD1', + 0x00200000232: 'VK_NUMPAD2', + 0x00200000233: 'VK_NUMPAD3', + 0x00200000234: 'VK_NUMPAD4', + 0x00200000235: 'VK_NUMPAD5', + 0x00200000236: 'VK_NUMPAD6', + 0x00200000237: 'VK_NUMPAD7', + 0x00200000238: 'VK_NUMPAD8', + 0x00200000239: 'VK_NUMPAD9', +}; + +/// flutter/packages/flutter/lib/src/services/keyboard_key.dart -> _debugName +/// see [PhysicalKeyboardKey.debugName] -> _debugName +const Map physicalKeyMap = { + 0x00010082: 'VK_SLEEP', + 0x00070004: 'VK_A', + 0x00070005: 'VK_B', + 0x00070006: 'VK_C', + 0x00070007: 'VK_D', + 0x00070008: 'VK_E', + 0x00070009: 'VK_F', + 0x0007000a: 'VK_G', + 0x0007000b: 'VK_H', + 0x0007000c: 'VK_I', + 0x0007000d: 'VK_J', + 0x0007000e: 'VK_K', + 0x0007000f: 'VK_L', + 0x00070010: 'VK_M', + 0x00070011: 'VK_N', + 0x00070012: 'VK_O', + 0x00070013: 'VK_P', + 0x00070014: 'VK_Q', + 0x00070015: 'VK_R', + 0x00070016: 'VK_S', + 0x00070017: 'VK_T', + 0x00070018: 'VK_U', + 0x00070019: 'VK_V', + 0x0007001a: 'VK_W', + 0x0007001b: 'VK_X', + 0x0007001c: 'VK_Y', + 0x0007001d: 'VK_Z', + 0x0007001e: 'VK_1', + 0x0007001f: 'VK_2', + 0x00070020: 'VK_3', + 0x00070021: 'VK_4', + 0x00070022: 'VK_5', + 0x00070023: 'VK_6', + 0x00070024: 'VK_7', + 0x00070025: 'VK_8', + 0x00070026: 'VK_9', + 0x00070027: 'VK_0', + 0x00070028: 'VK_ENTER', + 0x00070029: 'VK_ESCAPE', + 0x0007002a: 'VK_BACK', + 0x0007002b: 'VK_TAB', + 0x0007002c: 'VK_SPACE', + 0x0007002d: 'VK_MINUS', + 0x0007002e: 'VK_PLUS', // it is = + 0x0007002f: 'VK_LBRACKET', + 0x00070030: 'VK_RBRACKET', + 0x00070033: 'VK_SEMICOLON', + 0x00070034: 'VK_QUOTE', + 0x00070036: 'VK_COMMA', + 0x00070038: 'VK_SLASH', + 0x00070039: 'VK_CAPITAL', + 0x0007003a: 'VK_F1', + 0x0007003b: 'VK_F2', + 0x0007003c: 'VK_F3', + 0x0007003d: 'VK_F4', + 0x0007003e: 'VK_F5', + 0x0007003f: 'VK_F6', + 0x00070040: 'VK_F7', + 0x00070041: 'VK_F8', + 0x00070042: 'VK_F9', + 0x00070043: 'VK_F10', + 0x00070044: 'VK_F11', + 0x00070045: 'VK_F12', + 0x00070049: 'VK_INSERT', + 0x0007004a: 'VK_HOME', + 0x0007004b: 'VK_PRIOR', // Page Up + 0x0007004c: 'VK_DELETE', + 0x0007004d: 'VK_END', + 0x0007004e: 'VK_NEXT', // Page Down + 0x0007004f: 'VK_RIGHT', + 0x00070050: 'VK_LEFT', + 0x00070051: 'VK_DOWN', + 0x00070052: 'VK_UP', + 0x00070053: 'Num Lock', // TODO rust not impl + 0x00070054: 'VK_DIVIDE', // numpad + 0x00070055: 'VK_MULTIPLY', + 0x00070056: 'VK_SUBTRACT', + 0x00070057: 'VK_ADD', + 0x00070058: 'VK_ENTER', // num enter + 0x00070059: 'VK_NUMPAD0', + 0x0007005a: 'VK_NUMPAD1', + 0x0007005b: 'VK_NUMPAD2', + 0x0007005c: 'VK_NUMPAD3', + 0x0007005d: 'VK_NUMPAD4', + 0x0007005e: 'VK_NUMPAD5', + 0x0007005f: 'VK_NUMPAD6', + 0x00070060: 'VK_NUMPAD7', + 0x00070061: 'VK_NUMPAD8', + 0x00070062: 'VK_NUMPAD9', + 0x00070063: 'VK_DECIMAL', + 0x00070075: 'VK_HELP', + 0x00070077: 'VK_SELECT', + 0x00070088: 'VK_KANA', + 0x0007008a: 'VK_CONVERT', + 0x000700e0: 'VK_CONTROL', + 0x000700e1: 'VK_SHIFT', + 0x000700e2: 'VK_MENU', + 0x000700e3: 'Meta', + 0x000700e4: 'RControl', + 0x000700e5: 'RShift', + 0x000700e6: 'RAlt', + 0x000700e7: 'RWin', + 0x000c00b1: 'VK_PAUSE', + 0x000c00cd: 'VK_PAUSE', + 0x000c019e: 'LOCK_SCREEN', + 0x000c0208: 'VK_PRINT', +}; diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index 64a74d22a..134fe4219 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -8,18 +8,12 @@ import 'package:flutter_hbb/desktop/widgets/peer_widget.dart'; import 'package:flutter_hbb/desktop/widgets/peercard_widget.dart'; import 'package:flutter_hbb/utils/multi_window_manager.dart'; import 'package:get/get.dart'; -import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher_string.dart'; import '../../common.dart'; import '../../common/formatter/id_formatter.dart'; -import '../../mobile/pages/scan_page.dart'; -import '../../mobile/pages/settings_page.dart'; -import '../../models/model.dart'; import '../../models/platform_model.dart'; -// enum RemoteType { recently, favorite, discovered, addressBook } - /// Connection page for connecting to a remote peer. class ConnectionPage extends StatefulWidget { const ConnectionPage({Key? key}) : super(key: key); @@ -33,9 +27,6 @@ class _ConnectionPageState extends State { /// Controller for the id input bar. final _idController = IDTextEditingController(); - /// Update url. If it's not null, means an update is available. - final _updateUrl = ''; - Timer? _updateTimer; @override @@ -67,7 +58,6 @@ class _ConnectionPageState extends State { Expanded( child: Column( children: [ - getUpdateUI(), Row( children: [ getSearchBarUI(context), @@ -131,28 +121,6 @@ class _ConnectionPageState extends State { } } - /// UI for software update. - /// If [_updateUrl] is not empty, shows a button to update the software. - Widget getUpdateUI() { - return _updateUrl.isEmpty - ? SizedBox(height: 0) - : InkWell( - onTap: () async { - final url = _updateUrl + '.apk'; - if (await canLaunchUrlString(url)) { - await launchUrlString(url); - } - }, - child: Container( - alignment: AlignmentDirectional.center, - width: double.infinity, - color: Colors.pinkAccent, - padding: EdgeInsets.symmetric(vertical: 12), - child: Text(translate('Download new version'), - style: TextStyle( - color: Colors.white, fontWeight: FontWeight.bold)))); - } - /// UI for the search bar. /// Search for a peer and connect to it if the id exists. Widget getSearchBarUI(BuildContext context) { @@ -328,86 +296,6 @@ class _ConnectionPageState extends State { super.dispose(); } - /// Get the image for the current [platform]. - Widget getPlatformImage(String platform) { - platform = platform.toLowerCase(); - if (platform == 'mac os') - platform = 'mac'; - else if (platform != 'linux' && platform != 'android') platform = 'win'; - return Image.asset('assets/$platform.png', height: 50); - } - - bool hitTag(List selectedTags, List idents) { - if (selectedTags.isEmpty) { - return true; - } - if (idents.isEmpty) { - return false; - } - for (final tag in selectedTags) { - if (!idents.contains(tag)) { - return false; - } - } - return true; - } - - // /// Show the peer menu and handle user's choice. - // /// User might remove the peer or send a file to the peer. - // void showPeerMenu(BuildContext context, String id, RemoteType rType) async { - // var items = [ - // PopupMenuItem( - // child: Text(translate('Connect')), value: 'connect'), - // PopupMenuItem( - // child: Text(translate('Transfer File')), value: 'file'), - // PopupMenuItem( - // child: Text(translate('TCP Tunneling')), value: 'tcp-tunnel'), - // PopupMenuItem(child: Text(translate('Rename')), value: 'rename'), - // rType == RemoteType.addressBook - // ? PopupMenuItem( - // child: Text(translate('Remove')), value: 'ab-delete') - // : PopupMenuItem( - // child: Text(translate('Remove')), value: 'remove'), - // PopupMenuItem( - // child: Text(translate('Unremember Password')), - // value: 'unremember-password'), - // ]; - // if (rType == RemoteType.favorite) { - // items.add(PopupMenuItem( - // child: Text(translate('Remove from Favorites')), - // value: 'remove-fav')); - // } else if (rType != RemoteType.addressBook) { - // items.add(PopupMenuItem( - // child: Text(translate('Add to Favorites')), value: 'add-fav')); - // } else { - // items.add(PopupMenuItem( - // child: Text(translate('Edit Tag')), value: 'ab-edit-tag')); - // } - // var value = await showMenu( - // context: context, - // position: this._menuPos, - // items: items, - // elevation: 8, - // ); - // if (value == 'remove') { - // setState(() => gFFI.setByName('remove', '$id')); - // () async { - // removePreference(id); - // }(); - // } else if (value == 'file') { - // connect(id, isFileTransfer: true); - // } else if (value == 'add-fav') { - // } else if (value == 'connect') { - // connect(id, isFileTransfer: false); - // } else if (value == 'ab-delete') { - // gFFI.abModel.deletePeer(id); - // await gFFI.abModel.updateAb(); - // setState(() {}); - // } else if (value == 'ab-edit-tag') { - // abEditTag(id); - // } - // } - var svcStopped = false.obs; var svcStatusCode = 0.obs; var svcIsUsingPublicServer = true.obs; @@ -454,7 +342,7 @@ class _ConnectionPageState extends State { crossAxisAlignment: CrossAxisAlignment.center, children: [ light, - Text("${translate('Ready')}"), + Text(translate('Ready')), svcIsUsingPublicServer.value ? InkWell( onTap: onUsePublicServerGuide, @@ -469,7 +357,7 @@ class _ConnectionPageState extends State { } void onUsePublicServerGuide() { - final url = "https://rustdesk.com/blog/id-relay-set/"; + const url = "https://rustdesk.com/blog/id-relay-set/"; canLaunchUrlString(url).then((can) { if (can) { launchUrlString(url); @@ -857,100 +745,6 @@ class _ConnectionPageState extends State { } } -class WebMenu extends StatefulWidget { - @override - _WebMenuState createState() => _WebMenuState(); -} - -class _WebMenuState extends State { - String? username; - String url = ""; - - @override - void initState() { - super.initState(); - () async { - final usernameRes = await getUsername(); - final urlRes = await getUrl(); - var update = false; - if (usernameRes != username) { - username = usernameRes; - update = true; - } - if (urlRes != url) { - url = urlRes; - update = true; - } - - if (update) { - setState(() {}); - } - }(); - } - - @override - Widget build(BuildContext context) { - Provider.of(context); - return PopupMenuButton( - icon: Icon(Icons.more_vert), - itemBuilder: (context) { - return (isIOS - ? [ - PopupMenuItem( - child: Icon(Icons.qr_code_scanner, color: Colors.black), - value: "scan", - ) - ] - : >[]) + - [ - PopupMenuItem( - child: Text(translate('ID/Relay Server')), - value: "server", - ) - ] + - (url.contains('admin.rustdesk.com') - ? >[] - : [ - PopupMenuItem( - child: Text(username == null - ? translate("Login") - : translate("Logout") + ' ($username)'), - value: "login", - ) - ]) + - [ - PopupMenuItem( - child: Text(translate('About') + ' RustDesk'), - value: "about", - ) - ]; - }, - onSelected: (value) { - if (value == 'server') { - showServerSettings(gFFI.dialogManager); - } - if (value == 'about') { - showAbout(gFFI.dialogManager); - } - if (value == 'login') { - if (username == null) { - showLogin(gFFI.dialogManager); - } else { - logout(gFFI.dialogManager); - } - } - if (value == 'scan') { - Navigator.push( - context, - MaterialPageRoute( - builder: (BuildContext context) => ScanPage(), - ), - ); - } - }); - } -} - class _PeerTabbedPage extends StatefulWidget { final List tabs; final List children; diff --git a/flutter/lib/desktop/pages/file_manager_page.dart b/flutter/lib/desktop/pages/file_manager_page.dart index eee3c226b..ced61e8d9 100644 --- a/flutter/lib/desktop/pages/file_manager_page.dart +++ b/flutter/lib/desktop/pages/file_manager_page.dart @@ -67,7 +67,7 @@ class _FileManagerPageState extends State if (!Platform.isLinux) { Wakelock.enable(); } - print("init success with id ${widget.id}"); + debugPrint("File manager page init success with id ${widget.id}"); // register location listener _locationNodeLocal.addListener(onLocalLocationFocusChanged); _locationNodeRemote.addListener(onRemoteLocationFocusChanged); @@ -307,109 +307,6 @@ class _FileManagerPageState extends State ) ], )), - // Center(child: listTail(isLocal: isLocal)), - // Expanded( - // child: ListView.builder( - // controller: ScrollController(), - // itemCount: entries.length + 1, - // itemBuilder: (context, index) { - // if (index >= entries.length) { - // return listTail(isLocal: isLocal); - // } - // var selected = false; - // if (model.selectMode) { - // selected = _selectedItems.contains(entries[index]); - // } - // - // final sizeStr = entries[index].isFile - // ? readableFileSize(entries[index].size.toDouble()) - // : ""; - // return Card( - // child: ListTile( - // leading: Icon( - // entries[index].isFile ? Icons.feed_outlined : Icons.folder, - // size: 40), - // title: Text(entries[index].name), - // selected: selected, - // subtitle: Text( - // entries[index] - // .lastModified() - // .toString() - // .replaceAll(".000", "") + - // " " + - // sizeStr, - // style: TextStyle(fontSize: 12, color: MyTheme.darkGray), - // ), - // trailing: needShowCheckBox() - // ? Checkbox( - // value: selected, - // onChanged: (v) { - // if (v == null) return; - // if (v && !selected) { - // _selectedItems.add(isLocal, entries[index]); - // } else if (!v && selected) { - // _selectedItems.remove(entries[index]); - // } - // setState(() {}); - // }) - // : PopupMenuButton( - // icon: Icon(Icons.more_vert), - // itemBuilder: (context) { - // return [ - // PopupMenuItem( - // child: Text(translate("Delete")), - // value: "delete", - // ), - // PopupMenuItem( - // child: Text(translate("Multi Select")), - // value: "multi_select", - // ), - // PopupMenuItem( - // child: Text(translate("Properties")), - // value: "properties", - // enabled: false, - // ) - // ]; - // }, - // onSelected: (v) { - // if (v == "delete") { - // final items = SelectedItems(); - // items.add(isLocal, entries[index]); - // model.removeAction(items); - // } else if (v == "multi_select") { - // _selectedItems.clear(); - // model.toggleSelectMode(); - // } - // }), - // onTap: () { - // if (model.selectMode && !_selectedItems.isOtherPage(isLocal)) { - // if (selected) { - // _selectedItems.remove(entries[index]); - // } else { - // _selectedItems.add(isLocal, entries[index]); - // } - // setState(() {}); - // return; - // } - // if (entries[index].isDirectory) { - // openDirectory(entries[index].path, isLocal: isLocal); - // breadCrumbScrollToEnd(isLocal); - // } else { - // // Perform file-related tasks. - // } - // }, - // onLongPress: () { - // _selectedItems.clear(); - // model.toggleSelectMode(); - // if (model.selectMode) { - // _selectedItems.add(isLocal, entries[index]); - // } - // setState(() {}); - // }, - // ), - // ); - // }, - // )) ]), ), ); @@ -736,43 +633,9 @@ class _FileManagerPageState extends State )); } - Widget listTail({bool isLocal = false}) { - final dir = isLocal ? model.currentLocalDir : model.currentRemoteDir; - return Container( - height: 100, - child: Column( - children: [ - Padding( - padding: EdgeInsets.fromLTRB(30, 5, 30, 0), - child: Text( - dir.path, - style: TextStyle(color: MyTheme.darkGray), - ), - ), - Padding( - padding: EdgeInsets.all(2), - child: Text( - "${translate("Total")}: ${dir.entries.length} ${translate("items")}", - style: TextStyle(color: MyTheme.darkGray), - ), - ) - ], - ), - ); - } - @override bool get wantKeepAlive => true; - /// Get the image for the current [platform]. - Widget getPlatformImage(String platform) { - platform = platform.toLowerCase(); - if (platform == 'mac os') - platform = 'mac'; - else if (platform != 'linux' && platform != 'android') platform = 'win'; - return Image.asset('assets/$platform.png', width: 25, height: 25); - } - void onLocalLocationFocusChanged() { debugPrint("focus changed on local"); if (_locationNodeLocal.hasFocus) { @@ -861,7 +724,6 @@ class _FileManagerPageState extends State openDirectory(String path, {bool isLocal = false}) { model.openDirectory(path, isLocal: isLocal).then((_) { - print("scroll"); breadCrumbScrollToEnd(isLocal); }); } diff --git a/flutter/lib/desktop/pages/port_forward_page.dart b/flutter/lib/desktop/pages/port_forward_page.dart index f3e988744..49946cc56 100644 --- a/flutter/lib/desktop/pages/port_forward_page.dart +++ b/flutter/lib/desktop/pages/port_forward_page.dart @@ -52,7 +52,7 @@ class _PortForwardPageState extends State if (!Platform.isLinux) { Wakelock.enable(); } - debugPrint("init success with id ${widget.id}"); + debugPrint("Port forward page init success with id ${widget.id}"); } @override diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart index 35ab548c3..43d48740e 100644 --- a/flutter/lib/desktop/pages/remote_page.dart +++ b/flutter/lib/desktop/pages/remote_page.dart @@ -10,8 +10,7 @@ import 'package:provider/provider.dart'; import 'package:wakelock/wakelock.dart'; import 'package:flutter_custom_cursor/flutter_custom_cursor.dart'; -// import 'package:window_manager/window_manager.dart'; - +import '../../consts.dart'; import '../widgets/remote_menubar.dart'; import '../../common.dart'; import '../../mobile/widgets/dialog.dart'; @@ -19,8 +18,6 @@ import '../../models/model.dart'; import '../../models/platform_model.dart'; import '../../common/shared_state.dart'; -final initText = '\1' * 1024; - class RemotePage extends StatefulWidget { const RemotePage({ Key? key, @@ -38,15 +35,13 @@ class RemotePage extends StatefulWidget { class _RemotePageState extends State with AutomaticKeepAliveClientMixin { Timer? _timer; - String _value = ''; String keyboardMode = "legacy"; final _cursorOverImage = false.obs; late RxBool _showRemoteCursor; late RxBool _remoteCursorMoved; late RxBool _keyboardEnabled; - final FocusNode _mobileFocusNode = FocusNode(); - final FocusNode _physicalFocusNode = FocusNode(); + final FocusNode _rawKeyFocusNode = FocusNode(); var _isPhysicalMouse = false; var _imageFocused = false; @@ -95,11 +90,9 @@ class _RemotePageState extends State if (!Platform.isLinux) { Wakelock.enable(); } - _physicalFocusNode.requestFocus(); + _rawKeyFocusNode.requestFocus(); _ffi.ffiModel.updateEventListener(widget.id); - _ffi.listenToMouse(true); _ffi.qualityMonitorModel.checkShowQualityMonitor(widget.id); - // WindowManager.instance.addListener(this); _showRemoteCursor.value = bind.sessionGetToggleOptionSync( id: widget.id, arg: 'show-remote-cursor'); } @@ -108,9 +101,7 @@ class _RemotePageState extends State void dispose() { debugPrint("REMOTE PAGE dispose ${widget.id}"); _ffi.dialogManager.hideMobileActionsOverlay(); - _ffi.listenToMouse(false); - _mobileFocusNode.dispose(); - _physicalFocusNode.dispose(); + _rawKeyFocusNode.dispose(); _ffi.close(); _timer?.cancel(); _ffi.dialogManager.dismissAll(); @@ -119,7 +110,6 @@ class _RemotePageState extends State if (!Platform.isLinux) { Wakelock.disable(); } - // WindowManager.instance.removeListener(this); Get.delete(tag: widget.id); super.dispose(); _removeStates(widget.id); @@ -129,87 +119,10 @@ class _RemotePageState extends State _ffi.resetModifiers(); } - // handle mobile virtual keyboard - void handleInput(String newValue) { - var oldValue = _value; - _value = newValue; - if (isIOS) { - var i = newValue.length - 1; - for (; i >= 0 && newValue[i] != '\1'; --i) {} - var j = oldValue.length - 1; - for (; j >= 0 && oldValue[j] != '\1'; --j) {} - if (i < j) j = i; - newValue = newValue.substring(j + 1); - oldValue = oldValue.substring(j + 1); - var common = 0; - for (; - common < oldValue.length && - common < newValue.length && - newValue[common] == oldValue[common]; - ++common) {} - for (i = 0; i < oldValue.length - common; ++i) { - _ffi.inputKey('VK_BACK'); - } - if (newValue.length > common) { - var s = newValue.substring(common); - if (s.length > 1) { - bind.sessionInputString(id: widget.id, value: s); - } else { - inputChar(s); - } - } - return; - } - if (oldValue.isNotEmpty && - newValue.isNotEmpty && - oldValue[0] == '\1' && - newValue[0] != '\1') { - // clipboard - oldValue = ''; - } - if (newValue.length == oldValue.length) { - // ? - } else if (newValue.length < oldValue.length) { - const char = 'VK_BACK'; - _ffi.inputKey(char); - } else { - final content = newValue.substring(oldValue.length); - if (content.length > 1) { - if (oldValue != '' && - content.length == 2 && - (content == '""' || - content == '()' || - content == '[]' || - content == '<>' || - content == "{}" || - content == '”“' || - content == '《》' || - content == '()' || - content == '【】')) { - // can not only input content[0], because when input ], [ are also auo insert, which cause ] never be input - bind.sessionInputString(id: widget.id, value: content); - return; - } - bind.sessionInputString(id: widget.id, value: content); - } else { - inputChar(content); - } - } - } - - void inputChar(String char) { - if (char == '\n') { - char = 'VK_RETURN'; - } else if (char == ' ') { - char = 'VK_SPACE'; - } - _ffi.inputKey(char); - } - void sendRawKey(RawKeyEvent e, {bool? down, bool? press}) { // for maximum compatibility - final label = _logicalKeyMap[e.logicalKey.keyId] ?? - _physicalKeyMap[e.physicalKey.usbHidUsage] ?? + final label = logicalKeyMap[e.logicalKey.keyId] ?? + physicalKeyMap[e.physicalKey.usbHidUsage] ?? e.logicalKey.keyLabel; _ffi.inputKey(label, down: down, press: press ?? false); } @@ -339,7 +252,7 @@ class _RemotePageState extends State child: Focus( autofocus: true, canRequestFocus: true, - focusNode: _physicalFocusNode, + focusNode: _rawKeyFocusNode, onFocusChange: (bool v) { _imageFocused = v; }, @@ -347,15 +260,6 @@ class _RemotePageState extends State child: child)); } - /// touchMode only: - /// LongPress -> right click - /// OneFingerPan -> start/end -> left down start/end - /// onDoubleTapDown -> move to - /// onLongPressDown => move to - /// - /// mouseMode only: - /// DoubleFiner -> right click - /// HoldDrag -> left drag void _onPointHoverImage(PointerHoverEvent e) { if (e.kind != ui.PointerDeviceKind.mouse) return; if (!_isPhysicalMouse) { @@ -420,7 +324,7 @@ class _RemotePageState extends State void enterView(PointerEnterEvent evt) { if (!_imageFocused) { - _physicalFocusNode.requestFocus(); + _rawKeyFocusNode.requestFocus(); } _cursorOverImage.value = true; for (var f in _onEnterOrLeaveImage) { @@ -505,21 +409,6 @@ class _RemotePageState extends State return out; } - @override - void onWindowEvent(String eventName) { - print("window event: $eventName"); - switch (eventName) { - case 'resize': - _ffi.canvasModel.updateViewStyle(); - break; - case 'maximize': - Future.delayed(const Duration(milliseconds: 100), () { - _ffi.canvasModel.updateViewStyle(); - }); - break; - } - } - @override bool get wantKeepAlive => true; } @@ -747,249 +636,3 @@ class QualityMonitor extends StatelessWidget { ) : const SizedBox.shrink()))); } - -void sendPrompt(String id, bool isMac, String key) { - FFI _ffi = ffi(id); - final old = isMac ? _ffi.command : _ffi.ctrl; - if (isMac) { - _ffi.command = true; - } else { - _ffi.ctrl = true; - } - _ffi.inputKey(key); - if (isMac) { - _ffi.command = old; - } else { - _ffi.ctrl = old; - } -} - -/// flutter/packages/flutter/lib/src/services/keyboard_key.dart -> _keyLabels -/// see [LogicalKeyboardKey.keyLabel] -const Map _logicalKeyMap = { - 0x00000000020: 'VK_SPACE', - 0x00000000022: 'VK_QUOTE', - 0x0000000002c: 'VK_COMMA', - 0x0000000002d: 'VK_MINUS', - 0x0000000002f: 'VK_SLASH', - 0x00000000030: 'VK_0', - 0x00000000031: 'VK_1', - 0x00000000032: 'VK_2', - 0x00000000033: 'VK_3', - 0x00000000034: 'VK_4', - 0x00000000035: 'VK_5', - 0x00000000036: 'VK_6', - 0x00000000037: 'VK_7', - 0x00000000038: 'VK_8', - 0x00000000039: 'VK_9', - 0x0000000003b: 'VK_SEMICOLON', - 0x0000000003d: 'VK_PLUS', // it is = - 0x0000000005b: 'VK_LBRACKET', - 0x0000000005c: 'VK_BACKSLASH', - 0x0000000005d: 'VK_RBRACKET', - 0x00000000061: 'VK_A', - 0x00000000062: 'VK_B', - 0x00000000063: 'VK_C', - 0x00000000064: 'VK_D', - 0x00000000065: 'VK_E', - 0x00000000066: 'VK_F', - 0x00000000067: 'VK_G', - 0x00000000068: 'VK_H', - 0x00000000069: 'VK_I', - 0x0000000006a: 'VK_J', - 0x0000000006b: 'VK_K', - 0x0000000006c: 'VK_L', - 0x0000000006d: 'VK_M', - 0x0000000006e: 'VK_N', - 0x0000000006f: 'VK_O', - 0x00000000070: 'VK_P', - 0x00000000071: 'VK_Q', - 0x00000000072: 'VK_R', - 0x00000000073: 'VK_S', - 0x00000000074: 'VK_T', - 0x00000000075: 'VK_U', - 0x00000000076: 'VK_V', - 0x00000000077: 'VK_W', - 0x00000000078: 'VK_X', - 0x00000000079: 'VK_Y', - 0x0000000007a: 'VK_Z', - 0x00100000008: 'VK_BACK', - 0x00100000009: 'VK_TAB', - 0x0010000000d: 'VK_ENTER', - 0x0010000001b: 'VK_ESCAPE', - 0x0010000007f: 'VK_DELETE', - 0x00100000104: 'VK_CAPITAL', - 0x00100000301: 'VK_DOWN', - 0x00100000302: 'VK_LEFT', - 0x00100000303: 'VK_RIGHT', - 0x00100000304: 'VK_UP', - 0x00100000305: 'VK_END', - 0x00100000306: 'VK_HOME', - 0x00100000307: 'VK_NEXT', - 0x00100000308: 'VK_PRIOR', - 0x00100000401: 'VK_CLEAR', - 0x00100000407: 'VK_INSERT', - 0x00100000504: 'VK_CANCEL', - 0x00100000506: 'VK_EXECUTE', - 0x00100000508: 'VK_HELP', - 0x00100000509: 'VK_PAUSE', - 0x0010000050c: 'VK_SELECT', - 0x00100000608: 'VK_PRINT', - 0x00100000705: 'VK_CONVERT', - 0x00100000706: 'VK_FINAL', - 0x00100000711: 'VK_HANGUL', - 0x00100000712: 'VK_HANJA', - 0x00100000713: 'VK_JUNJA', - 0x00100000718: 'VK_KANA', - 0x00100000719: 'VK_KANJI', - 0x00100000801: 'VK_F1', - 0x00100000802: 'VK_F2', - 0x00100000803: 'VK_F3', - 0x00100000804: 'VK_F4', - 0x00100000805: 'VK_F5', - 0x00100000806: 'VK_F6', - 0x00100000807: 'VK_F7', - 0x00100000808: 'VK_F8', - 0x00100000809: 'VK_F9', - 0x0010000080a: 'VK_F10', - 0x0010000080b: 'VK_F11', - 0x0010000080c: 'VK_F12', - 0x00100000d2b: 'Apps', - 0x00200000002: 'VK_SLEEP', - 0x00200000100: 'VK_CONTROL', - 0x00200000101: 'RControl', - 0x00200000102: 'VK_SHIFT', - 0x00200000103: 'RShift', - 0x00200000104: 'VK_MENU', - 0x00200000105: 'RAlt', - 0x002000001f0: 'VK_CONTROL', - 0x002000001f2: 'VK_SHIFT', - 0x002000001f4: 'VK_MENU', - 0x002000001f6: 'Meta', - 0x0020000022a: 'VK_MULTIPLY', - 0x0020000022b: 'VK_ADD', - 0x0020000022d: 'VK_SUBTRACT', - 0x0020000022e: 'VK_DECIMAL', - 0x0020000022f: 'VK_DIVIDE', - 0x00200000230: 'VK_NUMPAD0', - 0x00200000231: 'VK_NUMPAD1', - 0x00200000232: 'VK_NUMPAD2', - 0x00200000233: 'VK_NUMPAD3', - 0x00200000234: 'VK_NUMPAD4', - 0x00200000235: 'VK_NUMPAD5', - 0x00200000236: 'VK_NUMPAD6', - 0x00200000237: 'VK_NUMPAD7', - 0x00200000238: 'VK_NUMPAD8', - 0x00200000239: 'VK_NUMPAD9', -}; - -/// flutter/packages/flutter/lib/src/services/keyboard_key.dart -> _debugName -/// see [PhysicalKeyboardKey.debugName] -> _debugName -const Map _physicalKeyMap = { - 0x00010082: 'VK_SLEEP', - 0x00070004: 'VK_A', - 0x00070005: 'VK_B', - 0x00070006: 'VK_C', - 0x00070007: 'VK_D', - 0x00070008: 'VK_E', - 0x00070009: 'VK_F', - 0x0007000a: 'VK_G', - 0x0007000b: 'VK_H', - 0x0007000c: 'VK_I', - 0x0007000d: 'VK_J', - 0x0007000e: 'VK_K', - 0x0007000f: 'VK_L', - 0x00070010: 'VK_M', - 0x00070011: 'VK_N', - 0x00070012: 'VK_O', - 0x00070013: 'VK_P', - 0x00070014: 'VK_Q', - 0x00070015: 'VK_R', - 0x00070016: 'VK_S', - 0x00070017: 'VK_T', - 0x00070018: 'VK_U', - 0x00070019: 'VK_V', - 0x0007001a: 'VK_W', - 0x0007001b: 'VK_X', - 0x0007001c: 'VK_Y', - 0x0007001d: 'VK_Z', - 0x0007001e: 'VK_1', - 0x0007001f: 'VK_2', - 0x00070020: 'VK_3', - 0x00070021: 'VK_4', - 0x00070022: 'VK_5', - 0x00070023: 'VK_6', - 0x00070024: 'VK_7', - 0x00070025: 'VK_8', - 0x00070026: 'VK_9', - 0x00070027: 'VK_0', - 0x00070028: 'VK_ENTER', - 0x00070029: 'VK_ESCAPE', - 0x0007002a: 'VK_BACK', - 0x0007002b: 'VK_TAB', - 0x0007002c: 'VK_SPACE', - 0x0007002d: 'VK_MINUS', - 0x0007002e: 'VK_PLUS', // it is = - 0x0007002f: 'VK_LBRACKET', - 0x00070030: 'VK_RBRACKET', - 0x00070033: 'VK_SEMICOLON', - 0x00070034: 'VK_QUOTE', - 0x00070036: 'VK_COMMA', - 0x00070038: 'VK_SLASH', - 0x00070039: 'VK_CAPITAL', - 0x0007003a: 'VK_F1', - 0x0007003b: 'VK_F2', - 0x0007003c: 'VK_F3', - 0x0007003d: 'VK_F4', - 0x0007003e: 'VK_F5', - 0x0007003f: 'VK_F6', - 0x00070040: 'VK_F7', - 0x00070041: 'VK_F8', - 0x00070042: 'VK_F9', - 0x00070043: 'VK_F10', - 0x00070044: 'VK_F11', - 0x00070045: 'VK_F12', - 0x00070049: 'VK_INSERT', - 0x0007004a: 'VK_HOME', - 0x0007004b: 'VK_PRIOR', // Page Up - 0x0007004c: 'VK_DELETE', - 0x0007004d: 'VK_END', - 0x0007004e: 'VK_NEXT', // Page Down - 0x0007004f: 'VK_RIGHT', - 0x00070050: 'VK_LEFT', - 0x00070051: 'VK_DOWN', - 0x00070052: 'VK_UP', - 0x00070053: 'Num Lock', // TODO rust not impl - 0x00070054: 'VK_DIVIDE', // numpad - 0x00070055: 'VK_MULTIPLY', - 0x00070056: 'VK_SUBTRACT', - 0x00070057: 'VK_ADD', - 0x00070058: 'VK_ENTER', // num enter - 0x00070059: 'VK_NUMPAD0', - 0x0007005a: 'VK_NUMPAD1', - 0x0007005b: 'VK_NUMPAD2', - 0x0007005c: 'VK_NUMPAD3', - 0x0007005d: 'VK_NUMPAD4', - 0x0007005e: 'VK_NUMPAD5', - 0x0007005f: 'VK_NUMPAD6', - 0x00070060: 'VK_NUMPAD7', - 0x00070061: 'VK_NUMPAD8', - 0x00070062: 'VK_NUMPAD9', - 0x00070063: 'VK_DECIMAL', - 0x00070075: 'VK_HELP', - 0x00070077: 'VK_SELECT', - 0x00070088: 'VK_KANA', - 0x0007008a: 'VK_CONVERT', - 0x000700e0: 'VK_CONTROL', - 0x000700e1: 'VK_SHIFT', - 0x000700e2: 'VK_MENU', - 0x000700e3: 'Meta', - 0x000700e4: 'RControl', - 0x000700e5: 'RShift', - 0x000700e6: 'RAlt', - 0x000700e7: 'RWin', - 0x000c00b1: 'VK_PAUSE', - 0x000c00cd: 'VK_PAUSE', - 0x000c019e: 'LOCK_SCREEN', - 0x000c0208: 'VK_PRINT', -}; diff --git a/flutter/lib/desktop/pages/server_page.dart b/flutter/lib/desktop/pages/server_page.dart index b49bfdc27..62e60ba26 100644 --- a/flutter/lib/desktop/pages/server_page.dart +++ b/flutter/lib/desktop/pages/server_page.dart @@ -98,13 +98,6 @@ class ConnectionManagerState extends State { gFFI.serverModel.updateClientState(); gFFI.serverModel.tabController.onSelected = (index) => gFFI.chatModel.changeCurrentID(gFFI.serverModel.clients[index].id); - // test - // gFFI.serverModel.clients.forEach((client) { - // DesktopTabBar.onAdd( - // gFFI.serverModel.tabs, - // TabInfo( - // key: client.id.toString(), label: client.name, closable: false)); - // }); super.initState(); } diff --git a/flutter/lib/desktop/widgets/peercard_widget.dart b/flutter/lib/desktop/widgets/peercard_widget.dart index a809adf9c..d9a87cd7b 100644 --- a/flutter/lib/desktop/widgets/peercard_widget.dart +++ b/flutter/lib/desktop/widgets/peercard_widget.dart @@ -99,7 +99,7 @@ class _PeerCardState extends State<_PeerCard> color: str2color('${peer.id}${peer.platform}', 0x7f), ), alignment: Alignment.center, - child: _getPlatformImage('${peer.platform}', 30).paddingAll(6), + child: getPlatformImage(peer.platform, size: 30).paddingAll(6), ), Expanded( child: Container( @@ -196,7 +196,8 @@ class _PeerCardState extends State<_PeerCard> children: [ Container( padding: const EdgeInsets.all(6), - child: _getPlatformImage(peer.platform, 60), + child: + getPlatformImage(peer.platform, size: 60), ), Row( children: [ @@ -287,17 +288,6 @@ class _PeerCardState extends State<_PeerCard> ); } - /// Get the image for the current [platform]. - Widget _getPlatformImage(String platform, double size) { - platform = platform.toLowerCase(); - if (platform == 'mac os') { - platform = 'mac'; - } else if (platform != 'linux' && platform != 'android') { - platform = 'win'; - } - return Image.asset('assets/$platform.png', height: size, width: size); - } - @override bool get wantKeepAlive => true; } diff --git a/flutter/lib/mobile/pages/connection_page.dart b/flutter/lib/mobile/pages/connection_page.dart index 7549bbae7..e6eddd087 100644 --- a/flutter/lib/mobile/pages/connection_page.dart +++ b/flutter/lib/mobile/pages/connection_page.dart @@ -215,15 +215,6 @@ class _ConnectionPageState extends State { super.dispose(); } - /// Get the image for the current [platform]. - Widget getPlatformImage(String platform) { - platform = platform.toLowerCase(); - if (platform == 'mac os') - platform = 'mac'; - else if (platform != 'linux' && platform != 'android') platform = 'win'; - return Image.asset('assets/$platform.png', width: 24, height: 24); - } - /// Get all the saved peers. Widget getPeers() { final windowWidth = MediaQuery.of(context).size.width; diff --git a/flutter/lib/mobile/pages/remote_page.dart b/flutter/lib/mobile/pages/remote_page.dart index a9a03c04d..d9943a62d 100644 --- a/flutter/lib/mobile/pages/remote_page.dart +++ b/flutter/lib/mobile/pages/remote_page.dart @@ -10,6 +10,7 @@ import 'package:provider/provider.dart'; import 'package:wakelock/wakelock.dart'; import '../../common.dart'; +import '../../consts.dart'; import '../../models/model.dart'; import '../../models/platform_model.dart'; import '../widgets/dialog.dart'; @@ -211,8 +212,8 @@ class _RemotePageState extends State { void sendRawKey(RawKeyEvent e, {bool? down, bool? press}) { // for maximum compatibility - final label = _logicalKeyMap[e.logicalKey.keyId] ?? - _physicalKeyMap[e.physicalKey.usbHidUsage] ?? + final label = logicalKeyMap[e.logicalKey.keyId] ?? + physicalKeyMap[e.physicalKey.usbHidUsage] ?? e.logicalKey.keyLabel; gFFI.inputKey(label, down: down, press: press ?? false); } @@ -1170,233 +1171,3 @@ void sendPrompt(bool isMac, String key) { gFFI.ctrl = old; } } - -/// flutter/packages/flutter/lib/src/services/keyboard_key.dart -> _keyLabels -/// see [LogicalKeyboardKey.keyLabel] -const Map _logicalKeyMap = { - 0x00000000020: 'VK_SPACE', - 0x00000000022: 'VK_QUOTE', - 0x0000000002c: 'VK_COMMA', - 0x0000000002d: 'VK_MINUS', - 0x0000000002f: 'VK_SLASH', - 0x00000000030: 'VK_0', - 0x00000000031: 'VK_1', - 0x00000000032: 'VK_2', - 0x00000000033: 'VK_3', - 0x00000000034: 'VK_4', - 0x00000000035: 'VK_5', - 0x00000000036: 'VK_6', - 0x00000000037: 'VK_7', - 0x00000000038: 'VK_8', - 0x00000000039: 'VK_9', - 0x0000000003b: 'VK_SEMICOLON', - 0x0000000003d: 'VK_PLUS', // it is = - 0x0000000005b: 'VK_LBRACKET', - 0x0000000005c: 'VK_BACKSLASH', - 0x0000000005d: 'VK_RBRACKET', - 0x00000000061: 'VK_A', - 0x00000000062: 'VK_B', - 0x00000000063: 'VK_C', - 0x00000000064: 'VK_D', - 0x00000000065: 'VK_E', - 0x00000000066: 'VK_F', - 0x00000000067: 'VK_G', - 0x00000000068: 'VK_H', - 0x00000000069: 'VK_I', - 0x0000000006a: 'VK_J', - 0x0000000006b: 'VK_K', - 0x0000000006c: 'VK_L', - 0x0000000006d: 'VK_M', - 0x0000000006e: 'VK_N', - 0x0000000006f: 'VK_O', - 0x00000000070: 'VK_P', - 0x00000000071: 'VK_Q', - 0x00000000072: 'VK_R', - 0x00000000073: 'VK_S', - 0x00000000074: 'VK_T', - 0x00000000075: 'VK_U', - 0x00000000076: 'VK_V', - 0x00000000077: 'VK_W', - 0x00000000078: 'VK_X', - 0x00000000079: 'VK_Y', - 0x0000000007a: 'VK_Z', - 0x00100000008: 'VK_BACK', - 0x00100000009: 'VK_TAB', - 0x0010000000d: 'VK_ENTER', - 0x0010000001b: 'VK_ESCAPE', - 0x0010000007f: 'VK_DELETE', - 0x00100000104: 'VK_CAPITAL', - 0x00100000301: 'VK_DOWN', - 0x00100000302: 'VK_LEFT', - 0x00100000303: 'VK_RIGHT', - 0x00100000304: 'VK_UP', - 0x00100000305: 'VK_END', - 0x00100000306: 'VK_HOME', - 0x00100000307: 'VK_NEXT', - 0x00100000308: 'VK_PRIOR', - 0x00100000401: 'VK_CLEAR', - 0x00100000407: 'VK_INSERT', - 0x00100000504: 'VK_CANCEL', - 0x00100000506: 'VK_EXECUTE', - 0x00100000508: 'VK_HELP', - 0x00100000509: 'VK_PAUSE', - 0x0010000050c: 'VK_SELECT', - 0x00100000608: 'VK_PRINT', - 0x00100000705: 'VK_CONVERT', - 0x00100000706: 'VK_FINAL', - 0x00100000711: 'VK_HANGUL', - 0x00100000712: 'VK_HANJA', - 0x00100000713: 'VK_JUNJA', - 0x00100000718: 'VK_KANA', - 0x00100000719: 'VK_KANJI', - 0x00100000801: 'VK_F1', - 0x00100000802: 'VK_F2', - 0x00100000803: 'VK_F3', - 0x00100000804: 'VK_F4', - 0x00100000805: 'VK_F5', - 0x00100000806: 'VK_F6', - 0x00100000807: 'VK_F7', - 0x00100000808: 'VK_F8', - 0x00100000809: 'VK_F9', - 0x0010000080a: 'VK_F10', - 0x0010000080b: 'VK_F11', - 0x0010000080c: 'VK_F12', - 0x00100000d2b: 'Apps', - 0x00200000002: 'VK_SLEEP', - 0x00200000100: 'VK_CONTROL', - 0x00200000101: 'RControl', - 0x00200000102: 'VK_SHIFT', - 0x00200000103: 'RShift', - 0x00200000104: 'VK_MENU', - 0x00200000105: 'RAlt', - 0x002000001f0: 'VK_CONTROL', - 0x002000001f2: 'VK_SHIFT', - 0x002000001f4: 'VK_MENU', - 0x002000001f6: 'Meta', - 0x0020000022a: 'VK_MULTIPLY', - 0x0020000022b: 'VK_ADD', - 0x0020000022d: 'VK_SUBTRACT', - 0x0020000022e: 'VK_DECIMAL', - 0x0020000022f: 'VK_DIVIDE', - 0x00200000230: 'VK_NUMPAD0', - 0x00200000231: 'VK_NUMPAD1', - 0x00200000232: 'VK_NUMPAD2', - 0x00200000233: 'VK_NUMPAD3', - 0x00200000234: 'VK_NUMPAD4', - 0x00200000235: 'VK_NUMPAD5', - 0x00200000236: 'VK_NUMPAD6', - 0x00200000237: 'VK_NUMPAD7', - 0x00200000238: 'VK_NUMPAD8', - 0x00200000239: 'VK_NUMPAD9', -}; - -/// flutter/packages/flutter/lib/src/services/keyboard_key.dart -> _debugName -/// see [PhysicalKeyboardKey.debugName] -> _debugName -const Map _physicalKeyMap = { - 0x00010082: 'VK_SLEEP', - 0x00070004: 'VK_A', - 0x00070005: 'VK_B', - 0x00070006: 'VK_C', - 0x00070007: 'VK_D', - 0x00070008: 'VK_E', - 0x00070009: 'VK_F', - 0x0007000a: 'VK_G', - 0x0007000b: 'VK_H', - 0x0007000c: 'VK_I', - 0x0007000d: 'VK_J', - 0x0007000e: 'VK_K', - 0x0007000f: 'VK_L', - 0x00070010: 'VK_M', - 0x00070011: 'VK_N', - 0x00070012: 'VK_O', - 0x00070013: 'VK_P', - 0x00070014: 'VK_Q', - 0x00070015: 'VK_R', - 0x00070016: 'VK_S', - 0x00070017: 'VK_T', - 0x00070018: 'VK_U', - 0x00070019: 'VK_V', - 0x0007001a: 'VK_W', - 0x0007001b: 'VK_X', - 0x0007001c: 'VK_Y', - 0x0007001d: 'VK_Z', - 0x0007001e: 'VK_1', - 0x0007001f: 'VK_2', - 0x00070020: 'VK_3', - 0x00070021: 'VK_4', - 0x00070022: 'VK_5', - 0x00070023: 'VK_6', - 0x00070024: 'VK_7', - 0x00070025: 'VK_8', - 0x00070026: 'VK_9', - 0x00070027: 'VK_0', - 0x00070028: 'VK_ENTER', - 0x00070029: 'VK_ESCAPE', - 0x0007002a: 'VK_BACK', - 0x0007002b: 'VK_TAB', - 0x0007002c: 'VK_SPACE', - 0x0007002d: 'VK_MINUS', - 0x0007002e: 'VK_PLUS', // it is = - 0x0007002f: 'VK_LBRACKET', - 0x00070030: 'VK_RBRACKET', - 0x00070033: 'VK_SEMICOLON', - 0x00070034: 'VK_QUOTE', - 0x00070036: 'VK_COMMA', - 0x00070038: 'VK_SLASH', - 0x00070039: 'VK_CAPITAL', - 0x0007003a: 'VK_F1', - 0x0007003b: 'VK_F2', - 0x0007003c: 'VK_F3', - 0x0007003d: 'VK_F4', - 0x0007003e: 'VK_F5', - 0x0007003f: 'VK_F6', - 0x00070040: 'VK_F7', - 0x00070041: 'VK_F8', - 0x00070042: 'VK_F9', - 0x00070043: 'VK_F10', - 0x00070044: 'VK_F11', - 0x00070045: 'VK_F12', - 0x00070049: 'VK_INSERT', - 0x0007004a: 'VK_HOME', - 0x0007004b: 'VK_PRIOR', // Page Up - 0x0007004c: 'VK_DELETE', - 0x0007004d: 'VK_END', - 0x0007004e: 'VK_NEXT', // Page Down - 0x0007004f: 'VK_RIGHT', - 0x00070050: 'VK_LEFT', - 0x00070051: 'VK_DOWN', - 0x00070052: 'VK_UP', - 0x00070053: 'Num Lock', // TODO rust not impl - 0x00070054: 'VK_DIVIDE', // numpad - 0x00070055: 'VK_MULTIPLY', - 0x00070056: 'VK_SUBTRACT', - 0x00070057: 'VK_ADD', - 0x00070058: 'VK_ENTER', // num enter - 0x00070059: 'VK_NUMPAD0', - 0x0007005a: 'VK_NUMPAD1', - 0x0007005b: 'VK_NUMPAD2', - 0x0007005c: 'VK_NUMPAD3', - 0x0007005d: 'VK_NUMPAD4', - 0x0007005e: 'VK_NUMPAD5', - 0x0007005f: 'VK_NUMPAD6', - 0x00070060: 'VK_NUMPAD7', - 0x00070061: 'VK_NUMPAD8', - 0x00070062: 'VK_NUMPAD9', - 0x00070063: 'VK_DECIMAL', - 0x00070075: 'VK_HELP', - 0x00070077: 'VK_SELECT', - 0x00070088: 'VK_KANA', - 0x0007008a: 'VK_CONVERT', - 0x000700e0: 'VK_CONTROL', - 0x000700e1: 'VK_SHIFT', - 0x000700e2: 'VK_MENU', - 0x000700e3: 'Meta', - 0x000700e4: 'RControl', - 0x000700e5: 'RShift', - 0x000700e6: 'RAlt', - 0x000700e7: 'RWin', - 0x000c00b1: 'VK_PAUSE', - 0x000c00cd: 'VK_PAUSE', - 0x000c019e: 'LOCK_SCREEN', - 0x000c0208: 'VK_PRINT', -}; From e9d94fdb245a56e88a53208feab844e7e7c70f18 Mon Sep 17 00:00:00 2001 From: csf Date: Tue, 13 Sep 2022 21:38:47 +0800 Subject: [PATCH 4/7] mv lib/cm_main.dart to test/cm_test.dart --- flutter/{lib/cm_main.dart => test/cm_test.dart} | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) rename flutter/{lib/cm_main.dart => test/cm_test.dart} (79%) diff --git a/flutter/lib/cm_main.dart b/flutter/test/cm_test.dart similarity index 79% rename from flutter/lib/cm_main.dart rename to flutter/test/cm_test.dart index 422e7aa26..704124781 100644 --- a/flutter/lib/cm_main.dart +++ b/flutter/test/cm_test.dart @@ -1,18 +1,17 @@ import 'package:flutter/material.dart'; +import 'package:flutter_hbb/common.dart'; import 'package:flutter_hbb/consts.dart'; +import 'package:flutter_hbb/desktop/pages/server_page.dart'; import 'package:flutter_hbb/main.dart'; +import 'package:flutter_hbb/models/server_model.dart'; import 'package:get/get.dart'; import 'package:window_manager/window_manager.dart'; -import 'common.dart'; -import 'desktop/pages/server_page.dart'; -import 'models/server_model.dart'; - /// -t lib/cm_main.dart to test cm void main(List args) async { WidgetsFlutterBinding.ensureInitialized(); await windowManager.ensureInitialized(); - await windowManager.setSize(Size(400, 600)); + await windowManager.setSize(const Size(400, 600)); await windowManager.setAlignment(Alignment.topRight); await initEnv(kAppTypeMain); gFFI.serverModel.clients @@ -23,6 +22,6 @@ void main(List args) async { .add(Client(2, false, false, "UserC", "331123123", true, false, false)); gFFI.serverModel.clients .add(Client(3, false, false, "UserD", "441123123", true, false, false)); - runApp(GetMaterialApp( + runApp(const GetMaterialApp( debugShowCheckedModeBanner: false, home: DesktopServerPage())); } From 2e2bf3b8fbe35017eb7d028134fbde6cc21f7bf0 Mon Sep 17 00:00:00 2001 From: csf Date: Tue, 13 Sep 2022 21:52:22 +0800 Subject: [PATCH 5/7] optimize model.dart --- flutter/lib/models/model.dart | 49 ++++++----------------------------- 1 file changed, 8 insertions(+), 41 deletions(-) diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index c6f38534a..b9225414d 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -331,7 +331,7 @@ class ImageModel with ChangeNotifier { ui.Image? get image => _image; - String _id = ''; + String id = ''; WeakReference parent; @@ -375,7 +375,7 @@ class ImageModel with ChangeNotifier { await initializeCursorAndCanvas(parent.target!); } if (parent.target?.ffiModel.isPeerAndroid ?? false) { - bind.sessionPeerOption(id: _id, name: 'view-style', value: 'adaptive'); + bind.sessionPeerOption(id: id, name: 'view-style', value: 'adaptive'); parent.target?.canvasModel.updateViewStyle(); } } @@ -468,7 +468,7 @@ class CanvasModel with ChangeNotifier { double _scale = 1.0; // the tabbar over the image double tabBarHeight = 0.0; - // TODO multi canvas model + // remote id String id = ''; // scroll offset x percent double _scrollX = 0.0; @@ -681,7 +681,7 @@ class CursorModel with ChangeNotifier { double _hoty = 0; double _displayOriginX = 0; double _displayOriginY = 0; - String id = ''; // TODO multi cursor model + String id = ''; WeakReference parent; ui.Image? get image => _image; @@ -991,7 +991,7 @@ extension ToString on MouseButtons { enum ConnType { defaultConn, fileTransfer, portForward, rdp } -/// FFI class for communicating with the Rust core. +/// Flutter state manager and data communication with the Rust core. class FFI { var id = ''; var shift = false; @@ -1020,7 +1020,7 @@ class FFI { ffiModel = FfiModel(WeakReference(this)); cursorModel = CursorModel(WeakReference(this)); canvasModel = CanvasModel(WeakReference(this)); - serverModel = ServerModel(WeakReference(this)); // use global FFI + serverModel = ServerModel(WeakReference(this)); chatModel = ChatModel(WeakReference(this)); fileModel = FileModel(WeakReference(this)); abModel = AbModel(WeakReference(this)); @@ -1042,12 +1042,6 @@ class FFI { .encode(modify({'id': id, 'type': 'wheel', 'y': y.toString()}))); } - /// Reconnect to the remote peer. - // static reconnect() { - // setByName('reconnect'); - // parent.target?.ffiModel.clearPermissions(); - // } - /// Reset key modifiers to false, including [shift], [ctrl], [alt] and [command]. resetModifiers() { shift = ctrl = alt = command = false; @@ -1070,7 +1064,7 @@ class FFI { msg: json.encode(modify({'type': type, 'buttons': button.value}))); } - // Raw Key + /// Send raw Key Event inputRawKey(String name, int keyCode, int scanCode, bool down) { bind.sessionHandleFlutterKeyEvent( id: id, @@ -1080,10 +1074,6 @@ class FFI { downOrUp: down); } - Future getKeyboardMode() { - return bind.sessionGetKeyboardName(id: id); - } - enterOrLeave(bool enter) { // Fix status if (!enter) { @@ -1097,18 +1087,6 @@ class FFI { /// [press] indicates a click event(down and up). inputKey(String name, {bool? down, bool? press}) { if (!ffiModel.keyboard()) return; - // final Map out = Map(); - // out['name'] = name; - // // default: down = false - // if (down == true) { - // out['down'] = 'true'; - // } - // // default: press = true - // if (press != false) { - // out['press'] = 'true'; - // } - // setByName('input_key', json.encode(modify(out))); - // TODO id bind.sessionInputKey( id: id, name: name, @@ -1161,7 +1139,7 @@ class FFI { } else { chatModel.resetClientMode(); canvasModel.id = id; - imageModel._id = id; + imageModel.id = id; cursorModel.id = id; } // ignore: unused_local_variable @@ -1212,17 +1190,6 @@ class FFI { debugPrint('model $id closed'); } - /// Send **get** command to the Rust core based on [name] and [arg]. - /// Return the result as a string. - // String getByName(String name, [String arg = '']) { - // return platformFFI.getByName(name, arg); - // } - - /// Send **set** command to the Rust core based on [name] and [value]. - // setByName(String name, [String value = '']) { - // platformFFI.setByName(name, value); - // } - handleMouse(Map evt, {double tabBarHeight = 0.0}) { var type = ''; var isMove = false; From 583ccb4b667f272b9085321b5cc9c580d2d07df1 Mon Sep 17 00:00:00 2001 From: csf Date: Tue, 13 Sep 2022 22:37:16 +0800 Subject: [PATCH 6/7] del finished TODOs --- src/flutter.rs | 2 +- src/flutter_ffi.rs | 4 ---- src/ui/remote.rs | 1 - src/ui_interface.rs | 7 +------ src/ui_session_interface.rs | 6 +----- 5 files changed, 3 insertions(+), 17 deletions(-) diff --git a/src/flutter.rs b/src/flutter.rs index 81b455b04..566576b5d 100644 --- a/src/flutter.rs +++ b/src/flutter.rs @@ -365,7 +365,7 @@ pub mod connection_manager { log::debug!("call_service_set_by_name fail,{}", e); } // send to UI, refresh widget - self.push_event("add_connection", vec![("client", &client_json)]); // TODO use add_connection + self.push_event("add_connection", vec![("client", &client_json)]); } fn remove_connection(&self, id: i32) { diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index f3c7b3735..568096b1c 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -575,7 +575,6 @@ pub fn main_forget_password(id: String) { forget_password(id) } -// TODO APP_DIR & ui_interface pub fn main_get_recent_peers() -> String { if !config::APP_DIR.read().unwrap().is_empty() { let peers: Vec<(String, config::PeerInfoSerde)> = PeerConfig::peers() @@ -709,9 +708,6 @@ pub fn session_new_rdp(id: String) { } pub fn main_get_last_remote_id() -> String { - // if !config::APP_DIR.read().unwrap().is_empty() { - // res = LocalConfig::get_remote_id(); - // } LocalConfig::get_remote_id() } diff --git a/src/ui/remote.rs b/src/ui/remote.rs index 9cf04b69a..76e1ee96c 100644 --- a/src/ui/remote.rs +++ b/src/ui/remote.rs @@ -411,7 +411,6 @@ impl sciter::EventHandler for SciterSession { impl SciterSession { pub fn new(cmd: String, id: String, password: String, args: Vec) -> Self { let session: Session = Session { - cmd: cmd.clone(), id: id.clone(), password: password.clone(), args, diff --git a/src/ui_interface.rs b/src/ui_interface.rs index 0b95cd588..133dd24b0 100644 --- a/src/ui_interface.rs +++ b/src/ui_interface.rs @@ -139,10 +139,6 @@ pub fn get_license() -> String { pub fn get_option(key: String) -> String { get_option_(&key) - // #[cfg(any(target_os = "android", target_os = "ios"))] - // return Config::get_option(&key); - // #[cfg(not(any(target_os = "android", target_os = "ios")))] - // return get_option_(&key); } fn get_option_(key: &str) -> String { @@ -208,7 +204,6 @@ pub fn get_sound_inputs() -> Vec { let mut a = Vec::new(); #[cfg(not(target_os = "linux"))] { - // TODO TEST fn get_sound_inputs_() -> Vec { let mut out = Vec::new(); use cpal::traits::{DeviceTrait, HostTrait}; @@ -236,7 +231,7 @@ pub fn get_sound_inputs() -> Vec { a.push(name); } } - #[cfg(target_os = "linux")] // TODO + #[cfg(target_os = "linux")] { let inputs: Vec = crate::platform::linux::get_pa_sources() .drain(..) diff --git a/src/ui_session_interface.rs b/src/ui_session_interface.rs index 7af3a2fbd..945c45385 100644 --- a/src/ui_session_interface.rs +++ b/src/ui_session_interface.rs @@ -35,7 +35,6 @@ lazy_static::lazy_static! { #[derive(Clone, Default)] pub struct Session { - pub cmd: String, pub id: String, pub password: String, pub args: Vec, @@ -53,7 +52,7 @@ impl Session { pub fn get_image_quality(&self) -> String { self.lc.read().unwrap().image_quality.clone() } - /// Get custom image quality. + pub fn get_custom_image_quality(&self) -> Vec { self.lc.read().unwrap().custom_image_quality.clone() } @@ -1115,7 +1114,6 @@ impl Interface for Session { crate::platform::windows::add_recent_document(&path); } } - // TODO use event callbcak #[cfg(not(any(target_os = "android", target_os = "ios")))] self.start_keyboard_hook(); } @@ -1158,8 +1156,6 @@ impl Interface for Session { } } -// TODO use event callbcak -// sciter only #[cfg(not(any(target_os = "android", target_os = "ios")))] impl Session { fn start_keyboard_hook(&self) { From d92bbc045ab76e74b9c52dbaa4e5b7c05f236379 Mon Sep 17 00:00:00 2001 From: csf Date: Tue, 13 Sep 2022 22:48:14 +0800 Subject: [PATCH 7/7] add main ui interface #[inline] --- src/ui_interface.rs | 78 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/src/ui_interface.rs b/src/ui_interface.rs index 133dd24b0..af7e8ba05 100644 --- a/src/ui_interface.rs +++ b/src/ui_interface.rs @@ -40,6 +40,7 @@ lazy_static::lazy_static! { pub static ref SENDER : Mutex> = Mutex::new(check_connect_status(true)); } +#[inline] pub fn recent_sessions_updated() -> bool { let mut childs = CHILDS.lock().unwrap(); if childs.0 { @@ -50,6 +51,7 @@ pub fn recent_sessions_updated() -> bool { } } +#[inline] pub fn get_id() -> String { #[cfg(any(target_os = "android", target_os = "ios"))] return Config::get_id(); @@ -57,18 +59,22 @@ pub fn get_id() -> String { return ipc::get_id(); } +#[inline] pub fn get_remote_id() -> String { LocalConfig::get_remote_id() } +#[inline] pub fn set_remote_id(id: String) { LocalConfig::set_remote_id(&id); } +#[inline] pub fn goto_install() { allow_err!(crate::run_me(vec!["--install"])); } +#[inline] pub fn install_me(_options: String, _path: String, silent: bool, debug: bool) { #[cfg(windows)] std::thread::spawn(move || { @@ -79,6 +85,7 @@ pub fn install_me(_options: String, _path: String, silent: bool, debug: bool) { }); } +#[inline] pub fn update_me(_path: String) { #[cfg(target_os = "linux")] { @@ -105,11 +112,13 @@ pub fn update_me(_path: String) { } } +#[inline] pub fn run_without_install() { crate::run_me(vec!["--noinstall"]).ok(); std::process::exit(0); } +#[inline] pub fn show_run_without_install() -> bool { let mut it = std::env::args(); if let Some(tmp) = it.next() { @@ -120,12 +129,14 @@ pub fn show_run_without_install() -> bool { false } +#[inline] pub fn has_rendezvous_service() -> bool { #[cfg(all(windows, feature = "hbbs"))] return crate::platform::is_win_server() && crate::platform::windows::get_license().is_some(); return false; } +#[inline] pub fn get_license() -> String { #[cfg(windows)] if let Some(lic) = crate::platform::windows::get_license() { @@ -137,10 +148,12 @@ pub fn get_license() -> String { Default::default() } +#[inline] pub fn get_option(key: String) -> String { get_option_(&key) } +#[inline] fn get_option_(key: &str) -> String { let map = OPTIONS.lock().unwrap(); if let Some(v) = map.get(key) { @@ -150,29 +163,35 @@ fn get_option_(key: &str) -> String { } } +#[inline] pub fn get_local_option(key: String) -> String { LocalConfig::get_option(&key) } +#[inline] pub fn set_local_option(key: String, value: String) { LocalConfig::set_option(key, value); } +#[inline] pub fn peer_has_password(id: String) -> bool { !PeerConfig::load(&id).password.is_empty() } +#[inline] pub fn forget_password(id: String) { let mut c = PeerConfig::load(&id); c.password.clear(); c.store(&id); } +#[inline] pub fn get_peer_option(id: String, name: String) -> String { let c = PeerConfig::load(&id); c.options.get(&name).unwrap_or(&"".to_owned()).to_owned() } +#[inline] pub fn set_peer_option(id: String, name: String, value: String) { let mut c = PeerConfig::load(&id); if value.is_empty() { @@ -183,10 +202,12 @@ pub fn set_peer_option(id: String, name: String, value: String) { c.store(&id); } +#[inline] pub fn using_public_server() -> bool { crate::get_custom_rendezvous_server(get_option_("custom-rendezvous-server")).is_empty() } +#[inline] pub fn get_options() -> String { let options = OPTIONS.lock().unwrap(); let mut m = serde_json::Map::new(); @@ -196,10 +217,12 @@ pub fn get_options() -> String { serde_json::to_string(&m).unwrap() } +#[inline] pub fn test_if_valid_server(host: String) -> String { hbb_common::socket_client::test_if_valid_server(&host) } +#[inline] pub fn get_sound_inputs() -> Vec { let mut a = Vec::new(); #[cfg(not(target_os = "linux"))] @@ -245,6 +268,7 @@ pub fn get_sound_inputs() -> Vec { a } +#[inline] pub fn set_options(m: HashMap) { *OPTIONS.lock().unwrap() = m.clone(); #[cfg(not(any(target_os = "android", target_os = "ios")))] @@ -253,6 +277,7 @@ pub fn set_options(m: HashMap) { Config::set_options(m); } +#[inline] pub fn set_option(key: String, value: String) { let mut options = OPTIONS.lock().unwrap(); #[cfg(target_os = "macos")] @@ -273,6 +298,7 @@ pub fn set_option(key: String, value: String) { Config::set_option(key, value); } +#[inline] pub fn install_path() -> String { #[cfg(windows)] return crate::platform::windows::get_install_info().1; @@ -280,6 +306,7 @@ pub fn install_path() -> String { return "".to_owned(); } +#[inline] pub fn get_socks() -> Vec { #[cfg(any(target_os = "android", target_os = "ios"))] return Vec::new(); @@ -299,6 +326,7 @@ pub fn get_socks() -> Vec { } } +#[inline] pub fn set_socks(proxy: String, username: String, password: String) { #[cfg(not(any(target_os = "android", target_os = "ios")))] ipc::set_socks(config::Socks5Server { @@ -310,10 +338,12 @@ pub fn set_socks(proxy: String, username: String, password: String) { } #[cfg(not(any(target_os = "android", target_os = "ios")))] +#[inline] pub fn is_installed() -> bool { crate::platform::is_installed() } +#[inline] pub fn is_rdp_service_open() -> bool { #[cfg(windows)] return is_installed() && crate::platform::windows::is_rdp_service_open(); @@ -321,6 +351,7 @@ pub fn is_rdp_service_open() -> bool { return false; } +#[inline] pub fn is_share_rdp() -> bool { #[cfg(windows)] return crate::platform::windows::is_share_rdp(); @@ -328,11 +359,13 @@ pub fn is_share_rdp() -> bool { return false; } +#[inline] pub fn set_share_rdp(_enable: bool) { #[cfg(windows)] crate::platform::windows::set_share_rdp(_enable); } +#[inline] pub fn is_installed_lower_version() -> bool { #[cfg(not(windows))] return false; @@ -345,12 +378,14 @@ pub fn is_installed_lower_version() -> bool { } } +#[inline] pub fn closing(x: i32, y: i32, w: i32, h: i32) { #[cfg(not(any(target_os = "android", target_os = "ios")))] crate::server::input_service::fix_key_down_timeout_at_exit(); LocalConfig::set_size(x, y, w, h); } +#[inline] pub fn get_size() -> Vec { let s = LocalConfig::get_size(); let mut v = Vec::new(); @@ -361,12 +396,14 @@ pub fn get_size() -> Vec { v } +#[inline] pub fn get_mouse_time() -> f64 { let ui_status = UI_STATUS.lock().unwrap(); let res = ui_status.2 as f64; return res; } +#[inline] pub fn check_mouse_time() { #[cfg(not(any(target_os = "android", target_os = "ios")))] { @@ -375,12 +412,14 @@ pub fn check_mouse_time() { } } +#[inline] pub fn get_connect_status() -> Status { let ui_statue = UI_STATUS.lock().unwrap(); let res = ui_statue.clone(); res } +#[inline] pub fn temporary_password() -> String { #[cfg(any(target_os = "android", target_os = "ios"))] return password_security::temporary_password(); @@ -388,6 +427,7 @@ pub fn temporary_password() -> String { return TEMPORARY_PASSWD.lock().unwrap().clone(); } +#[inline] pub fn update_temporary_password() { #[cfg(any(target_os = "android", target_os = "ios"))] password_security::update_temporary_password(); @@ -395,6 +435,7 @@ pub fn update_temporary_password() { allow_err!(ipc::update_temporary_password()); } +#[inline] pub fn permanent_password() -> String { #[cfg(any(target_os = "android", target_os = "ios"))] return Config::get_permanent_password(); @@ -402,6 +443,7 @@ pub fn permanent_password() -> String { return ipc::get_permanent_password(); } +#[inline] pub fn set_permanent_password(password: String) { #[cfg(any(target_os = "android", target_os = "ios"))] Config::set_permanent_password(&password); @@ -409,31 +451,38 @@ pub fn set_permanent_password(password: String) { allow_err!(ipc::set_permanent_password(password)); } +#[inline] pub fn get_peer(id: String) -> PeerConfig { PeerConfig::load(&id) } +#[inline] pub fn get_fav() -> Vec { LocalConfig::get_fav() } +#[inline] pub fn store_fav(fav: Vec) { LocalConfig::set_fav(fav); } +#[inline] pub fn get_recent_sessions() -> Vec<(String, SystemTime, PeerConfig)> { PeerConfig::peers() } +#[inline] #[cfg(not(any(target_os = "android", target_os = "ios", feature = "cli")))] pub fn get_icon() -> String { crate::get_icon() } +#[inline] pub fn remove_peer(id: String) { PeerConfig::remove(&id); } +#[inline] pub fn new_remote(id: String, remote_type: String) { let mut lock = CHILDS.lock().unwrap(); let args = vec![format!("--{}", remote_type), id.clone()]; @@ -462,6 +511,7 @@ pub fn new_remote(id: String, remote_type: String) { } } +#[inline] pub fn is_process_trusted(_prompt: bool) -> bool { #[cfg(target_os = "macos")] return crate::platform::macos::is_process_trusted(_prompt); @@ -469,6 +519,7 @@ pub fn is_process_trusted(_prompt: bool) -> bool { return true; } +#[inline] pub fn is_can_screen_recording(_prompt: bool) -> bool { #[cfg(target_os = "macos")] return crate::platform::macos::is_can_screen_recording(_prompt); @@ -476,6 +527,7 @@ pub fn is_can_screen_recording(_prompt: bool) -> bool { return true; } +#[inline] pub fn is_installed_daemon(_prompt: bool) -> bool { #[cfg(target_os = "macos")] return crate::platform::macos::is_installed_daemon(_prompt); @@ -483,6 +535,7 @@ pub fn is_installed_daemon(_prompt: bool) -> bool { return true; } +#[inline] pub fn get_error() -> String { #[cfg(not(any(feature = "cli")))] #[cfg(target_os = "linux")] @@ -503,6 +556,7 @@ pub fn get_error() -> String { return "".to_owned(); } +#[inline] pub fn is_login_wayland() -> bool { #[cfg(target_os = "linux")] return crate::platform::linux::is_login_wayland(); @@ -510,11 +564,13 @@ pub fn is_login_wayland() -> bool { return false; } +#[inline] pub fn fix_login_wayland() { #[cfg(target_os = "linux")] crate::platform::linux::fix_login_wayland(); } +#[inline] pub fn current_is_wayland() -> bool { #[cfg(target_os = "linux")] return crate::platform::linux::current_is_wayland(); @@ -522,6 +578,7 @@ pub fn current_is_wayland() -> bool { return false; } +#[inline] pub fn modify_default_login() -> String { #[cfg(target_os = "linux")] return crate::platform::linux::modify_default_login(); @@ -529,22 +586,27 @@ pub fn modify_default_login() -> String { return "".to_owned(); } +#[inline] pub fn get_software_update_url() -> String { SOFTWARE_UPDATE_URL.lock().unwrap().clone() } +#[inline] pub fn get_new_version() -> String { hbb_common::get_version_from_url(&*SOFTWARE_UPDATE_URL.lock().unwrap()) } +#[inline] pub fn get_version() -> String { crate::VERSION.to_owned() } +#[inline] pub fn get_app_name() -> String { crate::get_app_name() } +#[inline] #[cfg(not(any(target_os = "android", target_os = "ios")))] pub fn get_software_ext() -> String { #[cfg(windows)] @@ -556,6 +618,7 @@ pub fn get_software_ext() -> String { p.to_owned() } +#[inline] #[cfg(not(any(target_os = "android", target_os = "ios")))] pub fn get_software_store_path() -> String { let mut p = std::env::temp_dir(); @@ -570,17 +633,20 @@ pub fn get_software_store_path() -> String { format!("{}.{}", p.to_string_lossy(), get_software_ext()) } +#[inline] pub fn create_shortcut(_id: String) { #[cfg(windows)] crate::platform::windows::create_shortcut(&_id).ok(); } +#[inline] pub fn discover() { std::thread::spawn(move || { allow_err!(crate::lan::discover()); }); } +#[inline] pub fn get_lan_peers() -> Vec<(String, config::PeerInfoSerde)> { config::LanPeers::load() .peers @@ -598,10 +664,12 @@ pub fn get_lan_peers() -> Vec<(String, config::PeerInfoSerde)> { .collect() } +#[inline] pub fn get_uuid() -> String { base64::encode(hbb_common::get_uuid()) } +#[inline] #[cfg(not(any(target_os = "android", target_os = "ios", feature = "cli")))] pub fn open_url(url: String) { #[cfg(windows)] @@ -617,6 +685,7 @@ pub fn open_url(url: String) { allow_err!(std::process::Command::new(p).arg(url).spawn()); } +#[inline] #[cfg(not(any(target_os = "android", target_os = "ios")))] pub fn change_id(id: String) { *ASYNC_JOB_STATUS.lock().unwrap() = " ".to_owned(); @@ -626,6 +695,7 @@ pub fn change_id(id: String) { }); } +#[inline] pub fn post_request(url: String, body: String, header: String) { *ASYNC_JOB_STATUS.lock().unwrap() = " ".to_owned(); std::thread::spawn(move || { @@ -636,28 +706,34 @@ pub fn post_request(url: String, body: String, header: String) { }); } +#[inline] #[cfg(not(any(target_os = "android", target_os = "ios")))] pub fn is_ok_change_id() -> bool { machine_uid::get().is_ok() } +#[inline] pub fn get_async_job_status() -> String { ASYNC_JOB_STATUS.lock().unwrap().clone() } +#[inline] #[cfg(not(any(target_os = "android", target_os = "ios", feature = "cli")))] pub fn t(name: String) -> String { crate::client::translate(name) } +#[inline] pub fn get_langs() -> String { crate::lang::LANGS.to_string() } +#[inline] pub fn is_xfce() -> bool { crate::platform::is_xfce() } +#[inline] pub fn get_api_server() -> String { crate::get_api_server( get_option_("api-server"), @@ -665,6 +741,7 @@ pub fn get_api_server() -> String { ) } +#[inline] pub fn has_hwcodec() -> bool { #[cfg(not(feature = "hwcodec"))] return false; @@ -672,6 +749,7 @@ pub fn has_hwcodec() -> bool { return true; } +#[inline] pub fn check_super_user_permission() -> bool { #[cfg(any(windows, target_os = "linux"))] return crate::platform::check_super_user_permission().unwrap_or(false);