mirror of
https://github.com/weyne85/rustdesk.git
synced 2025-10-29 17:00:05 +00:00
commit
f4bc27f969
@ -898,3 +898,14 @@ Future<List<Peer>>? matchPeers(String searchText, List<Peer> peers) async {
|
|||||||
}
|
}
|
||||||
return filteredList;
|
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);
|
||||||
|
}
|
||||||
|
|||||||
@ -16,3 +16,233 @@ const int kDesktopDefaultDisplayWidth = 1080;
|
|||||||
const int kDesktopDefaultDisplayHeight = 720;
|
const int kDesktopDefaultDisplayHeight = 720;
|
||||||
|
|
||||||
const kInvalidValueStr = "InvalidValueStr";
|
const kInvalidValueStr = "InvalidValueStr";
|
||||||
|
|
||||||
|
/// flutter/packages/flutter/lib/src/services/keyboard_key.dart -> _keyLabels
|
||||||
|
/// see [LogicalKeyboardKey.keyLabel]
|
||||||
|
const Map<int, String> logicalKeyMap = <int, String>{
|
||||||
|
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<int, String> physicalKeyMap = <int, String>{
|
||||||
|
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',
|
||||||
|
};
|
||||||
|
|||||||
@ -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/desktop/widgets/peercard_widget.dart';
|
||||||
import 'package:flutter_hbb/utils/multi_window_manager.dart';
|
import 'package:flutter_hbb/utils/multi_window_manager.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:url_launcher/url_launcher_string.dart';
|
import 'package:url_launcher/url_launcher_string.dart';
|
||||||
|
|
||||||
import '../../common.dart';
|
import '../../common.dart';
|
||||||
import '../../common/formatter/id_formatter.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';
|
import '../../models/platform_model.dart';
|
||||||
|
|
||||||
// enum RemoteType { recently, favorite, discovered, addressBook }
|
|
||||||
|
|
||||||
/// Connection page for connecting to a remote peer.
|
/// Connection page for connecting to a remote peer.
|
||||||
class ConnectionPage extends StatefulWidget {
|
class ConnectionPage extends StatefulWidget {
|
||||||
const ConnectionPage({Key? key}) : super(key: key);
|
const ConnectionPage({Key? key}) : super(key: key);
|
||||||
@ -33,9 +27,6 @@ class _ConnectionPageState extends State<ConnectionPage> {
|
|||||||
/// Controller for the id input bar.
|
/// Controller for the id input bar.
|
||||||
final _idController = IDTextEditingController();
|
final _idController = IDTextEditingController();
|
||||||
|
|
||||||
/// Update url. If it's not null, means an update is available.
|
|
||||||
final _updateUrl = '';
|
|
||||||
|
|
||||||
Timer? _updateTimer;
|
Timer? _updateTimer;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -67,7 +58,6 @@ class _ConnectionPageState extends State<ConnectionPage> {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
getUpdateUI(),
|
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
getSearchBarUI(context),
|
getSearchBarUI(context),
|
||||||
@ -131,28 +121,6 @@ class _ConnectionPageState extends State<ConnectionPage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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.
|
/// UI for the search bar.
|
||||||
/// Search for a peer and connect to it if the id exists.
|
/// Search for a peer and connect to it if the id exists.
|
||||||
Widget getSearchBarUI(BuildContext context) {
|
Widget getSearchBarUI(BuildContext context) {
|
||||||
@ -328,86 +296,6 @@ class _ConnectionPageState extends State<ConnectionPage> {
|
|||||||
super.dispose();
|
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<dynamic> selectedTags, List<dynamic> 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<String>(
|
|
||||||
// child: Text(translate('Connect')), value: 'connect'),
|
|
||||||
// PopupMenuItem<String>(
|
|
||||||
// child: Text(translate('Transfer File')), value: 'file'),
|
|
||||||
// PopupMenuItem<String>(
|
|
||||||
// child: Text(translate('TCP Tunneling')), value: 'tcp-tunnel'),
|
|
||||||
// PopupMenuItem<String>(child: Text(translate('Rename')), value: 'rename'),
|
|
||||||
// rType == RemoteType.addressBook
|
|
||||||
// ? PopupMenuItem<String>(
|
|
||||||
// child: Text(translate('Remove')), value: 'ab-delete')
|
|
||||||
// : PopupMenuItem<String>(
|
|
||||||
// child: Text(translate('Remove')), value: 'remove'),
|
|
||||||
// PopupMenuItem<String>(
|
|
||||||
// child: Text(translate('Unremember Password')),
|
|
||||||
// value: 'unremember-password'),
|
|
||||||
// ];
|
|
||||||
// if (rType == RemoteType.favorite) {
|
|
||||||
// items.add(PopupMenuItem<String>(
|
|
||||||
// child: Text(translate('Remove from Favorites')),
|
|
||||||
// value: 'remove-fav'));
|
|
||||||
// } else if (rType != RemoteType.addressBook) {
|
|
||||||
// items.add(PopupMenuItem<String>(
|
|
||||||
// child: Text(translate('Add to Favorites')), value: 'add-fav'));
|
|
||||||
// } else {
|
|
||||||
// items.add(PopupMenuItem<String>(
|
|
||||||
// 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 svcStopped = false.obs;
|
||||||
var svcStatusCode = 0.obs;
|
var svcStatusCode = 0.obs;
|
||||||
var svcIsUsingPublicServer = true.obs;
|
var svcIsUsingPublicServer = true.obs;
|
||||||
@ -454,7 +342,7 @@ class _ConnectionPageState extends State<ConnectionPage> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
light,
|
light,
|
||||||
Text("${translate('Ready')}"),
|
Text(translate('Ready')),
|
||||||
svcIsUsingPublicServer.value
|
svcIsUsingPublicServer.value
|
||||||
? InkWell(
|
? InkWell(
|
||||||
onTap: onUsePublicServerGuide,
|
onTap: onUsePublicServerGuide,
|
||||||
@ -469,7 +357,7 @@ class _ConnectionPageState extends State<ConnectionPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void onUsePublicServerGuide() {
|
void onUsePublicServerGuide() {
|
||||||
final url = "https://rustdesk.com/blog/id-relay-set/";
|
const url = "https://rustdesk.com/blog/id-relay-set/";
|
||||||
canLaunchUrlString(url).then((can) {
|
canLaunchUrlString(url).then((can) {
|
||||||
if (can) {
|
if (can) {
|
||||||
launchUrlString(url);
|
launchUrlString(url);
|
||||||
@ -857,100 +745,6 @@ class _ConnectionPageState extends State<ConnectionPage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class WebMenu extends StatefulWidget {
|
|
||||||
@override
|
|
||||||
_WebMenuState createState() => _WebMenuState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _WebMenuState extends State<WebMenu> {
|
|
||||||
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<FfiModel>(context);
|
|
||||||
return PopupMenuButton<String>(
|
|
||||||
icon: Icon(Icons.more_vert),
|
|
||||||
itemBuilder: (context) {
|
|
||||||
return (isIOS
|
|
||||||
? [
|
|
||||||
PopupMenuItem(
|
|
||||||
child: Icon(Icons.qr_code_scanner, color: Colors.black),
|
|
||||||
value: "scan",
|
|
||||||
)
|
|
||||||
]
|
|
||||||
: <PopupMenuItem<String>>[]) +
|
|
||||||
[
|
|
||||||
PopupMenuItem(
|
|
||||||
child: Text(translate('ID/Relay Server')),
|
|
||||||
value: "server",
|
|
||||||
)
|
|
||||||
] +
|
|
||||||
(url.contains('admin.rustdesk.com')
|
|
||||||
? <PopupMenuItem<String>>[]
|
|
||||||
: [
|
|
||||||
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 {
|
class _PeerTabbedPage extends StatefulWidget {
|
||||||
final List<String> tabs;
|
final List<String> tabs;
|
||||||
final List<Widget> children;
|
final List<Widget> children;
|
||||||
|
|||||||
@ -67,7 +67,7 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
if (!Platform.isLinux) {
|
if (!Platform.isLinux) {
|
||||||
Wakelock.enable();
|
Wakelock.enable();
|
||||||
}
|
}
|
||||||
print("init success with id ${widget.id}");
|
debugPrint("File manager page init success with id ${widget.id}");
|
||||||
// register location listener
|
// register location listener
|
||||||
_locationNodeLocal.addListener(onLocalLocationFocusChanged);
|
_locationNodeLocal.addListener(onLocalLocationFocusChanged);
|
||||||
_locationNodeRemote.addListener(onRemoteLocationFocusChanged);
|
_locationNodeRemote.addListener(onRemoteLocationFocusChanged);
|
||||||
@ -307,109 +307,6 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
)
|
)
|
||||||
],
|
],
|
||||||
)),
|
)),
|
||||||
// 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<String>(
|
|
||||||
// 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<FileManagerPage>
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
@override
|
||||||
bool get wantKeepAlive => true;
|
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() {
|
void onLocalLocationFocusChanged() {
|
||||||
debugPrint("focus changed on local");
|
debugPrint("focus changed on local");
|
||||||
if (_locationNodeLocal.hasFocus) {
|
if (_locationNodeLocal.hasFocus) {
|
||||||
@ -861,7 +724,6 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
|
|
||||||
openDirectory(String path, {bool isLocal = false}) {
|
openDirectory(String path, {bool isLocal = false}) {
|
||||||
model.openDirectory(path, isLocal: isLocal).then((_) {
|
model.openDirectory(path, isLocal: isLocal).then((_) {
|
||||||
print("scroll");
|
|
||||||
breadCrumbScrollToEnd(isLocal);
|
breadCrumbScrollToEnd(isLocal);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -52,7 +52,7 @@ class _PortForwardPageState extends State<PortForwardPage>
|
|||||||
if (!Platform.isLinux) {
|
if (!Platform.isLinux) {
|
||||||
Wakelock.enable();
|
Wakelock.enable();
|
||||||
}
|
}
|
||||||
debugPrint("init success with id ${widget.id}");
|
debugPrint("Port forward page init success with id ${widget.id}");
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@ -10,8 +10,7 @@ import 'package:provider/provider.dart';
|
|||||||
import 'package:wakelock/wakelock.dart';
|
import 'package:wakelock/wakelock.dart';
|
||||||
import 'package:flutter_custom_cursor/flutter_custom_cursor.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 '../widgets/remote_menubar.dart';
|
||||||
import '../../common.dart';
|
import '../../common.dart';
|
||||||
import '../../mobile/widgets/dialog.dart';
|
import '../../mobile/widgets/dialog.dart';
|
||||||
@ -19,8 +18,6 @@ import '../../models/model.dart';
|
|||||||
import '../../models/platform_model.dart';
|
import '../../models/platform_model.dart';
|
||||||
import '../../common/shared_state.dart';
|
import '../../common/shared_state.dart';
|
||||||
|
|
||||||
final initText = '\1' * 1024;
|
|
||||||
|
|
||||||
class RemotePage extends StatefulWidget {
|
class RemotePage extends StatefulWidget {
|
||||||
const RemotePage({
|
const RemotePage({
|
||||||
Key? key,
|
Key? key,
|
||||||
@ -38,15 +35,13 @@ class RemotePage extends StatefulWidget {
|
|||||||
class _RemotePageState extends State<RemotePage>
|
class _RemotePageState extends State<RemotePage>
|
||||||
with AutomaticKeepAliveClientMixin {
|
with AutomaticKeepAliveClientMixin {
|
||||||
Timer? _timer;
|
Timer? _timer;
|
||||||
String _value = '';
|
|
||||||
String keyboardMode = "legacy";
|
String keyboardMode = "legacy";
|
||||||
final _cursorOverImage = false.obs;
|
final _cursorOverImage = false.obs;
|
||||||
late RxBool _showRemoteCursor;
|
late RxBool _showRemoteCursor;
|
||||||
late RxBool _remoteCursorMoved;
|
late RxBool _remoteCursorMoved;
|
||||||
late RxBool _keyboardEnabled;
|
late RxBool _keyboardEnabled;
|
||||||
|
|
||||||
final FocusNode _mobileFocusNode = FocusNode();
|
final FocusNode _rawKeyFocusNode = FocusNode();
|
||||||
final FocusNode _physicalFocusNode = FocusNode();
|
|
||||||
var _isPhysicalMouse = false;
|
var _isPhysicalMouse = false;
|
||||||
var _imageFocused = false;
|
var _imageFocused = false;
|
||||||
|
|
||||||
@ -95,11 +90,9 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
if (!Platform.isLinux) {
|
if (!Platform.isLinux) {
|
||||||
Wakelock.enable();
|
Wakelock.enable();
|
||||||
}
|
}
|
||||||
_physicalFocusNode.requestFocus();
|
_rawKeyFocusNode.requestFocus();
|
||||||
_ffi.ffiModel.updateEventListener(widget.id);
|
_ffi.ffiModel.updateEventListener(widget.id);
|
||||||
_ffi.listenToMouse(true);
|
|
||||||
_ffi.qualityMonitorModel.checkShowQualityMonitor(widget.id);
|
_ffi.qualityMonitorModel.checkShowQualityMonitor(widget.id);
|
||||||
// WindowManager.instance.addListener(this);
|
|
||||||
_showRemoteCursor.value = bind.sessionGetToggleOptionSync(
|
_showRemoteCursor.value = bind.sessionGetToggleOptionSync(
|
||||||
id: widget.id, arg: 'show-remote-cursor');
|
id: widget.id, arg: 'show-remote-cursor');
|
||||||
}
|
}
|
||||||
@ -108,9 +101,7 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
void dispose() {
|
void dispose() {
|
||||||
debugPrint("REMOTE PAGE dispose ${widget.id}");
|
debugPrint("REMOTE PAGE dispose ${widget.id}");
|
||||||
_ffi.dialogManager.hideMobileActionsOverlay();
|
_ffi.dialogManager.hideMobileActionsOverlay();
|
||||||
_ffi.listenToMouse(false);
|
_rawKeyFocusNode.dispose();
|
||||||
_mobileFocusNode.dispose();
|
|
||||||
_physicalFocusNode.dispose();
|
|
||||||
_ffi.close();
|
_ffi.close();
|
||||||
_timer?.cancel();
|
_timer?.cancel();
|
||||||
_ffi.dialogManager.dismissAll();
|
_ffi.dialogManager.dismissAll();
|
||||||
@ -119,7 +110,6 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
if (!Platform.isLinux) {
|
if (!Platform.isLinux) {
|
||||||
Wakelock.disable();
|
Wakelock.disable();
|
||||||
}
|
}
|
||||||
// WindowManager.instance.removeListener(this);
|
|
||||||
Get.delete<FFI>(tag: widget.id);
|
Get.delete<FFI>(tag: widget.id);
|
||||||
super.dispose();
|
super.dispose();
|
||||||
_removeStates(widget.id);
|
_removeStates(widget.id);
|
||||||
@ -129,87 +119,10 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
_ffi.resetModifiers();
|
_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}) {
|
void sendRawKey(RawKeyEvent e, {bool? down, bool? press}) {
|
||||||
// for maximum compatibility
|
// for maximum compatibility
|
||||||
final label = _logicalKeyMap[e.logicalKey.keyId] ??
|
final label = logicalKeyMap[e.logicalKey.keyId] ??
|
||||||
_physicalKeyMap[e.physicalKey.usbHidUsage] ??
|
physicalKeyMap[e.physicalKey.usbHidUsage] ??
|
||||||
e.logicalKey.keyLabel;
|
e.logicalKey.keyLabel;
|
||||||
_ffi.inputKey(label, down: down, press: press ?? false);
|
_ffi.inputKey(label, down: down, press: press ?? false);
|
||||||
}
|
}
|
||||||
@ -339,7 +252,7 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
child: Focus(
|
child: Focus(
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
canRequestFocus: true,
|
canRequestFocus: true,
|
||||||
focusNode: _physicalFocusNode,
|
focusNode: _rawKeyFocusNode,
|
||||||
onFocusChange: (bool v) {
|
onFocusChange: (bool v) {
|
||||||
_imageFocused = v;
|
_imageFocused = v;
|
||||||
},
|
},
|
||||||
@ -347,15 +260,6 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
child: child));
|
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) {
|
void _onPointHoverImage(PointerHoverEvent e) {
|
||||||
if (e.kind != ui.PointerDeviceKind.mouse) return;
|
if (e.kind != ui.PointerDeviceKind.mouse) return;
|
||||||
if (!_isPhysicalMouse) {
|
if (!_isPhysicalMouse) {
|
||||||
@ -420,7 +324,7 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
|
|
||||||
void enterView(PointerEnterEvent evt) {
|
void enterView(PointerEnterEvent evt) {
|
||||||
if (!_imageFocused) {
|
if (!_imageFocused) {
|
||||||
_physicalFocusNode.requestFocus();
|
_rawKeyFocusNode.requestFocus();
|
||||||
}
|
}
|
||||||
_cursorOverImage.value = true;
|
_cursorOverImage.value = true;
|
||||||
for (var f in _onEnterOrLeaveImage) {
|
for (var f in _onEnterOrLeaveImage) {
|
||||||
@ -505,21 +409,6 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
return out;
|
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
|
@override
|
||||||
bool get wantKeepAlive => true;
|
bool get wantKeepAlive => true;
|
||||||
}
|
}
|
||||||
@ -747,249 +636,3 @@ class QualityMonitor extends StatelessWidget {
|
|||||||
)
|
)
|
||||||
: const SizedBox.shrink())));
|
: 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<int, String> _logicalKeyMap = <int, String>{
|
|
||||||
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<int, String> _physicalKeyMap = <int, String>{
|
|
||||||
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',
|
|
||||||
};
|
|
||||||
|
|||||||
@ -98,13 +98,6 @@ class ConnectionManagerState extends State<ConnectionManager> {
|
|||||||
gFFI.serverModel.updateClientState();
|
gFFI.serverModel.updateClientState();
|
||||||
gFFI.serverModel.tabController.onSelected = (index) =>
|
gFFI.serverModel.tabController.onSelected = (index) =>
|
||||||
gFFI.chatModel.changeCurrentID(gFFI.serverModel.clients[index].id);
|
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();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -99,7 +99,7 @@ class _PeerCardState extends State<_PeerCard>
|
|||||||
color: str2color('${peer.id}${peer.platform}', 0x7f),
|
color: str2color('${peer.id}${peer.platform}', 0x7f),
|
||||||
),
|
),
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: _getPlatformImage('${peer.platform}', 30).paddingAll(6),
|
child: getPlatformImage(peer.platform, size: 30).paddingAll(6),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Container(
|
child: Container(
|
||||||
@ -196,7 +196,8 @@ class _PeerCardState extends State<_PeerCard>
|
|||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.all(6),
|
padding: const EdgeInsets.all(6),
|
||||||
child: _getPlatformImage(peer.platform, 60),
|
child:
|
||||||
|
getPlatformImage(peer.platform, size: 60),
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
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
|
@override
|
||||||
bool get wantKeepAlive => true;
|
bool get wantKeepAlive => true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -215,15 +215,6 @@ class _ConnectionPageState extends State<ConnectionPage> {
|
|||||||
super.dispose();
|
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.
|
/// Get all the saved peers.
|
||||||
Widget getPeers() {
|
Widget getPeers() {
|
||||||
final windowWidth = MediaQuery.of(context).size.width;
|
final windowWidth = MediaQuery.of(context).size.width;
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import 'package:provider/provider.dart';
|
|||||||
import 'package:wakelock/wakelock.dart';
|
import 'package:wakelock/wakelock.dart';
|
||||||
|
|
||||||
import '../../common.dart';
|
import '../../common.dart';
|
||||||
|
import '../../consts.dart';
|
||||||
import '../../models/model.dart';
|
import '../../models/model.dart';
|
||||||
import '../../models/platform_model.dart';
|
import '../../models/platform_model.dart';
|
||||||
import '../widgets/dialog.dart';
|
import '../widgets/dialog.dart';
|
||||||
@ -211,8 +212,8 @@ class _RemotePageState extends State<RemotePage> {
|
|||||||
|
|
||||||
void sendRawKey(RawKeyEvent e, {bool? down, bool? press}) {
|
void sendRawKey(RawKeyEvent e, {bool? down, bool? press}) {
|
||||||
// for maximum compatibility
|
// for maximum compatibility
|
||||||
final label = _logicalKeyMap[e.logicalKey.keyId] ??
|
final label = logicalKeyMap[e.logicalKey.keyId] ??
|
||||||
_physicalKeyMap[e.physicalKey.usbHidUsage] ??
|
physicalKeyMap[e.physicalKey.usbHidUsage] ??
|
||||||
e.logicalKey.keyLabel;
|
e.logicalKey.keyLabel;
|
||||||
gFFI.inputKey(label, down: down, press: press ?? false);
|
gFFI.inputKey(label, down: down, press: press ?? false);
|
||||||
}
|
}
|
||||||
@ -1170,233 +1171,3 @@ void sendPrompt(bool isMac, String key) {
|
|||||||
gFFI.ctrl = old;
|
gFFI.ctrl = old;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// flutter/packages/flutter/lib/src/services/keyboard_key.dart -> _keyLabels
|
|
||||||
/// see [LogicalKeyboardKey.keyLabel]
|
|
||||||
const Map<int, String> _logicalKeyMap = <int, String>{
|
|
||||||
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<int, String> _physicalKeyMap = <int, String>{
|
|
||||||
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',
|
|
||||||
};
|
|
||||||
|
|||||||
@ -331,7 +331,7 @@ class ImageModel with ChangeNotifier {
|
|||||||
|
|
||||||
ui.Image? get image => _image;
|
ui.Image? get image => _image;
|
||||||
|
|
||||||
String _id = '';
|
String id = '';
|
||||||
|
|
||||||
WeakReference<FFI> parent;
|
WeakReference<FFI> parent;
|
||||||
|
|
||||||
@ -375,7 +375,7 @@ class ImageModel with ChangeNotifier {
|
|||||||
await initializeCursorAndCanvas(parent.target!);
|
await initializeCursorAndCanvas(parent.target!);
|
||||||
}
|
}
|
||||||
if (parent.target?.ffiModel.isPeerAndroid ?? false) {
|
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();
|
parent.target?.canvasModel.updateViewStyle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -468,7 +468,7 @@ class CanvasModel with ChangeNotifier {
|
|||||||
double _scale = 1.0;
|
double _scale = 1.0;
|
||||||
// the tabbar over the image
|
// the tabbar over the image
|
||||||
double tabBarHeight = 0.0;
|
double tabBarHeight = 0.0;
|
||||||
// TODO multi canvas model
|
// remote id
|
||||||
String id = '';
|
String id = '';
|
||||||
// scroll offset x percent
|
// scroll offset x percent
|
||||||
double _scrollX = 0.0;
|
double _scrollX = 0.0;
|
||||||
@ -681,7 +681,7 @@ class CursorModel with ChangeNotifier {
|
|||||||
double _hoty = 0;
|
double _hoty = 0;
|
||||||
double _displayOriginX = 0;
|
double _displayOriginX = 0;
|
||||||
double _displayOriginY = 0;
|
double _displayOriginY = 0;
|
||||||
String id = ''; // TODO multi cursor model
|
String id = '';
|
||||||
WeakReference<FFI> parent;
|
WeakReference<FFI> parent;
|
||||||
|
|
||||||
ui.Image? get image => _image;
|
ui.Image? get image => _image;
|
||||||
@ -991,7 +991,7 @@ extension ToString on MouseButtons {
|
|||||||
|
|
||||||
enum ConnType { defaultConn, fileTransfer, portForward, rdp }
|
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 {
|
class FFI {
|
||||||
var id = '';
|
var id = '';
|
||||||
var shift = false;
|
var shift = false;
|
||||||
@ -1020,7 +1020,7 @@ class FFI {
|
|||||||
ffiModel = FfiModel(WeakReference(this));
|
ffiModel = FfiModel(WeakReference(this));
|
||||||
cursorModel = CursorModel(WeakReference(this));
|
cursorModel = CursorModel(WeakReference(this));
|
||||||
canvasModel = CanvasModel(WeakReference(this));
|
canvasModel = CanvasModel(WeakReference(this));
|
||||||
serverModel = ServerModel(WeakReference(this)); // use global FFI
|
serverModel = ServerModel(WeakReference(this));
|
||||||
chatModel = ChatModel(WeakReference(this));
|
chatModel = ChatModel(WeakReference(this));
|
||||||
fileModel = FileModel(WeakReference(this));
|
fileModel = FileModel(WeakReference(this));
|
||||||
abModel = AbModel(WeakReference(this));
|
abModel = AbModel(WeakReference(this));
|
||||||
@ -1042,12 +1042,6 @@ class FFI {
|
|||||||
.encode(modify({'id': id, 'type': 'wheel', 'y': y.toString()})));
|
.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].
|
/// Reset key modifiers to false, including [shift], [ctrl], [alt] and [command].
|
||||||
resetModifiers() {
|
resetModifiers() {
|
||||||
shift = ctrl = alt = command = false;
|
shift = ctrl = alt = command = false;
|
||||||
@ -1070,7 +1064,7 @@ class FFI {
|
|||||||
msg: json.encode(modify({'type': type, 'buttons': button.value})));
|
msg: json.encode(modify({'type': type, 'buttons': button.value})));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Raw Key
|
/// Send raw Key Event
|
||||||
inputRawKey(String name, int keyCode, int scanCode, bool down) {
|
inputRawKey(String name, int keyCode, int scanCode, bool down) {
|
||||||
bind.sessionHandleFlutterKeyEvent(
|
bind.sessionHandleFlutterKeyEvent(
|
||||||
id: id,
|
id: id,
|
||||||
@ -1080,10 +1074,6 @@ class FFI {
|
|||||||
downOrUp: down);
|
downOrUp: down);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> getKeyboardMode() {
|
|
||||||
return bind.sessionGetKeyboardName(id: id);
|
|
||||||
}
|
|
||||||
|
|
||||||
enterOrLeave(bool enter) {
|
enterOrLeave(bool enter) {
|
||||||
// Fix status
|
// Fix status
|
||||||
if (!enter) {
|
if (!enter) {
|
||||||
@ -1097,18 +1087,6 @@ class FFI {
|
|||||||
/// [press] indicates a click event(down and up).
|
/// [press] indicates a click event(down and up).
|
||||||
inputKey(String name, {bool? down, bool? press}) {
|
inputKey(String name, {bool? down, bool? press}) {
|
||||||
if (!ffiModel.keyboard()) return;
|
if (!ffiModel.keyboard()) return;
|
||||||
// final Map<String, String> 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(
|
bind.sessionInputKey(
|
||||||
id: id,
|
id: id,
|
||||||
name: name,
|
name: name,
|
||||||
@ -1161,7 +1139,7 @@ class FFI {
|
|||||||
} else {
|
} else {
|
||||||
chatModel.resetClientMode();
|
chatModel.resetClientMode();
|
||||||
canvasModel.id = id;
|
canvasModel.id = id;
|
||||||
imageModel._id = id;
|
imageModel.id = id;
|
||||||
cursorModel.id = id;
|
cursorModel.id = id;
|
||||||
}
|
}
|
||||||
// ignore: unused_local_variable
|
// ignore: unused_local_variable
|
||||||
@ -1212,17 +1190,6 @@ class FFI {
|
|||||||
debugPrint('model $id closed');
|
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<String, dynamic> evt, {double tabBarHeight = 0.0}) {
|
handleMouse(Map<String, dynamic> evt, {double tabBarHeight = 0.0}) {
|
||||||
var type = '';
|
var type = '';
|
||||||
var isMove = false;
|
var isMove = false;
|
||||||
@ -1240,8 +1207,8 @@ class FFI {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
evt['type'] = type;
|
evt['type'] = type;
|
||||||
var x = evt['x'];
|
double x = evt['x'];
|
||||||
var y = max(0.0, (evt['y'] as double) - tabBarHeight);
|
double y = max(0.0, (evt['y'] as double) - tabBarHeight);
|
||||||
if (isMove) {
|
if (isMove) {
|
||||||
canvasModel.moveDesktopMouse(x, y);
|
canvasModel.moveDesktopMouse(x, y);
|
||||||
}
|
}
|
||||||
@ -1264,9 +1231,6 @@ class FFI {
|
|||||||
y -= canvasModel.y;
|
y -= canvasModel.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isMove && (x < 0 || x > d.width || y < 0 || y > d.height)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
x /= canvasModel.scale;
|
x /= canvasModel.scale;
|
||||||
y /= canvasModel.scale;
|
y /= canvasModel.scale;
|
||||||
x += d.x;
|
x += d.x;
|
||||||
@ -1275,6 +1239,9 @@ class FFI {
|
|||||||
x = 0;
|
x = 0;
|
||||||
y = 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['x'] = '${x.round()}';
|
||||||
evt['y'] = '${y.round()}';
|
evt['y'] = '${y.round()}';
|
||||||
var buttons = '';
|
var buttons = '';
|
||||||
|
|||||||
@ -133,8 +133,6 @@ class ServerModel with ChangeNotifier {
|
|||||||
_fileOk = fileOption.isEmpty;
|
_fileOk = fileOption.isEmpty;
|
||||||
}
|
}
|
||||||
|
|
||||||
// input (mouse control) false by default
|
|
||||||
bind.mainSetOption(key: "enable-keyboard", value: "N");
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,18 +1,17 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hbb/common.dart';
|
||||||
import 'package:flutter_hbb/consts.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/main.dart';
|
||||||
|
import 'package:flutter_hbb/models/server_model.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:window_manager/window_manager.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
|
/// -t lib/cm_main.dart to test cm
|
||||||
void main(List<String> args) async {
|
void main(List<String> args) async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
await windowManager.ensureInitialized();
|
await windowManager.ensureInitialized();
|
||||||
await windowManager.setSize(Size(400, 600));
|
await windowManager.setSize(const Size(400, 600));
|
||||||
await windowManager.setAlignment(Alignment.topRight);
|
await windowManager.setAlignment(Alignment.topRight);
|
||||||
await initEnv(kAppTypeMain);
|
await initEnv(kAppTypeMain);
|
||||||
gFFI.serverModel.clients
|
gFFI.serverModel.clients
|
||||||
@ -23,6 +22,6 @@ void main(List<String> args) async {
|
|||||||
.add(Client(2, false, false, "UserC", "331123123", true, false, false));
|
.add(Client(2, false, false, "UserC", "331123123", true, false, false));
|
||||||
gFFI.serverModel.clients
|
gFFI.serverModel.clients
|
||||||
.add(Client(3, false, false, "UserD", "441123123", true, false, false));
|
.add(Client(3, false, false, "UserD", "441123123", true, false, false));
|
||||||
runApp(GetMaterialApp(
|
runApp(const GetMaterialApp(
|
||||||
debugShowCheckedModeBanner: false, home: DesktopServerPage()));
|
debugShowCheckedModeBanner: false, home: DesktopServerPage()));
|
||||||
}
|
}
|
||||||
@ -365,7 +365,7 @@ pub mod connection_manager {
|
|||||||
log::debug!("call_service_set_by_name fail,{}", e);
|
log::debug!("call_service_set_by_name fail,{}", e);
|
||||||
}
|
}
|
||||||
// send to UI, refresh widget
|
// 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) {
|
fn remove_connection(&self, id: i32) {
|
||||||
|
|||||||
@ -575,7 +575,6 @@ pub fn main_forget_password(id: String) {
|
|||||||
forget_password(id)
|
forget_password(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO APP_DIR & ui_interface
|
|
||||||
pub fn main_get_recent_peers() -> String {
|
pub fn main_get_recent_peers() -> String {
|
||||||
if !config::APP_DIR.read().unwrap().is_empty() {
|
if !config::APP_DIR.read().unwrap().is_empty() {
|
||||||
let peers: Vec<(String, config::PeerInfoSerde)> = PeerConfig::peers()
|
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 {
|
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()
|
LocalConfig::get_remote_id()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -411,7 +411,6 @@ impl sciter::EventHandler for SciterSession {
|
|||||||
impl SciterSession {
|
impl SciterSession {
|
||||||
pub fn new(cmd: String, id: String, password: String, args: Vec<String>) -> Self {
|
pub fn new(cmd: String, id: String, password: String, args: Vec<String>) -> Self {
|
||||||
let session: Session<SciterHandler> = Session {
|
let session: Session<SciterHandler> = Session {
|
||||||
cmd: cmd.clone(),
|
|
||||||
id: id.clone(),
|
id: id.clone(),
|
||||||
password: password.clone(),
|
password: password.clone(),
|
||||||
args,
|
args,
|
||||||
|
|||||||
@ -40,6 +40,7 @@ lazy_static::lazy_static! {
|
|||||||
pub static ref SENDER : Mutex<mpsc::UnboundedSender<ipc::Data>> = Mutex::new(check_connect_status(true));
|
pub static ref SENDER : Mutex<mpsc::UnboundedSender<ipc::Data>> = Mutex::new(check_connect_status(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn recent_sessions_updated() -> bool {
|
pub fn recent_sessions_updated() -> bool {
|
||||||
let mut childs = CHILDS.lock().unwrap();
|
let mut childs = CHILDS.lock().unwrap();
|
||||||
if childs.0 {
|
if childs.0 {
|
||||||
@ -50,6 +51,7 @@ pub fn recent_sessions_updated() -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_id() -> String {
|
pub fn get_id() -> String {
|
||||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||||
return Config::get_id();
|
return Config::get_id();
|
||||||
@ -57,18 +59,22 @@ pub fn get_id() -> String {
|
|||||||
return ipc::get_id();
|
return ipc::get_id();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_remote_id() -> String {
|
pub fn get_remote_id() -> String {
|
||||||
LocalConfig::get_remote_id()
|
LocalConfig::get_remote_id()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn set_remote_id(id: String) {
|
pub fn set_remote_id(id: String) {
|
||||||
LocalConfig::set_remote_id(&id);
|
LocalConfig::set_remote_id(&id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn goto_install() {
|
pub fn goto_install() {
|
||||||
allow_err!(crate::run_me(vec!["--install"]));
|
allow_err!(crate::run_me(vec!["--install"]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn install_me(_options: String, _path: String, silent: bool, debug: bool) {
|
pub fn install_me(_options: String, _path: String, silent: bool, debug: bool) {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
std::thread::spawn(move || {
|
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) {
|
pub fn update_me(_path: String) {
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
{
|
{
|
||||||
@ -105,11 +112,13 @@ pub fn update_me(_path: String) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn run_without_install() {
|
pub fn run_without_install() {
|
||||||
crate::run_me(vec!["--noinstall"]).ok();
|
crate::run_me(vec!["--noinstall"]).ok();
|
||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn show_run_without_install() -> bool {
|
pub fn show_run_without_install() -> bool {
|
||||||
let mut it = std::env::args();
|
let mut it = std::env::args();
|
||||||
if let Some(tmp) = it.next() {
|
if let Some(tmp) = it.next() {
|
||||||
@ -120,12 +129,14 @@ pub fn show_run_without_install() -> bool {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn has_rendezvous_service() -> bool {
|
pub fn has_rendezvous_service() -> bool {
|
||||||
#[cfg(all(windows, feature = "hbbs"))]
|
#[cfg(all(windows, feature = "hbbs"))]
|
||||||
return crate::platform::is_win_server() && crate::platform::windows::get_license().is_some();
|
return crate::platform::is_win_server() && crate::platform::windows::get_license().is_some();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_license() -> String {
|
pub fn get_license() -> String {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
if let Some(lic) = crate::platform::windows::get_license() {
|
if let Some(lic) = crate::platform::windows::get_license() {
|
||||||
@ -137,14 +148,12 @@ pub fn get_license() -> String {
|
|||||||
Default::default()
|
Default::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_option(key: String) -> String {
|
pub fn get_option(key: String) -> String {
|
||||||
get_option_(&key)
|
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn get_option_(key: &str) -> String {
|
fn get_option_(key: &str) -> String {
|
||||||
let map = OPTIONS.lock().unwrap();
|
let map = OPTIONS.lock().unwrap();
|
||||||
if let Some(v) = map.get(key) {
|
if let Some(v) = map.get(key) {
|
||||||
@ -154,29 +163,35 @@ fn get_option_(key: &str) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_local_option(key: String) -> String {
|
pub fn get_local_option(key: String) -> String {
|
||||||
LocalConfig::get_option(&key)
|
LocalConfig::get_option(&key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn set_local_option(key: String, value: String) {
|
pub fn set_local_option(key: String, value: String) {
|
||||||
LocalConfig::set_option(key, value);
|
LocalConfig::set_option(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn peer_has_password(id: String) -> bool {
|
pub fn peer_has_password(id: String) -> bool {
|
||||||
!PeerConfig::load(&id).password.is_empty()
|
!PeerConfig::load(&id).password.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn forget_password(id: String) {
|
pub fn forget_password(id: String) {
|
||||||
let mut c = PeerConfig::load(&id);
|
let mut c = PeerConfig::load(&id);
|
||||||
c.password.clear();
|
c.password.clear();
|
||||||
c.store(&id);
|
c.store(&id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_peer_option(id: String, name: String) -> String {
|
pub fn get_peer_option(id: String, name: String) -> String {
|
||||||
let c = PeerConfig::load(&id);
|
let c = PeerConfig::load(&id);
|
||||||
c.options.get(&name).unwrap_or(&"".to_owned()).to_owned()
|
c.options.get(&name).unwrap_or(&"".to_owned()).to_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn set_peer_option(id: String, name: String, value: String) {
|
pub fn set_peer_option(id: String, name: String, value: String) {
|
||||||
let mut c = PeerConfig::load(&id);
|
let mut c = PeerConfig::load(&id);
|
||||||
if value.is_empty() {
|
if value.is_empty() {
|
||||||
@ -187,10 +202,12 @@ pub fn set_peer_option(id: String, name: String, value: String) {
|
|||||||
c.store(&id);
|
c.store(&id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn using_public_server() -> bool {
|
pub fn using_public_server() -> bool {
|
||||||
crate::get_custom_rendezvous_server(get_option_("custom-rendezvous-server")).is_empty()
|
crate::get_custom_rendezvous_server(get_option_("custom-rendezvous-server")).is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_options() -> String {
|
pub fn get_options() -> String {
|
||||||
let options = OPTIONS.lock().unwrap();
|
let options = OPTIONS.lock().unwrap();
|
||||||
let mut m = serde_json::Map::new();
|
let mut m = serde_json::Map::new();
|
||||||
@ -200,15 +217,16 @@ pub fn get_options() -> String {
|
|||||||
serde_json::to_string(&m).unwrap()
|
serde_json::to_string(&m).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn test_if_valid_server(host: String) -> String {
|
pub fn test_if_valid_server(host: String) -> String {
|
||||||
hbb_common::socket_client::test_if_valid_server(&host)
|
hbb_common::socket_client::test_if_valid_server(&host)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_sound_inputs() -> Vec<String> {
|
pub fn get_sound_inputs() -> Vec<String> {
|
||||||
let mut a = Vec::new();
|
let mut a = Vec::new();
|
||||||
#[cfg(not(target_os = "linux"))]
|
#[cfg(not(target_os = "linux"))]
|
||||||
{
|
{
|
||||||
// TODO TEST
|
|
||||||
fn get_sound_inputs_() -> Vec<String> {
|
fn get_sound_inputs_() -> Vec<String> {
|
||||||
let mut out = Vec::new();
|
let mut out = Vec::new();
|
||||||
use cpal::traits::{DeviceTrait, HostTrait};
|
use cpal::traits::{DeviceTrait, HostTrait};
|
||||||
@ -236,7 +254,7 @@ pub fn get_sound_inputs() -> Vec<String> {
|
|||||||
a.push(name);
|
a.push(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(target_os = "linux")] // TODO
|
#[cfg(target_os = "linux")]
|
||||||
{
|
{
|
||||||
let inputs: Vec<String> = crate::platform::linux::get_pa_sources()
|
let inputs: Vec<String> = crate::platform::linux::get_pa_sources()
|
||||||
.drain(..)
|
.drain(..)
|
||||||
@ -250,6 +268,7 @@ pub fn get_sound_inputs() -> Vec<String> {
|
|||||||
a
|
a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn set_options(m: HashMap<String, String>) {
|
pub fn set_options(m: HashMap<String, String>) {
|
||||||
*OPTIONS.lock().unwrap() = m.clone();
|
*OPTIONS.lock().unwrap() = m.clone();
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
@ -258,6 +277,7 @@ pub fn set_options(m: HashMap<String, String>) {
|
|||||||
Config::set_options(m);
|
Config::set_options(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn set_option(key: String, value: String) {
|
pub fn set_option(key: String, value: String) {
|
||||||
let mut options = OPTIONS.lock().unwrap();
|
let mut options = OPTIONS.lock().unwrap();
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
@ -278,6 +298,7 @@ pub fn set_option(key: String, value: String) {
|
|||||||
Config::set_option(key, value);
|
Config::set_option(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn install_path() -> String {
|
pub fn install_path() -> String {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
return crate::platform::windows::get_install_info().1;
|
return crate::platform::windows::get_install_info().1;
|
||||||
@ -285,6 +306,7 @@ pub fn install_path() -> String {
|
|||||||
return "".to_owned();
|
return "".to_owned();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_socks() -> Vec<String> {
|
pub fn get_socks() -> Vec<String> {
|
||||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
@ -304,6 +326,7 @@ pub fn get_socks() -> Vec<String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn set_socks(proxy: String, username: String, password: String) {
|
pub fn set_socks(proxy: String, username: String, password: String) {
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
ipc::set_socks(config::Socks5Server {
|
ipc::set_socks(config::Socks5Server {
|
||||||
@ -315,10 +338,12 @@ pub fn set_socks(proxy: String, username: String, password: String) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
|
#[inline]
|
||||||
pub fn is_installed() -> bool {
|
pub fn is_installed() -> bool {
|
||||||
crate::platform::is_installed()
|
crate::platform::is_installed()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn is_rdp_service_open() -> bool {
|
pub fn is_rdp_service_open() -> bool {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
return is_installed() && crate::platform::windows::is_rdp_service_open();
|
return is_installed() && crate::platform::windows::is_rdp_service_open();
|
||||||
@ -326,6 +351,7 @@ pub fn is_rdp_service_open() -> bool {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn is_share_rdp() -> bool {
|
pub fn is_share_rdp() -> bool {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
return crate::platform::windows::is_share_rdp();
|
return crate::platform::windows::is_share_rdp();
|
||||||
@ -333,11 +359,13 @@ pub fn is_share_rdp() -> bool {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn set_share_rdp(_enable: bool) {
|
pub fn set_share_rdp(_enable: bool) {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
crate::platform::windows::set_share_rdp(_enable);
|
crate::platform::windows::set_share_rdp(_enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn is_installed_lower_version() -> bool {
|
pub fn is_installed_lower_version() -> bool {
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
return false;
|
return false;
|
||||||
@ -350,12 +378,14 @@ pub fn is_installed_lower_version() -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn closing(x: i32, y: i32, w: i32, h: i32) {
|
pub fn closing(x: i32, y: i32, w: i32, h: i32) {
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
crate::server::input_service::fix_key_down_timeout_at_exit();
|
crate::server::input_service::fix_key_down_timeout_at_exit();
|
||||||
LocalConfig::set_size(x, y, w, h);
|
LocalConfig::set_size(x, y, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_size() -> Vec<i32> {
|
pub fn get_size() -> Vec<i32> {
|
||||||
let s = LocalConfig::get_size();
|
let s = LocalConfig::get_size();
|
||||||
let mut v = Vec::new();
|
let mut v = Vec::new();
|
||||||
@ -366,12 +396,14 @@ pub fn get_size() -> Vec<i32> {
|
|||||||
v
|
v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_mouse_time() -> f64 {
|
pub fn get_mouse_time() -> f64 {
|
||||||
let ui_status = UI_STATUS.lock().unwrap();
|
let ui_status = UI_STATUS.lock().unwrap();
|
||||||
let res = ui_status.2 as f64;
|
let res = ui_status.2 as f64;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn check_mouse_time() {
|
pub fn check_mouse_time() {
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
{
|
{
|
||||||
@ -380,12 +412,14 @@ pub fn check_mouse_time() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_connect_status() -> Status {
|
pub fn get_connect_status() -> Status {
|
||||||
let ui_statue = UI_STATUS.lock().unwrap();
|
let ui_statue = UI_STATUS.lock().unwrap();
|
||||||
let res = ui_statue.clone();
|
let res = ui_statue.clone();
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn temporary_password() -> String {
|
pub fn temporary_password() -> String {
|
||||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||||
return password_security::temporary_password();
|
return password_security::temporary_password();
|
||||||
@ -393,6 +427,7 @@ pub fn temporary_password() -> String {
|
|||||||
return TEMPORARY_PASSWD.lock().unwrap().clone();
|
return TEMPORARY_PASSWD.lock().unwrap().clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn update_temporary_password() {
|
pub fn update_temporary_password() {
|
||||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||||
password_security::update_temporary_password();
|
password_security::update_temporary_password();
|
||||||
@ -400,6 +435,7 @@ pub fn update_temporary_password() {
|
|||||||
allow_err!(ipc::update_temporary_password());
|
allow_err!(ipc::update_temporary_password());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn permanent_password() -> String {
|
pub fn permanent_password() -> String {
|
||||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||||
return Config::get_permanent_password();
|
return Config::get_permanent_password();
|
||||||
@ -407,6 +443,7 @@ pub fn permanent_password() -> String {
|
|||||||
return ipc::get_permanent_password();
|
return ipc::get_permanent_password();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn set_permanent_password(password: String) {
|
pub fn set_permanent_password(password: String) {
|
||||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||||
Config::set_permanent_password(&password);
|
Config::set_permanent_password(&password);
|
||||||
@ -414,31 +451,38 @@ pub fn set_permanent_password(password: String) {
|
|||||||
allow_err!(ipc::set_permanent_password(password));
|
allow_err!(ipc::set_permanent_password(password));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_peer(id: String) -> PeerConfig {
|
pub fn get_peer(id: String) -> PeerConfig {
|
||||||
PeerConfig::load(&id)
|
PeerConfig::load(&id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_fav() -> Vec<String> {
|
pub fn get_fav() -> Vec<String> {
|
||||||
LocalConfig::get_fav()
|
LocalConfig::get_fav()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn store_fav(fav: Vec<String>) {
|
pub fn store_fav(fav: Vec<String>) {
|
||||||
LocalConfig::set_fav(fav);
|
LocalConfig::set_fav(fav);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_recent_sessions() -> Vec<(String, SystemTime, PeerConfig)> {
|
pub fn get_recent_sessions() -> Vec<(String, SystemTime, PeerConfig)> {
|
||||||
PeerConfig::peers()
|
PeerConfig::peers()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios", feature = "cli")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios", feature = "cli")))]
|
||||||
pub fn get_icon() -> String {
|
pub fn get_icon() -> String {
|
||||||
crate::get_icon()
|
crate::get_icon()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn remove_peer(id: String) {
|
pub fn remove_peer(id: String) {
|
||||||
PeerConfig::remove(&id);
|
PeerConfig::remove(&id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn new_remote(id: String, remote_type: String) {
|
pub fn new_remote(id: String, remote_type: String) {
|
||||||
let mut lock = CHILDS.lock().unwrap();
|
let mut lock = CHILDS.lock().unwrap();
|
||||||
let args = vec![format!("--{}", remote_type), id.clone()];
|
let args = vec![format!("--{}", remote_type), id.clone()];
|
||||||
@ -467,6 +511,7 @@ pub fn new_remote(id: String, remote_type: String) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn is_process_trusted(_prompt: bool) -> bool {
|
pub fn is_process_trusted(_prompt: bool) -> bool {
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
return crate::platform::macos::is_process_trusted(_prompt);
|
return crate::platform::macos::is_process_trusted(_prompt);
|
||||||
@ -474,6 +519,7 @@ pub fn is_process_trusted(_prompt: bool) -> bool {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn is_can_screen_recording(_prompt: bool) -> bool {
|
pub fn is_can_screen_recording(_prompt: bool) -> bool {
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
return crate::platform::macos::is_can_screen_recording(_prompt);
|
return crate::platform::macos::is_can_screen_recording(_prompt);
|
||||||
@ -481,6 +527,7 @@ pub fn is_can_screen_recording(_prompt: bool) -> bool {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn is_installed_daemon(_prompt: bool) -> bool {
|
pub fn is_installed_daemon(_prompt: bool) -> bool {
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
return crate::platform::macos::is_installed_daemon(_prompt);
|
return crate::platform::macos::is_installed_daemon(_prompt);
|
||||||
@ -488,6 +535,7 @@ pub fn is_installed_daemon(_prompt: bool) -> bool {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_error() -> String {
|
pub fn get_error() -> String {
|
||||||
#[cfg(not(any(feature = "cli")))]
|
#[cfg(not(any(feature = "cli")))]
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
@ -508,6 +556,7 @@ pub fn get_error() -> String {
|
|||||||
return "".to_owned();
|
return "".to_owned();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn is_login_wayland() -> bool {
|
pub fn is_login_wayland() -> bool {
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
return crate::platform::linux::is_login_wayland();
|
return crate::platform::linux::is_login_wayland();
|
||||||
@ -515,11 +564,13 @@ pub fn is_login_wayland() -> bool {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn fix_login_wayland() {
|
pub fn fix_login_wayland() {
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
crate::platform::linux::fix_login_wayland();
|
crate::platform::linux::fix_login_wayland();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn current_is_wayland() -> bool {
|
pub fn current_is_wayland() -> bool {
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
return crate::platform::linux::current_is_wayland();
|
return crate::platform::linux::current_is_wayland();
|
||||||
@ -527,6 +578,7 @@ pub fn current_is_wayland() -> bool {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn modify_default_login() -> String {
|
pub fn modify_default_login() -> String {
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
return crate::platform::linux::modify_default_login();
|
return crate::platform::linux::modify_default_login();
|
||||||
@ -534,22 +586,27 @@ pub fn modify_default_login() -> String {
|
|||||||
return "".to_owned();
|
return "".to_owned();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_software_update_url() -> String {
|
pub fn get_software_update_url() -> String {
|
||||||
SOFTWARE_UPDATE_URL.lock().unwrap().clone()
|
SOFTWARE_UPDATE_URL.lock().unwrap().clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_new_version() -> String {
|
pub fn get_new_version() -> String {
|
||||||
hbb_common::get_version_from_url(&*SOFTWARE_UPDATE_URL.lock().unwrap())
|
hbb_common::get_version_from_url(&*SOFTWARE_UPDATE_URL.lock().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_version() -> String {
|
pub fn get_version() -> String {
|
||||||
crate::VERSION.to_owned()
|
crate::VERSION.to_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_app_name() -> String {
|
pub fn get_app_name() -> String {
|
||||||
crate::get_app_name()
|
crate::get_app_name()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
pub fn get_software_ext() -> String {
|
pub fn get_software_ext() -> String {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
@ -561,6 +618,7 @@ pub fn get_software_ext() -> String {
|
|||||||
p.to_owned()
|
p.to_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
pub fn get_software_store_path() -> String {
|
pub fn get_software_store_path() -> String {
|
||||||
let mut p = std::env::temp_dir();
|
let mut p = std::env::temp_dir();
|
||||||
@ -575,17 +633,20 @@ pub fn get_software_store_path() -> String {
|
|||||||
format!("{}.{}", p.to_string_lossy(), get_software_ext())
|
format!("{}.{}", p.to_string_lossy(), get_software_ext())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn create_shortcut(_id: String) {
|
pub fn create_shortcut(_id: String) {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
crate::platform::windows::create_shortcut(&_id).ok();
|
crate::platform::windows::create_shortcut(&_id).ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn discover() {
|
pub fn discover() {
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
allow_err!(crate::lan::discover());
|
allow_err!(crate::lan::discover());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_lan_peers() -> Vec<(String, config::PeerInfoSerde)> {
|
pub fn get_lan_peers() -> Vec<(String, config::PeerInfoSerde)> {
|
||||||
config::LanPeers::load()
|
config::LanPeers::load()
|
||||||
.peers
|
.peers
|
||||||
@ -603,10 +664,12 @@ pub fn get_lan_peers() -> Vec<(String, config::PeerInfoSerde)> {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_uuid() -> String {
|
pub fn get_uuid() -> String {
|
||||||
base64::encode(hbb_common::get_uuid())
|
base64::encode(hbb_common::get_uuid())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios", feature = "cli")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios", feature = "cli")))]
|
||||||
pub fn open_url(url: String) {
|
pub fn open_url(url: String) {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
@ -622,6 +685,7 @@ pub fn open_url(url: String) {
|
|||||||
allow_err!(std::process::Command::new(p).arg(url).spawn());
|
allow_err!(std::process::Command::new(p).arg(url).spawn());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
pub fn change_id(id: String) {
|
pub fn change_id(id: String) {
|
||||||
*ASYNC_JOB_STATUS.lock().unwrap() = " ".to_owned();
|
*ASYNC_JOB_STATUS.lock().unwrap() = " ".to_owned();
|
||||||
@ -631,6 +695,7 @@ pub fn change_id(id: String) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn post_request(url: String, body: String, header: String) {
|
pub fn post_request(url: String, body: String, header: String) {
|
||||||
*ASYNC_JOB_STATUS.lock().unwrap() = " ".to_owned();
|
*ASYNC_JOB_STATUS.lock().unwrap() = " ".to_owned();
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
@ -641,28 +706,34 @@ pub fn post_request(url: String, body: String, header: String) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
pub fn is_ok_change_id() -> bool {
|
pub fn is_ok_change_id() -> bool {
|
||||||
machine_uid::get().is_ok()
|
machine_uid::get().is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_async_job_status() -> String {
|
pub fn get_async_job_status() -> String {
|
||||||
ASYNC_JOB_STATUS.lock().unwrap().clone()
|
ASYNC_JOB_STATUS.lock().unwrap().clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios", feature = "cli")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios", feature = "cli")))]
|
||||||
pub fn t(name: String) -> String {
|
pub fn t(name: String) -> String {
|
||||||
crate::client::translate(name)
|
crate::client::translate(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_langs() -> String {
|
pub fn get_langs() -> String {
|
||||||
crate::lang::LANGS.to_string()
|
crate::lang::LANGS.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn is_xfce() -> bool {
|
pub fn is_xfce() -> bool {
|
||||||
crate::platform::is_xfce()
|
crate::platform::is_xfce()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_api_server() -> String {
|
pub fn get_api_server() -> String {
|
||||||
crate::get_api_server(
|
crate::get_api_server(
|
||||||
get_option_("api-server"),
|
get_option_("api-server"),
|
||||||
@ -670,6 +741,7 @@ pub fn get_api_server() -> String {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn has_hwcodec() -> bool {
|
pub fn has_hwcodec() -> bool {
|
||||||
#[cfg(not(feature = "hwcodec"))]
|
#[cfg(not(feature = "hwcodec"))]
|
||||||
return false;
|
return false;
|
||||||
@ -677,6 +749,7 @@ pub fn has_hwcodec() -> bool {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn check_super_user_permission() -> bool {
|
pub fn check_super_user_permission() -> bool {
|
||||||
#[cfg(any(windows, target_os = "linux"))]
|
#[cfg(any(windows, target_os = "linux"))]
|
||||||
return crate::platform::check_super_user_permission().unwrap_or(false);
|
return crate::platform::check_super_user_permission().unwrap_or(false);
|
||||||
|
|||||||
@ -35,7 +35,6 @@ lazy_static::lazy_static! {
|
|||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct Session<T: InvokeUiSession> {
|
pub struct Session<T: InvokeUiSession> {
|
||||||
pub cmd: String,
|
|
||||||
pub id: String,
|
pub id: String,
|
||||||
pub password: String,
|
pub password: String,
|
||||||
pub args: Vec<String>,
|
pub args: Vec<String>,
|
||||||
@ -53,7 +52,7 @@ impl<T: InvokeUiSession> Session<T> {
|
|||||||
pub fn get_image_quality(&self) -> String {
|
pub fn get_image_quality(&self) -> String {
|
||||||
self.lc.read().unwrap().image_quality.clone()
|
self.lc.read().unwrap().image_quality.clone()
|
||||||
}
|
}
|
||||||
/// Get custom image quality.
|
|
||||||
pub fn get_custom_image_quality(&self) -> Vec<i32> {
|
pub fn get_custom_image_quality(&self) -> Vec<i32> {
|
||||||
self.lc.read().unwrap().custom_image_quality.clone()
|
self.lc.read().unwrap().custom_image_quality.clone()
|
||||||
}
|
}
|
||||||
@ -1115,7 +1114,6 @@ impl<T: InvokeUiSession> Interface for Session<T> {
|
|||||||
crate::platform::windows::add_recent_document(&path);
|
crate::platform::windows::add_recent_document(&path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO use event callbcak
|
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
self.start_keyboard_hook();
|
self.start_keyboard_hook();
|
||||||
}
|
}
|
||||||
@ -1158,8 +1156,6 @@ impl<T: InvokeUiSession> Interface for Session<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO use event callbcak
|
|
||||||
// sciter only
|
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
impl<T: InvokeUiSession> Session<T> {
|
impl<T: InvokeUiSession> Session<T> {
|
||||||
fn start_keyboard_hook(&self) {
|
fn start_keyboard_hook(&self) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user