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