refact: custom client, more advanced settings (#8085)
* refact: custom client, more advanced settings Signed-off-by: fufesou <shuanglongchen@yeah.net> * feat: custom client, more advanced settings Signed-off-by: fufesou <shuanglongchen@yeah.net> --------- Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
parent
c2b7810c33
commit
96f41fcc02
@ -1408,7 +1408,7 @@ bool option2bool(String option, String value) {
|
|||||||
res = value != "N";
|
res = value != "N";
|
||||||
} else if (option.startsWith("allow-") ||
|
} else if (option.startsWith("allow-") ||
|
||||||
option == "stop-service" ||
|
option == "stop-service" ||
|
||||||
option == "direct-server" ||
|
option == kOptionDirectServer ||
|
||||||
option == "stop-rendezvous-service" ||
|
option == "stop-rendezvous-service" ||
|
||||||
option == kOptionForceAlwaysRelay) {
|
option == kOptionForceAlwaysRelay) {
|
||||||
res = value == "Y";
|
res = value == "Y";
|
||||||
@ -1425,7 +1425,7 @@ String bool2option(String option, bool b) {
|
|||||||
res = b ? defaultOptionYes : 'N';
|
res = b ? defaultOptionYes : 'N';
|
||||||
} else if (option.startsWith('allow-') ||
|
} else if (option.startsWith('allow-') ||
|
||||||
option == "stop-service" ||
|
option == "stop-service" ||
|
||||||
option == "direct-server" ||
|
option == kOptionDirectServer ||
|
||||||
option == "stop-rendezvous-service" ||
|
option == "stop-rendezvous-service" ||
|
||||||
option == kOptionForceAlwaysRelay) {
|
option == kOptionForceAlwaysRelay) {
|
||||||
res = b ? 'Y' : defaultOptionNo;
|
res = b ? 'Y' : defaultOptionNo;
|
||||||
|
@ -341,7 +341,7 @@ initSharedStates(String id) {
|
|||||||
ShowRemoteCursorLockState.init(id);
|
ShowRemoteCursorLockState.init(id);
|
||||||
RemoteCursorMovedState.init(id);
|
RemoteCursorMovedState.init(id);
|
||||||
FingerprintState.init(id);
|
FingerprintState.init(id);
|
||||||
PeerBoolOption.init(id, 'zoom-cursor', () => false);
|
PeerBoolOption.init(id, kOptionZoomCursor, () => false);
|
||||||
UnreadChatCountState.init(id);
|
UnreadChatCountState.init(id);
|
||||||
if (isMobile) ConnectionTypeState.init(id); // desktop in other places
|
if (isMobile) ConnectionTypeState.init(id); // desktop in other places
|
||||||
}
|
}
|
||||||
@ -355,7 +355,7 @@ removeSharedStates(String id) {
|
|||||||
KeyboardEnabledState.delete(id);
|
KeyboardEnabledState.delete(id);
|
||||||
RemoteCursorMovedState.delete(id);
|
RemoteCursorMovedState.delete(id);
|
||||||
FingerprintState.delete(id);
|
FingerprintState.delete(id);
|
||||||
PeerBoolOption.delete(id, 'zoom-cursor');
|
PeerBoolOption.delete(id, kOptionZoomCursor);
|
||||||
UnreadChatCountState.delete(id);
|
UnreadChatCountState.delete(id);
|
||||||
if (isMobile) ConnectionTypeState.delete(id);
|
if (isMobile) ConnectionTypeState.delete(id);
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import 'package:flutter_hbb/common/formatter/id_formatter.dart';
|
|||||||
import 'package:flutter_hbb/common/hbbs/hbbs.dart';
|
import 'package:flutter_hbb/common/hbbs/hbbs.dart';
|
||||||
import 'package:flutter_hbb/common/widgets/peer_card.dart';
|
import 'package:flutter_hbb/common/widgets/peer_card.dart';
|
||||||
import 'package:flutter_hbb/common/widgets/peers_view.dart';
|
import 'package:flutter_hbb/common/widgets/peers_view.dart';
|
||||||
|
import 'package:flutter_hbb/consts.dart';
|
||||||
import 'package:flutter_hbb/desktop/widgets/popup_menu.dart';
|
import 'package:flutter_hbb/desktop/widgets/popup_menu.dart';
|
||||||
import 'package:flutter_hbb/models/ab_model.dart';
|
import 'package:flutter_hbb/models/ab_model.dart';
|
||||||
import 'package:flutter_hbb/models/platform_model.dart';
|
import 'package:flutter_hbb/models/platform_model.dart';
|
||||||
@ -191,12 +192,15 @@ class _AddressBookState extends State<AddressBook> {
|
|||||||
}
|
}
|
||||||
final TextEditingController textEditingController = TextEditingController();
|
final TextEditingController textEditingController = TextEditingController();
|
||||||
|
|
||||||
|
final isOptFixed = isOptionFixed(kOptionCurrentAbName);
|
||||||
return DropdownButton2<String>(
|
return DropdownButton2<String>(
|
||||||
value: gFFI.abModel.currentName.value,
|
value: gFFI.abModel.currentName.value,
|
||||||
onChanged: (value) {
|
onChanged: isOptFixed
|
||||||
|
? null
|
||||||
|
: (value) {
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
gFFI.abModel.setCurrentName(value);
|
gFFI.abModel.setCurrentName(value);
|
||||||
bind.setLocalFlutterOption(k: 'current-ab-name', v: value);
|
bind.setLocalFlutterOption(k: kOptionCurrentAbName, v: value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
underline: Container(
|
underline: Container(
|
||||||
@ -358,7 +362,8 @@ class _AddressBookState extends State<AddressBook> {
|
|||||||
return shouldSortTags();
|
return shouldSortTags();
|
||||||
},
|
},
|
||||||
setter: (bool v) async {
|
setter: (bool v) async {
|
||||||
bind.mainSetLocalOption(key: sortAbTagsOption, value: v ? 'Y' : defaultOptionNo);
|
bind.mainSetLocalOption(
|
||||||
|
key: sortAbTagsOption, value: v ? 'Y' : defaultOptionNo);
|
||||||
gFFI.abModel.sortTags.value = v;
|
gFFI.abModel.sortTags.value = v;
|
||||||
},
|
},
|
||||||
dismissOnClicked: true,
|
dismissOnClicked: true,
|
||||||
@ -376,7 +381,8 @@ class _AddressBookState extends State<AddressBook> {
|
|||||||
return filterAbTagByIntersection();
|
return filterAbTagByIntersection();
|
||||||
},
|
},
|
||||||
setter: (bool v) async {
|
setter: (bool v) async {
|
||||||
bind.mainSetLocalOption(key: filterAbTagOption, value: v ? 'Y' : defaultOptionNo);
|
bind.mainSetLocalOption(
|
||||||
|
key: filterAbTagOption, value: v ? 'Y' : defaultOptionNo);
|
||||||
gFFI.abModel.filterByIntersection.value = v;
|
gFFI.abModel.filterByIntersection.value = v;
|
||||||
},
|
},
|
||||||
dismissOnClicked: true,
|
dismissOnClicked: true,
|
||||||
|
@ -204,6 +204,7 @@ void changeWhiteList({Function()? callback}) async {
|
|||||||
errorText: msg.isEmpty ? null : translate(msg),
|
errorText: msg.isEmpty ? null : translate(msg),
|
||||||
),
|
),
|
||||||
controller: controller,
|
controller: controller,
|
||||||
|
enabled: !isOptFixed,
|
||||||
autofocus: true),
|
autofocus: true),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -217,15 +218,15 @@ void changeWhiteList({Function()? callback}) async {
|
|||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
dialogButton("Cancel", onPressed: close, isOutline: true),
|
dialogButton("Cancel", onPressed: close, isOutline: true),
|
||||||
dialogButton("Clear", onPressed: isOptFixed ? null : () async {
|
if (!isOptFixed)dialogButton("Clear", onPressed: () async {
|
||||||
await bind.mainSetOption(
|
await bind.mainSetOption(
|
||||||
key: kOptionWhitelist, value: defaultOptionWhitelist);
|
key: kOptionWhitelist, value: defaultOptionWhitelist);
|
||||||
callback?.call();
|
callback?.call();
|
||||||
close();
|
close();
|
||||||
}, isOutline: true),
|
}, isOutline: true),
|
||||||
dialogButton(
|
if (!isOptFixed) dialogButton(
|
||||||
"OK",
|
"OK",
|
||||||
onPressed: isOptFixed ? null : () async {
|
onPressed: () async {
|
||||||
setState(() {
|
setState(() {
|
||||||
msg = "";
|
msg = "";
|
||||||
isInProgress = true;
|
isInProgress = true;
|
||||||
|
@ -74,9 +74,11 @@ class _PeerTabPageState extends State<PeerTabPage>
|
|||||||
];
|
];
|
||||||
RelativeRect? mobileTabContextMenuPos;
|
RelativeRect? mobileTabContextMenuPos;
|
||||||
|
|
||||||
|
final isOptVisiableFixed = isOptionFixed(kOptionPeerTabVisible);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
final uiType = bind.getLocalFlutterOption(k: 'peer-card-ui-type');
|
final uiType = bind.getLocalFlutterOption(k: kOptionPeerCardUiType);
|
||||||
if (uiType != '') {
|
if (uiType != '') {
|
||||||
peerCardUiType.value = int.parse(uiType) == 0
|
peerCardUiType.value = int.parse(uiType) == 0
|
||||||
? PeerUiType.grid
|
? PeerUiType.grid
|
||||||
@ -85,7 +87,7 @@ class _PeerTabPageState extends State<PeerTabPage>
|
|||||||
: PeerUiType.list;
|
: PeerUiType.list;
|
||||||
}
|
}
|
||||||
hideAbTagsPanel.value =
|
hideAbTagsPanel.value =
|
||||||
bind.mainGetLocalOption(key: "hideAbTagsPanel").isNotEmpty;
|
bind.mainGetLocalOption(key: kOptionHideAbTagsPanel).isNotEmpty;
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,10 +175,12 @@ class _PeerTabPageState extends State<PeerTabPage>
|
|||||||
child: Icon(model.tabIcon(t), color: color)
|
child: Icon(model.tabIcon(t), color: color)
|
||||||
.paddingSymmetric(horizontal: 4),
|
.paddingSymmetric(horizontal: 4),
|
||||||
).paddingSymmetric(horizontal: 4),
|
).paddingSymmetric(horizontal: 4),
|
||||||
onTap: () async {
|
onTap: isOptionFixed(kOptionPeerTabIndex)
|
||||||
|
? null
|
||||||
|
: () async {
|
||||||
await handleTabSelection(t);
|
await handleTabSelection(t);
|
||||||
await bind.setLocalFlutterOption(
|
await bind.setLocalFlutterOption(
|
||||||
k: PeerTabModel.kPeerTabIndex, v: t.toString());
|
k: kOptionPeerTabIndex, v: t.toString());
|
||||||
},
|
},
|
||||||
onHover: (value) => hover.value = value,
|
onHover: (value) => hover.value = value,
|
||||||
),
|
),
|
||||||
@ -265,12 +269,17 @@ class _PeerTabPageState extends State<PeerTabPage>
|
|||||||
if (!model.isEnabled[i]) continue;
|
if (!model.isEnabled[i]) continue;
|
||||||
items.add(PopupMenuItem(
|
items.add(PopupMenuItem(
|
||||||
height: kMinInteractiveDimension * 0.8,
|
height: kMinInteractiveDimension * 0.8,
|
||||||
onTap: () => model.setTabVisible(i, !model.isVisibleEnabled[i]),
|
onTap: isOptVisiableFixed
|
||||||
|
? null
|
||||||
|
: () => model.setTabVisible(i, !model.isVisibleEnabled[i]),
|
||||||
|
enabled: !isOptVisiableFixed,
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Checkbox(
|
Checkbox(
|
||||||
value: model.isVisibleEnabled[i],
|
value: model.isVisibleEnabled[i],
|
||||||
onChanged: (_) {
|
onChanged: isOptVisiableFixed
|
||||||
|
? null
|
||||||
|
: (_) {
|
||||||
model.setTabVisible(i, !model.isVisibleEnabled[i]);
|
model.setTabVisible(i, !model.isVisibleEnabled[i]);
|
||||||
if (Navigator.canPop(context)) {
|
if (Navigator.canPop(context)) {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
@ -333,7 +342,8 @@ class _PeerTabPageState extends State<PeerTabPage>
|
|||||||
setter: (show) async {
|
setter: (show) async {
|
||||||
model.setTabVisible(tabIndex, show);
|
model.setTabVisible(tabIndex, show);
|
||||||
cancelFunc();
|
cancelFunc();
|
||||||
}));
|
},
|
||||||
|
enabled: (!isOptVisiableFixed).obs));
|
||||||
}
|
}
|
||||||
return mod_menu.PopupMenu(
|
return mod_menu.PopupMenu(
|
||||||
items: menu
|
items: menu
|
||||||
@ -537,7 +547,8 @@ class _PeerTabPageState extends State<PeerTabPage>
|
|||||||
),
|
),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await bind.mainSetLocalOption(
|
await bind.mainSetLocalOption(
|
||||||
key: "hideAbTagsPanel", value: hideAbTagsPanel.value ? defaultOptionNo : "Y");
|
key: kOptionHideAbTagsPanel,
|
||||||
|
value: hideAbTagsPanel.value ? defaultOptionNo : "Y");
|
||||||
hideAbTagsPanel.value = !hideAbTagsPanel.value;
|
hideAbTagsPanel.value = !hideAbTagsPanel.value;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -799,12 +810,15 @@ class _PeerViewDropdownState extends State<PeerViewDropdown> {
|
|||||||
style: style),
|
style: style),
|
||||||
e,
|
e,
|
||||||
peerCardUiType.value,
|
peerCardUiType.value,
|
||||||
dense: true, (PeerUiType? v) async {
|
dense: true,
|
||||||
|
isOptionFixed(kOptionPeerCardUiType)
|
||||||
|
? null
|
||||||
|
: (PeerUiType? v) async {
|
||||||
if (v != null) {
|
if (v != null) {
|
||||||
peerCardUiType.value = v;
|
peerCardUiType.value = v;
|
||||||
setState(() {});
|
setState(() {});
|
||||||
await bind.setLocalFlutterOption(
|
await bind.setLocalFlutterOption(
|
||||||
k: "peer-card-ui-type",
|
k: kOptionPeerCardUiType,
|
||||||
v: peerCardUiType.value.index.toString(),
|
v: peerCardUiType.value.index.toString(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -852,7 +866,7 @@ class _PeerSortDropdownState extends State<PeerSortDropdown> {
|
|||||||
if (!PeerSortType.values.contains(peerSort.value)) {
|
if (!PeerSortType.values.contains(peerSort.value)) {
|
||||||
peerSort.value = PeerSortType.remoteId;
|
peerSort.value = PeerSortType.remoteId;
|
||||||
bind.setLocalFlutterOption(
|
bind.setLocalFlutterOption(
|
||||||
k: "peer-sorting",
|
k: kOptionPeerSorting,
|
||||||
v: peerSort.value,
|
v: peerSort.value,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -882,7 +896,7 @@ class _PeerSortDropdownState extends State<PeerSortDropdown> {
|
|||||||
if (v != null) {
|
if (v != null) {
|
||||||
peerSort.value = v;
|
peerSort.value = v;
|
||||||
await bind.setLocalFlutterOption(
|
await bind.setLocalFlutterOption(
|
||||||
k: "peer-sorting",
|
k: kOptionPeerSorting,
|
||||||
v: peerSort.value,
|
v: peerSort.value,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,12 @@ import 'dart:collection';
|
|||||||
import 'package:dynamic_layouts/dynamic_layouts.dart';
|
import 'package:dynamic_layouts/dynamic_layouts.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hbb/consts.dart';
|
||||||
import 'package:flutter_hbb/desktop/widgets/scroll_wrapper.dart';
|
import 'package:flutter_hbb/desktop/widgets/scroll_wrapper.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:visibility_detector/visibility_detector.dart';
|
import 'package:visibility_detector/visibility_detector.dart';
|
||||||
import 'package:window_manager/window_manager.dart';
|
import 'package:window_manager/window_manager.dart';
|
||||||
import 'package:flutter_hbb/models/peer_tab_model.dart';
|
|
||||||
|
|
||||||
import '../../common.dart';
|
import '../../common.dart';
|
||||||
import '../../models/peer_model.dart';
|
import '../../models/peer_model.dart';
|
||||||
@ -45,7 +45,7 @@ class LoadEvent {
|
|||||||
final peerSearchText = "".obs;
|
final peerSearchText = "".obs;
|
||||||
|
|
||||||
/// for peer sort, global obs value
|
/// for peer sort, global obs value
|
||||||
final peerSort = bind.getLocalFlutterOption(k: 'peer-sorting').obs;
|
final peerSort = bind.getLocalFlutterOption(k: kOptionPeerSorting).obs;
|
||||||
|
|
||||||
// list for listener
|
// list for listener
|
||||||
final obslist = [peerSearchText, peerSort].obs;
|
final obslist = [peerSearchText, peerSort].obs;
|
||||||
@ -302,7 +302,7 @@ class _PeersViewState extends State<_PeersView> with WindowListener {
|
|||||||
if (!PeerSortType.values.contains(sortedBy)) {
|
if (!PeerSortType.values.contains(sortedBy)) {
|
||||||
sortedBy = PeerSortType.remoteId;
|
sortedBy = PeerSortType.remoteId;
|
||||||
bind.setLocalFlutterOption(
|
bind.setLocalFlutterOption(
|
||||||
k: "peer-sorting",
|
k: kOptionPeerSorting,
|
||||||
v: sortedBy,
|
v: sortedBy,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -227,7 +227,8 @@ List<(String, String)> otherDefaultSettings() {
|
|||||||
if ((isDesktop || isWebDesktop)) ('Zoom cursor', kOptionZoomCursor),
|
if ((isDesktop || isWebDesktop)) ('Zoom cursor', kOptionZoomCursor),
|
||||||
('Show quality monitor', kOptionShowQualityMonitor),
|
('Show quality monitor', kOptionShowQualityMonitor),
|
||||||
('Mute', kOptionDisableAudio),
|
('Mute', kOptionDisableAudio),
|
||||||
if (isDesktop) ('Enable file copy and paste', kOptionEnableFileTransfer),
|
if (isDesktop)
|
||||||
|
('Enable file copy and paste', kOptionEnableFileCopyPaste),
|
||||||
('Disable clipboard', kOptionDisableClipboard),
|
('Disable clipboard', kOptionDisableClipboard),
|
||||||
('Lock after session end', kOptionLockAfterSessionEnd),
|
('Lock after session end', kOptionLockAfterSessionEnd),
|
||||||
('Privacy mode', kOptionPrivacyMode),
|
('Privacy mode', kOptionPrivacyMode),
|
||||||
|
@ -534,15 +534,15 @@ Future<List<TToggleMenu>> toolbarDisplayToggle(
|
|||||||
perms['file'] != false &&
|
perms['file'] != false &&
|
||||||
(isSupportIfPeer_1_2_3 || isSupportIfPeer_1_2_4)) {
|
(isSupportIfPeer_1_2_3 || isSupportIfPeer_1_2_4)) {
|
||||||
final enabled = !ffiModel.viewOnly;
|
final enabled = !ffiModel.viewOnly;
|
||||||
final option = 'enable-file-transfer';
|
final value = bind.sessionGetToggleOptionSync(
|
||||||
final value =
|
sessionId: sessionId, arg: kOptionEnableFileCopyPaste);
|
||||||
bind.sessionGetToggleOptionSync(sessionId: sessionId, arg: option);
|
|
||||||
v.add(TToggleMenu(
|
v.add(TToggleMenu(
|
||||||
value: value,
|
value: value,
|
||||||
onChanged: enabled
|
onChanged: enabled
|
||||||
? (value) {
|
? (value) {
|
||||||
if (value == null) return;
|
if (value == null) return;
|
||||||
bind.sessionToggleOption(sessionId: sessionId, value: option);
|
bind.sessionToggleOption(
|
||||||
|
sessionId: sessionId, value: kOptionEnableFileCopyPaste);
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
child: Text(translate('Enable file copy and paste'))));
|
child: Text(translate('Enable file copy and paste'))));
|
||||||
|
@ -107,14 +107,27 @@ const String kOptionFollowRemoteWindow = "follow_remote_window";
|
|||||||
const String kOptionZoomCursor = "zoom-cursor";
|
const String kOptionZoomCursor = "zoom-cursor";
|
||||||
const String kOptionShowQualityMonitor = "show_quality_monitor";
|
const String kOptionShowQualityMonitor = "show_quality_monitor";
|
||||||
const String kOptionDisableAudio = "disable_audio";
|
const String kOptionDisableAudio = "disable_audio";
|
||||||
|
const String kOptionEnableFileCopyPaste = "enable-file-copy-paste";
|
||||||
// "Settings -> Display -> Other default options"
|
// "Settings -> Display -> Other default options"
|
||||||
const String kOptionDisableClipboard = "disable_clipboard";
|
const String kOptionDisableClipboard = "disable_clipboard";
|
||||||
const String kOptionLockAfterSessionEnd = "lock_after_session_end";
|
const String kOptionLockAfterSessionEnd = "lock_after_session_end";
|
||||||
const String kOptionPrivacyMode = "privacy_mode";
|
const String kOptionPrivacyMode = "privacy_mode";
|
||||||
const String kOptionTouchMode = "touch-mode";
|
const String kOptionTouchMode = "touch-mode";
|
||||||
const String kOptionI444 = "i444";
|
const String kOptionI444 = "i444";
|
||||||
const String kOptionSwapLeftRightMouse = 'swap-left-right-mouse';
|
const String kOptionSwapLeftRightMouse = "swap-left-right-mouse";
|
||||||
const String kOptionCodecPreference = 'codec-preference';
|
const String kOptionCodecPreference = "codec-preference";
|
||||||
|
const String kOptionRemoteMenubarDragLeft = "remote-menubar-drag-left";
|
||||||
|
const String kOptionRemoteMenubarDragRight = "remote-menubar-drag-right";
|
||||||
|
const String kOptionHideAbTagsPanel = "hideAbTagsPanel";
|
||||||
|
const String kOptionRemoteMenubarState = "remoteMenubarState";
|
||||||
|
const String kOptionPeerSorting = "peer-sorting";
|
||||||
|
const String kOptionPeerTabIndex = "peer-tab-index";
|
||||||
|
const String kOptionPeerTabOrder = "peer-tab-order";
|
||||||
|
const String kOptionPeerTabVisible = "peer-tab-visible";
|
||||||
|
const String kOptionPeerCardUiType = "peer-card-ui-type";
|
||||||
|
const String kOptionCurrentAbName = "current-ab-name";
|
||||||
|
|
||||||
|
const String kOptionToggleViewOnly = "view-only";
|
||||||
|
|
||||||
const String kUrlActionClose = "close";
|
const String kUrlActionClose = "close";
|
||||||
|
|
||||||
|
@ -377,7 +377,7 @@ class _GeneralState extends State<_General> {
|
|||||||
_OptionCheckBox(context, 'Confirm before closing multiple tabs',
|
_OptionCheckBox(context, 'Confirm before closing multiple tabs',
|
||||||
'enable-confirm-closing-tabs',
|
'enable-confirm-closing-tabs',
|
||||||
isServer: false),
|
isServer: false),
|
||||||
_OptionCheckBox(context, 'Adaptive bitrate', 'enable-abr'),
|
_OptionCheckBox(context, 'Adaptive bitrate', kOptionEnableAbr),
|
||||||
wallpaper(),
|
wallpaper(),
|
||||||
if (!bind.isIncomingOnly()) ...[
|
if (!bind.isIncomingOnly()) ...[
|
||||||
_OptionCheckBox(
|
_OptionCheckBox(
|
||||||
@ -456,9 +456,9 @@ class _GeneralState extends State<_General> {
|
|||||||
_OptionCheckBox(
|
_OptionCheckBox(
|
||||||
context,
|
context,
|
||||||
'Enable hardware codec',
|
'Enable hardware codec',
|
||||||
'enable-hwcodec',
|
kOptionEnableHwcodec,
|
||||||
update: () {
|
update: () {
|
||||||
if (mainGetBoolOptionSync('enable-hwcodec')) {
|
if (mainGetBoolOptionSync(kOptionEnableHwcodec)) {
|
||||||
bind.mainCheckHwcodec();
|
bind.mainCheckHwcodec();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -510,7 +510,7 @@ class _GeneralState extends State<_General> {
|
|||||||
bool user_dir_exists = map['user_dir_exists']!;
|
bool user_dir_exists = map['user_dir_exists']!;
|
||||||
return _Card(title: 'Recording', children: [
|
return _Card(title: 'Recording', children: [
|
||||||
_OptionCheckBox(context, 'Automatically record incoming sessions',
|
_OptionCheckBox(context, 'Automatically record incoming sessions',
|
||||||
'allow-auto-record-incoming'),
|
kOptionAllowAutoRecordIncoming),
|
||||||
if (showRootDir)
|
if (showRootDir)
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
@ -705,7 +705,7 @@ class _SafetyState extends State<_Safety> with AutomaticKeepAliveClientMixin {
|
|||||||
bool enabled = !locked;
|
bool enabled = !locked;
|
||||||
// Simple temp wrapper for PR check
|
// Simple temp wrapper for PR check
|
||||||
tmpWrapper() {
|
tmpWrapper() {
|
||||||
String accessMode = bind.mainGetOptionSync(key: 'access-mode');
|
String accessMode = bind.mainGetOptionSync(key: kOptionAccessMode);
|
||||||
_AccessMode mode;
|
_AccessMode mode;
|
||||||
if (accessMode == 'full') {
|
if (accessMode == 'full') {
|
||||||
mode = _AccessMode.full;
|
mode = _AccessMode.full;
|
||||||
@ -1347,14 +1347,14 @@ class _DisplayState extends State<_Display> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget imageQuality(BuildContext context) {
|
Widget imageQuality(BuildContext context) {
|
||||||
final key = 'image_quality';
|
|
||||||
onChanged(String value) async {
|
onChanged(String value) async {
|
||||||
await bind.mainSetUserDefaultOption(key: key, value: value);
|
await bind.mainSetUserDefaultOption(
|
||||||
|
key: kOptionImageQuality, value: value);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
|
||||||
final isOptFixed = isOptionFixed(key);
|
final isOptFixed = isOptionFixed(kOptionImageQuality);
|
||||||
final groupValue = bind.mainGetUserDefaultOption(key: key);
|
final groupValue = bind.mainGetUserDefaultOption(key: kOptionImageQuality);
|
||||||
return _Card(title: 'Default Image Quality', children: [
|
return _Card(title: 'Default Image Quality', children: [
|
||||||
_Radio(context,
|
_Radio(context,
|
||||||
value: kRemoteImageQualityBest,
|
value: kRemoteImageQualityBest,
|
||||||
@ -1484,7 +1484,7 @@ class _DisplayState extends State<_Display> {
|
|||||||
key: key,
|
key: key,
|
||||||
value: b
|
value: b
|
||||||
? 'Y'
|
? 'Y'
|
||||||
: (key == kOptionEnableFileTransfer ? 'N' : defaultOptionNo));
|
: (key == kOptionEnableFileCopyPaste ? 'N' : defaultOptionNo));
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
|
|
||||||
void _initStates(String id) {
|
void _initStates(String id) {
|
||||||
initSharedStates(id);
|
initSharedStates(id);
|
||||||
_zoomCursor = PeerBoolOption.find(id, 'zoom-cursor');
|
_zoomCursor = PeerBoolOption.find(id, kOptionZoomCursor);
|
||||||
_showRemoteCursor = ShowRemoteCursorState.find(id);
|
_showRemoteCursor = ShowRemoteCursorState.find(id);
|
||||||
_keyboardEnabled = KeyboardEnabledState.find(id);
|
_keyboardEnabled = KeyboardEnabledState.find(id);
|
||||||
_remoteCursorMoved = RemoteCursorMovedState.find(id);
|
_remoteCursorMoved = RemoteCursorMovedState.find(id);
|
||||||
@ -136,7 +136,7 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
_showRemoteCursor.value = bind.sessionGetToggleOptionSync(
|
_showRemoteCursor.value = bind.sessionGetToggleOptionSync(
|
||||||
sessionId: sessionId, arg: 'show-remote-cursor');
|
sessionId: sessionId, arg: 'show-remote-cursor');
|
||||||
_zoomCursor.value = bind.sessionGetToggleOptionSync(
|
_zoomCursor.value = bind.sessionGetToggleOptionSync(
|
||||||
sessionId: sessionId, arg: 'zoom-cursor');
|
sessionId: sessionId, arg: kOptionZoomCursor);
|
||||||
DesktopMultiWindow.addListener(this);
|
DesktopMultiWindow.addListener(this);
|
||||||
// if (!_isCustomCursorInited) {
|
// if (!_isCustomCursorInited) {
|
||||||
// customCursorController.registerNeedUpdateCursorCallback(
|
// customCursorController.registerNeedUpdateCursorCallback(
|
||||||
|
@ -341,9 +341,10 @@ class PopupMenuItemState<T, W extends PopupMenuItem<T>> extends State<W> {
|
|||||||
@protected
|
@protected
|
||||||
void handleTap() {
|
void handleTap() {
|
||||||
widget.onTap?.call();
|
widget.onTap?.call();
|
||||||
|
if (Navigator.canPop(context)) {
|
||||||
Navigator.pop<T>(context, widget.value);
|
Navigator.pop<T>(context, widget.value);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -445,6 +445,8 @@ abstract class MenuEntrySwitchBase<T> extends MenuEntryBase<T> {
|
|||||||
dismissCallback: dismissCallback,
|
dismissCallback: dismissCallback,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
bool get isEnabled => enabled?.value ?? true;
|
||||||
|
|
||||||
RxBool get curOption;
|
RxBool get curOption;
|
||||||
Future<void> setOption(bool? option);
|
Future<void> setOption(bool? option);
|
||||||
|
|
||||||
@ -481,7 +483,8 @@ abstract class MenuEntrySwitchBase<T> extends MenuEntryBase<T> {
|
|||||||
if (switchType == SwitchType.sswitch) {
|
if (switchType == SwitchType.sswitch) {
|
||||||
return Switch(
|
return Switch(
|
||||||
value: curOption.value,
|
value: curOption.value,
|
||||||
onChanged: (v) {
|
onChanged: isEnabled
|
||||||
|
? (v) {
|
||||||
if (super.dismissOnClicked &&
|
if (super.dismissOnClicked &&
|
||||||
Navigator.canPop(context)) {
|
Navigator.canPop(context)) {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
@ -490,12 +493,14 @@ abstract class MenuEntrySwitchBase<T> extends MenuEntryBase<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
setOption(v);
|
setOption(v);
|
||||||
},
|
}
|
||||||
|
: null,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return Checkbox(
|
return Checkbox(
|
||||||
value: curOption.value,
|
value: curOption.value,
|
||||||
onChanged: (v) {
|
onChanged: isEnabled
|
||||||
|
? (v) {
|
||||||
if (super.dismissOnClicked &&
|
if (super.dismissOnClicked &&
|
||||||
Navigator.canPop(context)) {
|
Navigator.canPop(context)) {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
@ -504,13 +509,15 @@ abstract class MenuEntrySwitchBase<T> extends MenuEntryBase<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
setOption(v);
|
setOption(v);
|
||||||
},
|
}
|
||||||
|
: null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
})),
|
})),
|
||||||
))
|
))
|
||||||
])),
|
])),
|
||||||
onPressed: () {
|
onPressed: isEnabled
|
||||||
|
? () {
|
||||||
if (super.dismissOnClicked && Navigator.canPop(context)) {
|
if (super.dismissOnClicked && Navigator.canPop(context)) {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
if (super.dismissCallback != null) {
|
if (super.dismissCallback != null) {
|
||||||
@ -518,7 +525,8 @@ abstract class MenuEntrySwitchBase<T> extends MenuEntryBase<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
setOption(!curOption.value);
|
setOption(!curOption.value);
|
||||||
},
|
}
|
||||||
|
: null,
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
];
|
];
|
||||||
|
@ -27,12 +27,11 @@ import './popup_menu.dart';
|
|||||||
import './kb_layout_type_chooser.dart';
|
import './kb_layout_type_chooser.dart';
|
||||||
|
|
||||||
class ToolbarState {
|
class ToolbarState {
|
||||||
final kStoreKey = 'remoteMenubarState';
|
|
||||||
late RxBool show;
|
late RxBool show;
|
||||||
late RxBool _pin;
|
late RxBool _pin;
|
||||||
|
|
||||||
ToolbarState() {
|
ToolbarState() {
|
||||||
final s = bind.getLocalFlutterOption(k: kStoreKey);
|
final s = bind.getLocalFlutterOption(k: kOptionRemoteMenubarState);
|
||||||
if (s.isEmpty) {
|
if (s.isEmpty) {
|
||||||
_initSet(false, false);
|
_initSet(false, false);
|
||||||
return;
|
return;
|
||||||
@ -53,8 +52,8 @@ class ToolbarState {
|
|||||||
|
|
||||||
_initSet(bool s, bool p) {
|
_initSet(bool s, bool p) {
|
||||||
// Show remubar when connection is established.
|
// Show remubar when connection is established.
|
||||||
show =
|
show = RxBool(
|
||||||
RxBool(bind.mainGetUserDefaultOption(key: kOptionCollapseToolbar) != 'Y');
|
bind.mainGetUserDefaultOption(key: kOptionCollapseToolbar) != 'Y');
|
||||||
_pin = RxBool(p);
|
_pin = RxBool(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +85,7 @@ class ToolbarState {
|
|||||||
|
|
||||||
_savePin() async {
|
_savePin() async {
|
||||||
bind.setLocalFlutterOption(
|
bind.setLocalFlutterOption(
|
||||||
k: kStoreKey, v: jsonEncode({'pin': _pin.value}));
|
k: kOptionRemoteMenubarState, v: jsonEncode({'pin': _pin.value}));
|
||||||
}
|
}
|
||||||
|
|
||||||
save() async {
|
save() async {
|
||||||
@ -1875,7 +1874,7 @@ class _KeyboardMenu extends StatelessWidget {
|
|||||||
? (value) async {
|
? (value) async {
|
||||||
if (value == null) return;
|
if (value == null) return;
|
||||||
await bind.sessionToggleOption(
|
await bind.sessionToggleOption(
|
||||||
sessionId: ffi.sessionId, value: kOptionViewOnly);
|
sessionId: ffi.sessionId, value: kOptionToggleViewOnly);
|
||||||
ffiModel.setViewOnly(id, value);
|
ffiModel.setViewOnly(id, value);
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
@ -2019,6 +2018,7 @@ class _VoiceCallMenu extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _RecordMenu extends StatelessWidget {
|
class _RecordMenu extends StatelessWidget {
|
||||||
const _RecordMenu({Key? key}) : super(key: key);
|
const _RecordMenu({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@ -2372,18 +2372,18 @@ class _DraggableShowHideState extends State<_DraggableShowHide> {
|
|||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
final confLeft = double.tryParse(
|
final confLeft = double.tryParse(
|
||||||
bind.mainGetLocalOption(key: 'remote-menubar-drag-left'));
|
bind.mainGetLocalOption(key: kOptionRemoteMenubarDragLeft));
|
||||||
if (confLeft == null) {
|
if (confLeft == null) {
|
||||||
bind.mainSetLocalOption(
|
bind.mainSetLocalOption(
|
||||||
key: 'remote-menubar-drag-left', value: left.toString());
|
key: kOptionRemoteMenubarDragLeft, value: left.toString());
|
||||||
} else {
|
} else {
|
||||||
left = confLeft;
|
left = confLeft;
|
||||||
}
|
}
|
||||||
final confRight = double.tryParse(
|
final confRight = double.tryParse(
|
||||||
bind.mainGetLocalOption(key: 'remote-menubar-drag-right'));
|
bind.mainGetLocalOption(key: kOptionRemoteMenubarDragRight));
|
||||||
if (confRight == null) {
|
if (confRight == null) {
|
||||||
bind.mainSetLocalOption(
|
bind.mainSetLocalOption(
|
||||||
key: 'remote-menubar-drag-right', value: right.toString());
|
key: kOptionRemoteMenubarDragRight, value: right.toString());
|
||||||
} else {
|
} else {
|
||||||
right = confRight;
|
right = confRight;
|
||||||
}
|
}
|
||||||
|
@ -323,11 +323,11 @@ class DesktopTab extends StatelessWidget {
|
|||||||
return buildRemoteBlock(
|
return buildRemoteBlock(
|
||||||
child: child,
|
child: child,
|
||||||
use: () async {
|
use: () async {
|
||||||
var access_mode = await bind.mainGetOption(key: 'access-mode');
|
var access_mode = await bind.mainGetOption(key: kOptionAccessMode);
|
||||||
var option = option2bool(
|
var option = option2bool(
|
||||||
'allow-remote-config-modification',
|
kOptionAllowRemoteConfigModification,
|
||||||
await bind.mainGetOption(
|
await bind.mainGetOption(
|
||||||
key: 'allow-remote-config-modification'));
|
key: kOptionAllowRemoteConfigModification));
|
||||||
return access_mode == 'view' || (access_mode.isEmpty && !option);
|
return access_mode == 'view' || (access_mode.isEmpty && !option);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -638,7 +638,7 @@ class _RemotePageState extends State<RemotePage> {
|
|||||||
gFFI.ffiModel.toggleTouchMode();
|
gFFI.ffiModel.toggleTouchMode();
|
||||||
final v = gFFI.ffiModel.touchMode ? 'Y' : '';
|
final v = gFFI.ffiModel.touchMode ? 'Y' : '';
|
||||||
bind.sessionPeerOption(
|
bind.sessionPeerOption(
|
||||||
sessionId: sessionId, name: "touch-mode", value: v);
|
sessionId: sessionId, name: kOptionTouchMode, value: v);
|
||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ class ServerPage extends StatefulWidget implements PageShape {
|
|||||||
} else if (value == kUsePermanentPassword ||
|
} else if (value == kUsePermanentPassword ||
|
||||||
value == kUseTemporaryPassword ||
|
value == kUseTemporaryPassword ||
|
||||||
value == kUseBothPasswords) {
|
value == kUseBothPasswords) {
|
||||||
bind.mainSetOption(key: "verification-method", value: value);
|
bind.mainSetOption(key: kOptionVerificationMethod, value: value);
|
||||||
gFFI.serverModel.updatePasswordModel();
|
gFFI.serverModel.updatePasswordModel();
|
||||||
} else if (value.startsWith("AcceptSessionsVia")) {
|
} else if (value.startsWith("AcceptSessionsVia")) {
|
||||||
value = value.substring("AcceptSessionsVia".length);
|
value = value.substring("AcceptSessionsVia".length);
|
||||||
|
@ -87,7 +87,7 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final enableAbrRes = option2bool(
|
final enableAbrRes = option2bool(
|
||||||
"enable-abr", await bind.mainGetOption(key: "enable-abr"));
|
kOptionEnableAbr, await bind.mainGetOption(key: kOptionEnableAbr));
|
||||||
if (enableAbrRes != _enableAbr) {
|
if (enableAbrRes != _enableAbr) {
|
||||||
update = true;
|
update = true;
|
||||||
_enableAbr = enableAbrRes;
|
_enableAbr = enableAbrRes;
|
||||||
@ -107,30 +107,30 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
|||||||
_onlyWhiteList = onlyWhiteList;
|
_onlyWhiteList = onlyWhiteList;
|
||||||
}
|
}
|
||||||
|
|
||||||
final enableDirectIPAccess = option2bool(
|
final enableDirectIPAccess = option2bool(kOptionDirectServer,
|
||||||
'direct-server', await bind.mainGetOption(key: 'direct-server'));
|
await bind.mainGetOption(key: kOptionDirectServer));
|
||||||
if (enableDirectIPAccess != _enableDirectIPAccess) {
|
if (enableDirectIPAccess != _enableDirectIPAccess) {
|
||||||
update = true;
|
update = true;
|
||||||
_enableDirectIPAccess = enableDirectIPAccess;
|
_enableDirectIPAccess = enableDirectIPAccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
final enableRecordSession = option2bool('enable-record-session',
|
final enableRecordSession = option2bool(kOptionEnableRecordSession,
|
||||||
await bind.mainGetOption(key: 'enable-record-session'));
|
await bind.mainGetOption(key: kOptionEnableRecordSession));
|
||||||
if (enableRecordSession != _enableRecordSession) {
|
if (enableRecordSession != _enableRecordSession) {
|
||||||
update = true;
|
update = true;
|
||||||
_enableRecordSession = enableRecordSession;
|
_enableRecordSession = enableRecordSession;
|
||||||
}
|
}
|
||||||
|
|
||||||
final enableHardwareCodec = option2bool(
|
final enableHardwareCodec = option2bool(kOptionEnableHwcodec,
|
||||||
'enable-hwcodec', await bind.mainGetOption(key: 'enable-hwcodec'));
|
await bind.mainGetOption(key: kOptionEnableHwcodec));
|
||||||
if (_enableHardwareCodec != enableHardwareCodec) {
|
if (_enableHardwareCodec != enableHardwareCodec) {
|
||||||
update = true;
|
update = true;
|
||||||
_enableHardwareCodec = enableHardwareCodec;
|
_enableHardwareCodec = enableHardwareCodec;
|
||||||
}
|
}
|
||||||
|
|
||||||
final autoRecordIncomingSession = option2bool(
|
final autoRecordIncomingSession = option2bool(
|
||||||
'allow-auto-record-incoming',
|
kOptionAllowAutoRecordIncoming,
|
||||||
await bind.mainGetOption(key: 'allow-auto-record-incoming'));
|
await bind.mainGetOption(key: kOptionAllowAutoRecordIncoming));
|
||||||
if (autoRecordIncomingSession != _autoRecordIncomingSession) {
|
if (autoRecordIncomingSession != _autoRecordIncomingSession) {
|
||||||
update = true;
|
update = true;
|
||||||
_autoRecordIncomingSession = autoRecordIncomingSession;
|
_autoRecordIncomingSession = autoRecordIncomingSession;
|
||||||
@ -161,15 +161,15 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
|||||||
_buildDate = buildDate;
|
_buildDate = buildDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
final allowAutoDisconnect = option2bool('allow-auto-disconnect',
|
final allowAutoDisconnect = option2bool(kOptionAllowAutoDisconnect,
|
||||||
await bind.mainGetOption(key: 'allow-auto-disconnect'));
|
await bind.mainGetOption(key: kOptionAllowAutoDisconnect));
|
||||||
if (allowAutoDisconnect != _allowAutoDisconnect) {
|
if (allowAutoDisconnect != _allowAutoDisconnect) {
|
||||||
update = true;
|
update = true;
|
||||||
_allowAutoDisconnect = allowAutoDisconnect;
|
_allowAutoDisconnect = allowAutoDisconnect;
|
||||||
}
|
}
|
||||||
|
|
||||||
final autoDisconnectTimeout =
|
final autoDisconnectTimeout =
|
||||||
await bind.mainGetOption(key: 'auto-disconnect-timeout');
|
await bind.mainGetOption(key: kOptionAutoDisconnectTimeout);
|
||||||
if (autoDisconnectTimeout != _autoDisconnectTimeout) {
|
if (autoDisconnectTimeout != _autoDisconnectTimeout) {
|
||||||
update = true;
|
update = true;
|
||||||
_autoDisconnectTimeout = autoDisconnectTimeout;
|
_autoDisconnectTimeout = autoDisconnectTimeout;
|
||||||
|
@ -5,6 +5,7 @@ import 'dart:io';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hbb/common/hbbs/hbbs.dart';
|
import 'package:flutter_hbb/common/hbbs/hbbs.dart';
|
||||||
import 'package:flutter_hbb/common/widgets/peers_view.dart';
|
import 'package:flutter_hbb/common/widgets/peers_view.dart';
|
||||||
|
import 'package:flutter_hbb/consts.dart';
|
||||||
import 'package:flutter_hbb/models/model.dart';
|
import 'package:flutter_hbb/models/model.dart';
|
||||||
import 'package:flutter_hbb/models/peer_model.dart';
|
import 'package:flutter_hbb/models/peer_model.dart';
|
||||||
import 'package:flutter_hbb/models/platform_model.dart';
|
import 'package:flutter_hbb/models/platform_model.dart';
|
||||||
@ -548,7 +549,7 @@ class AbModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
trySetCurrentToLast() {
|
trySetCurrentToLast() {
|
||||||
final name = bind.getLocalFlutterOption(k: 'current-ab-name');
|
final name = bind.getLocalFlutterOption(k: kOptionCurrentAbName);
|
||||||
if (addressbooks.containsKey(name)) {
|
if (addressbooks.containsKey(name)) {
|
||||||
_currentName.value = name;
|
_currentName.value = name;
|
||||||
}
|
}
|
||||||
|
@ -389,7 +389,7 @@ class FfiModel with ChangeNotifier {
|
|||||||
_handleSyncPeerOption(Map<String, dynamic> evt, String peer) {
|
_handleSyncPeerOption(Map<String, dynamic> evt, String peer) {
|
||||||
final k = evt['k'];
|
final k = evt['k'];
|
||||||
final v = evt['v'];
|
final v = evt['v'];
|
||||||
if (k == kOptionViewOnly) {
|
if (k == kOptionToggleViewOnly) {
|
||||||
setViewOnly(peer, v as bool);
|
setViewOnly(peer, v as bool);
|
||||||
} else if (k == 'keyboard_mode') {
|
} else if (k == 'keyboard_mode') {
|
||||||
parent.target?.inputModel.updateKeyboardMode();
|
parent.target?.inputModel.updateKeyboardMode();
|
||||||
@ -765,7 +765,7 @@ class FfiModel with ChangeNotifier {
|
|||||||
_touchMode = true;
|
_touchMode = true;
|
||||||
} else {
|
} else {
|
||||||
_touchMode = await bind.sessionGetOption(
|
_touchMode = await bind.sessionGetOption(
|
||||||
sessionId: sessionId, arg: 'touch-mode') !=
|
sessionId: sessionId, arg: kOptionTouchMode) !=
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
if (connType == ConnType.fileTransfer) {
|
if (connType == ConnType.fileTransfer) {
|
||||||
@ -797,7 +797,7 @@ class FfiModel with ChangeNotifier {
|
|||||||
setViewOnly(
|
setViewOnly(
|
||||||
peerId,
|
peerId,
|
||||||
bind.sessionGetToggleOptionSync(
|
bind.sessionGetToggleOptionSync(
|
||||||
sessionId: sessionId, arg: kOptionViewOnly));
|
sessionId: sessionId, arg: kOptionToggleViewOnly));
|
||||||
}
|
}
|
||||||
if (connType == ConnType.defaultConn) {
|
if (connType == ConnType.defaultConn) {
|
||||||
final platformAdditions = evt['platform_additions'];
|
final platformAdditions = evt['platform_additions'];
|
||||||
|
@ -2,6 +2,7 @@ import 'dart:convert';
|
|||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hbb/consts.dart';
|
||||||
import 'package:flutter_hbb/models/peer_model.dart';
|
import 'package:flutter_hbb/models/peer_model.dart';
|
||||||
import 'package:flutter_hbb/models/platform_model.dart';
|
import 'package:flutter_hbb/models/platform_model.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
@ -22,9 +23,6 @@ class PeerTabModel with ChangeNotifier {
|
|||||||
int get currentTab => _currentTab;
|
int get currentTab => _currentTab;
|
||||||
int _currentTab = 0; // index in tabNames
|
int _currentTab = 0; // index in tabNames
|
||||||
static const int maxTabCount = 5;
|
static const int maxTabCount = 5;
|
||||||
static const String kPeerTabIndex = 'peer-tab-index';
|
|
||||||
static const String kPeerTabOrder = 'peer-tab-order';
|
|
||||||
static const String kPeerTabVisible = 'peer-tab-visible';
|
|
||||||
static const List<String> tabNames = [
|
static const List<String> tabNames = [
|
||||||
'Recent sessions',
|
'Recent sessions',
|
||||||
'Favorites',
|
'Favorites',
|
||||||
@ -72,7 +70,7 @@ class PeerTabModel with ChangeNotifier {
|
|||||||
PeerTabModel(this.parent) {
|
PeerTabModel(this.parent) {
|
||||||
// visible
|
// visible
|
||||||
try {
|
try {
|
||||||
final option = bind.getLocalFlutterOption(k: kPeerTabVisible);
|
final option = bind.getLocalFlutterOption(k: kOptionPeerTabVisible);
|
||||||
if (option.isNotEmpty) {
|
if (option.isNotEmpty) {
|
||||||
List<dynamic> decodeList = jsonDecode(option);
|
List<dynamic> decodeList = jsonDecode(option);
|
||||||
if (decodeList.length == _isVisible.length) {
|
if (decodeList.length == _isVisible.length) {
|
||||||
@ -88,7 +86,7 @@ class PeerTabModel with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
// order
|
// order
|
||||||
try {
|
try {
|
||||||
final option = bind.getLocalFlutterOption(k: kPeerTabOrder);
|
final option = bind.getLocalFlutterOption(k: kOptionPeerTabOrder);
|
||||||
if (option.isNotEmpty) {
|
if (option.isNotEmpty) {
|
||||||
List<dynamic> decodeList = jsonDecode(option);
|
List<dynamic> decodeList = jsonDecode(option);
|
||||||
if (decodeList.length == maxTabCount) {
|
if (decodeList.length == maxTabCount) {
|
||||||
@ -112,7 +110,7 @@ class PeerTabModel with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
// init currentTab
|
// init currentTab
|
||||||
_currentTab =
|
_currentTab =
|
||||||
int.tryParse(bind.getLocalFlutterOption(k: kPeerTabIndex)) ?? 0;
|
int.tryParse(bind.getLocalFlutterOption(k: kOptionPeerTabIndex)) ?? 0;
|
||||||
if (_currentTab < 0 || _currentTab >= maxTabCount) {
|
if (_currentTab < 0 || _currentTab >= maxTabCount) {
|
||||||
_currentTab = 0;
|
_currentTab = 0;
|
||||||
}
|
}
|
||||||
@ -222,7 +220,7 @@ class PeerTabModel with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
bind.setLocalFlutterOption(
|
bind.setLocalFlutterOption(
|
||||||
k: kPeerTabVisible, v: jsonEncode(_isVisible));
|
k: kOptionPeerTabVisible, v: jsonEncode(_isVisible));
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
@ -258,7 +256,7 @@ class PeerTabModel with ChangeNotifier {
|
|||||||
for (int i = 0; i < list.length; i++) {
|
for (int i = 0; i < list.length; i++) {
|
||||||
orders[i] = list[i];
|
orders[i] = list[i];
|
||||||
}
|
}
|
||||||
bind.setLocalFlutterOption(k: kPeerTabOrder, v: jsonEncode(orders));
|
bind.setLocalFlutterOption(k: kOptionPeerTabOrder, v: jsonEncode(orders));
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,8 +125,8 @@ class ServerModel with ChangeNotifier {
|
|||||||
/*
|
/*
|
||||||
// initital _hideCm at startup
|
// initital _hideCm at startup
|
||||||
final verificationMethod =
|
final verificationMethod =
|
||||||
bind.mainGetOptionSync(key: "verification-method");
|
bind.mainGetOptionSync(key: kOptionVerificationMethod);
|
||||||
final approveMode = bind.mainGetOptionSync(key: 'approve-mode');
|
final approveMode = bind.mainGetOptionSync(key: kOptionApproveMode);
|
||||||
_hideCm = option2bool(
|
_hideCm = option2bool(
|
||||||
'allow-hide-cm', bind.mainGetOptionSync(key: 'allow-hide-cm'));
|
'allow-hide-cm', bind.mainGetOptionSync(key: 'allow-hide-cm'));
|
||||||
if (!(approveMode == 'password' &&
|
if (!(approveMode == 'password' &&
|
||||||
@ -187,18 +187,19 @@ class ServerModel with ChangeNotifier {
|
|||||||
if (androidVersion < 30 ||
|
if (androidVersion < 30 ||
|
||||||
!await AndroidPermissionManager.check(kRecordAudio)) {
|
!await AndroidPermissionManager.check(kRecordAudio)) {
|
||||||
_audioOk = false;
|
_audioOk = false;
|
||||||
bind.mainSetOption(key: "enable-audio", value: "N");
|
bind.mainSetOption(key: kOptionEnableAudio, value: "N");
|
||||||
} else {
|
} else {
|
||||||
final audioOption = await bind.mainGetOption(key: 'enable-audio');
|
final audioOption = await bind.mainGetOption(key: kOptionEnableAudio);
|
||||||
_audioOk = audioOption.isEmpty;
|
_audioOk = audioOption.isEmpty;
|
||||||
}
|
}
|
||||||
|
|
||||||
// file
|
// file
|
||||||
if (!await AndroidPermissionManager.check(kManageExternalStorage)) {
|
if (!await AndroidPermissionManager.check(kManageExternalStorage)) {
|
||||||
_fileOk = false;
|
_fileOk = false;
|
||||||
bind.mainSetOption(key: "enable-file-transfer", value: "N");
|
bind.mainSetOption(key: kOptionEnableFileTransfer, value: "N");
|
||||||
} else {
|
} else {
|
||||||
final fileOption = await bind.mainGetOption(key: 'enable-file-transfer');
|
final fileOption =
|
||||||
|
await bind.mainGetOption(key: kOptionEnableFileTransfer);
|
||||||
_fileOk = fileOption.isEmpty;
|
_fileOk = fileOption.isEmpty;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,10 +210,10 @@ class ServerModel with ChangeNotifier {
|
|||||||
var update = false;
|
var update = false;
|
||||||
final temporaryPassword = await bind.mainGetTemporaryPassword();
|
final temporaryPassword = await bind.mainGetTemporaryPassword();
|
||||||
final verificationMethod =
|
final verificationMethod =
|
||||||
await bind.mainGetOption(key: "verification-method");
|
await bind.mainGetOption(key: kOptionVerificationMethod);
|
||||||
final temporaryPasswordLength =
|
final temporaryPasswordLength =
|
||||||
await bind.mainGetOption(key: "temporary-password-length");
|
await bind.mainGetOption(key: "temporary-password-length");
|
||||||
final approveMode = await bind.mainGetOption(key: 'approve-mode');
|
final approveMode = await bind.mainGetOption(key: kOptionApproveMode);
|
||||||
/*
|
/*
|
||||||
var hideCm = option2bool(
|
var hideCm = option2bool(
|
||||||
'allow-hide-cm', await bind.mainGetOption(key: 'allow-hide-cm'));
|
'allow-hide-cm', await bind.mainGetOption(key: 'allow-hide-cm'));
|
||||||
@ -283,7 +284,8 @@ class ServerModel with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_audioOk = !_audioOk;
|
_audioOk = !_audioOk;
|
||||||
bind.mainSetOption(key: "enable-audio", value: _audioOk ? defaultOptionYes : 'N');
|
bind.mainSetOption(
|
||||||
|
key: kOptionEnableAudio, value: _audioOk ? defaultOptionYes : 'N');
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,7 +304,9 @@ class ServerModel with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_fileOk = !_fileOk;
|
_fileOk = !_fileOk;
|
||||||
bind.mainSetOption(key: kOptionEnableFileTransfer, value: _fileOk ? defaultOptionYes : 'N');
|
bind.mainSetOption(
|
||||||
|
key: kOptionEnableFileTransfer,
|
||||||
|
value: _fileOk ? defaultOptionYes : 'N');
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,7 +449,9 @@ class ServerModel with ChangeNotifier {
|
|||||||
break;
|
break;
|
||||||
case "input":
|
case "input":
|
||||||
if (_inputOk != value) {
|
if (_inputOk != value) {
|
||||||
bind.mainSetOption(key: kOptionEnableKeyboard, value: value ? defaultOptionYes : 'N');
|
bind.mainSetOption(
|
||||||
|
key: kOptionEnableKeyboard,
|
||||||
|
value: value ? defaultOptionYes : 'N');
|
||||||
}
|
}
|
||||||
_inputOk = value;
|
_inputOk = value;
|
||||||
break;
|
break;
|
||||||
|
@ -660,7 +660,7 @@ export default class Connection {
|
|||||||
const defaultToggleTrue = [
|
const defaultToggleTrue = [
|
||||||
'show-remote-cursor',
|
'show-remote-cursor',
|
||||||
'privacy-mode',
|
'privacy-mode',
|
||||||
'enable-file-transfer',
|
'enable-file-copy-paste',
|
||||||
'allow_swap_key',
|
'allow_swap_key',
|
||||||
];
|
];
|
||||||
return this._options[name] || (defaultToggleTrue.includes(name) ? true : false);
|
return this._options[name] || (defaultToggleTrue.includes(name) ? true : false);
|
||||||
@ -906,7 +906,7 @@ export default class Connection {
|
|||||||
case "privacy-mode":
|
case "privacy-mode":
|
||||||
option.privacy_mode = v2;
|
option.privacy_mode = v2;
|
||||||
break;
|
break;
|
||||||
case "enable-file-transfer":
|
case "enable-file-copy-paste":
|
||||||
option.enable_file_transfer = v2;
|
option.enable_file_transfer = v2;
|
||||||
break;
|
break;
|
||||||
case "block-input":
|
case "block-input":
|
||||||
@ -933,7 +933,7 @@ export default class Connection {
|
|||||||
option.show_remote_cursor = this.getToggleOption("show-remote-cursor")
|
option.show_remote_cursor = this.getToggleOption("show-remote-cursor")
|
||||||
? message.OptionMessage_BoolOption.Yes
|
? message.OptionMessage_BoolOption.Yes
|
||||||
: message.OptionMessage_BoolOption.No;
|
: message.OptionMessage_BoolOption.No;
|
||||||
option.enable_file_transfer = this.getToggleOption("enable-file-transfer")
|
option.enable_file_transfer = this.getToggleOption("enable-file-copy-paste")
|
||||||
? message.OptionMessage_BoolOption.Yes
|
? message.OptionMessage_BoolOption.Yes
|
||||||
: message.OptionMessage_BoolOption.No;
|
: message.OptionMessage_BoolOption.No;
|
||||||
option.lock_after_session_end = this.getToggleOption("lock-after-session-end")
|
option.lock_after_session_end = this.getToggleOption("lock-after-session-end")
|
||||||
|
@ -40,10 +40,6 @@ const SERIAL: i32 = 3;
|
|||||||
const PASSWORD_ENC_VERSION: &str = "00";
|
const PASSWORD_ENC_VERSION: &str = "00";
|
||||||
const ENCRYPT_MAX_LEN: usize = 128;
|
const ENCRYPT_MAX_LEN: usize = 128;
|
||||||
|
|
||||||
// config2 options
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
pub const CONFIG_OPTION_ALLOW_LINUX_HEADLESS: &str = "allow-linux-headless";
|
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
pub static ref ORG: RwLock<String> = RwLock::new("com.carriez".to_owned());
|
pub static ref ORG: RwLock<String> = RwLock::new("com.carriez".to_owned());
|
||||||
@ -278,7 +274,7 @@ pub struct PeerConfig {
|
|||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub disable_clipboard: DisableClipboard,
|
pub disable_clipboard: DisableClipboard,
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub enable_file_transfer: EnableFileTransfer,
|
pub enable_file_copy_paste: EnableFileCopyPaste,
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub show_quality_monitor: ShowQualityMonitor,
|
pub show_quality_monitor: ShowQualityMonitor,
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
@ -355,7 +351,7 @@ impl Default for PeerConfig {
|
|||||||
direct_failures: Default::default(),
|
direct_failures: Default::default(),
|
||||||
disable_audio: Default::default(),
|
disable_audio: Default::default(),
|
||||||
disable_clipboard: Default::default(),
|
disable_clipboard: Default::default(),
|
||||||
enable_file_transfer: Default::default(),
|
enable_file_copy_paste: Default::default(),
|
||||||
show_quality_monitor: Default::default(),
|
show_quality_monitor: Default::default(),
|
||||||
follow_remote_cursor: Default::default(),
|
follow_remote_cursor: Default::default(),
|
||||||
follow_remote_window: Default::default(),
|
follow_remote_window: Default::default(),
|
||||||
@ -1289,11 +1285,13 @@ serde_field_bool!(
|
|||||||
default_disable_audio,
|
default_disable_audio,
|
||||||
"DisableAudio::default_disable_audio"
|
"DisableAudio::default_disable_audio"
|
||||||
);
|
);
|
||||||
|
// The key is enable_file_transfer, but no need to keep the old name.
|
||||||
|
// This option should always be true.
|
||||||
serde_field_bool!(
|
serde_field_bool!(
|
||||||
EnableFileTransfer,
|
EnableFileCopyPaste,
|
||||||
"enable_file_transfer",
|
"enable_file_copy_paste",
|
||||||
default_enable_file_transfer,
|
default_enable_file_copy_paste,
|
||||||
"EnableFileTransfer::default_enable_file_transfer"
|
"EnableFileCopyPaste::default_enable_file_copy_paste"
|
||||||
);
|
);
|
||||||
serde_field_bool!(
|
serde_field_bool!(
|
||||||
DisableClipboard,
|
DisableClipboard,
|
||||||
@ -1438,11 +1436,13 @@ impl LocalConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_flutter_option(k: &str) -> String {
|
pub fn get_flutter_option(k: &str) -> String {
|
||||||
if let Some(v) = LOCAL_CONFIG.read().unwrap().ui_flutter.get(k) {
|
get_or(
|
||||||
v.clone()
|
&OVERWRITE_LOCAL_SETTINGS,
|
||||||
} else {
|
&LOCAL_CONFIG.read().unwrap().ui_flutter,
|
||||||
"".to_owned()
|
&DEFAULT_LOCAL_SETTINGS,
|
||||||
}
|
k,
|
||||||
|
)
|
||||||
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_flutter_option(k: String, v: String) {
|
pub fn set_flutter_option(k: String, v: String) {
|
||||||
@ -1591,7 +1591,7 @@ impl UserDefaultConfig {
|
|||||||
self.get_double_string(key, 50.0, 10.0, 0xFFF as f64)
|
self.get_double_string(key, 50.0, 10.0, 0xFFF as f64)
|
||||||
}
|
}
|
||||||
keys::OPTION_CUSTOM_FPS => self.get_double_string(key, 30.0, 5.0, 120.0),
|
keys::OPTION_CUSTOM_FPS => self.get_double_string(key, 30.0, 5.0, 120.0),
|
||||||
keys::OPTION_ENABLE_FILE_TRANSFER => self.get_string(key, "Y", vec!["", "N"]),
|
keys::OPTION_ENABLE_FILE_COPY_PASTE => self.get_string(key, "Y", vec!["", "N"]),
|
||||||
_ => self
|
_ => self
|
||||||
.get_after(key)
|
.get_after(key)
|
||||||
.map(|v| v.to_string())
|
.map(|v| v.to_string())
|
||||||
@ -1992,6 +1992,7 @@ pub mod keys {
|
|||||||
pub const OPTION_ZOOM_CURSOR: &str = "zoom-cursor";
|
pub const OPTION_ZOOM_CURSOR: &str = "zoom-cursor";
|
||||||
pub const OPTION_SHOW_QUALITY_MONITOR: &str = "show_quality_monitor";
|
pub const OPTION_SHOW_QUALITY_MONITOR: &str = "show_quality_monitor";
|
||||||
pub const OPTION_DISABLE_AUDIO: &str = "disable_audio";
|
pub const OPTION_DISABLE_AUDIO: &str = "disable_audio";
|
||||||
|
pub const OPTION_ENABLE_FILE_COPY_PASTE: &str = "enable-file-copy-paste";
|
||||||
pub const OPTION_DISABLE_CLIPBOARD: &str = "disable_clipboard";
|
pub const OPTION_DISABLE_CLIPBOARD: &str = "disable_clipboard";
|
||||||
pub const OPTION_LOCK_AFTER_SESSION_END: &str = "lock_after_session_end";
|
pub const OPTION_LOCK_AFTER_SESSION_END: &str = "lock_after_session_end";
|
||||||
pub const OPTION_PRIVACY_MODE: &str = "privacy_mode";
|
pub const OPTION_PRIVACY_MODE: &str = "privacy_mode";
|
||||||
@ -2010,6 +2011,9 @@ pub mod keys {
|
|||||||
pub const OPTION_CODEC_PREFERENCE: &str = "codec-preference";
|
pub const OPTION_CODEC_PREFERENCE: &str = "codec-preference";
|
||||||
pub const OPTION_THEME: &str = "theme";
|
pub const OPTION_THEME: &str = "theme";
|
||||||
pub const OPTION_LANGUAGE: &str = "lang";
|
pub const OPTION_LANGUAGE: &str = "lang";
|
||||||
|
pub const OPTION_REMOTE_MENUBAR_DRAG_LEFT: &str = "remote-menubar-drag-left";
|
||||||
|
pub const OPTION_REMOTE_MENUBAR_DRAG_RIGHT: &str = "remote-menubar-drag-right";
|
||||||
|
pub const OPTION_HIDE_AB_TAGS_PANEL: &str = "hideAbTagsPanel";
|
||||||
pub const OPTION_ENABLE_CONFIRM_CLOSING_TABS: &str = "enable-confirm-closing-tabs";
|
pub const OPTION_ENABLE_CONFIRM_CLOSING_TABS: &str = "enable-confirm-closing-tabs";
|
||||||
pub const OPTION_ENABLE_OPEN_NEW_CONNECTIONS_IN_TABS: &str =
|
pub const OPTION_ENABLE_OPEN_NEW_CONNECTIONS_IN_TABS: &str =
|
||||||
"enable-open-new-connections-in-tabs";
|
"enable-open-new-connections-in-tabs";
|
||||||
@ -2043,6 +2047,15 @@ pub mod keys {
|
|||||||
pub const OPTION_ENABLE_HWCODEC: &str = "enable-hwcodec";
|
pub const OPTION_ENABLE_HWCODEC: &str = "enable-hwcodec";
|
||||||
pub const OPTION_APPROVE_MODE: &str = "approve-mode";
|
pub const OPTION_APPROVE_MODE: &str = "approve-mode";
|
||||||
|
|
||||||
|
// flutter local options
|
||||||
|
pub const OPTION_FLUTTER_REMOTE_MENUBAR_STATE: &str = "remoteMenubarState";
|
||||||
|
pub const OPTION_FLUTTER_PEER_SORTING: &str = "peer-sorting";
|
||||||
|
pub const OPTION_FLUTTER_PEER_TAB_INDEX: &str = "peer-tab-index";
|
||||||
|
pub const OPTION_FLUTTER_PEER_TAB_ORDER: &str = "peer-tab-order";
|
||||||
|
pub const OPTION_FLUTTER_PEER_TAB_VISIBLE: &str = "peer-tab-visible";
|
||||||
|
pub const OPTION_FLUTTER_PEER_CARD_UI_TYLE: &str = "peer-card-ui-type";
|
||||||
|
pub const OPTION_FLUTTER_CURRENT_AB_NAME: &str = "current-ab-name";
|
||||||
|
|
||||||
// DEFAULT_DISPLAY_SETTINGS, OVERWRITE_DISPLAY_SETTINGS
|
// DEFAULT_DISPLAY_SETTINGS, OVERWRITE_DISPLAY_SETTINGS
|
||||||
pub const KEYS_DISPLAY_SETTINGS: &[&str] = &[
|
pub const KEYS_DISPLAY_SETTINGS: &[&str] = &[
|
||||||
OPTION_VIEW_ONLY,
|
OPTION_VIEW_ONLY,
|
||||||
@ -2054,7 +2067,7 @@ pub mod keys {
|
|||||||
OPTION_ZOOM_CURSOR,
|
OPTION_ZOOM_CURSOR,
|
||||||
OPTION_SHOW_QUALITY_MONITOR,
|
OPTION_SHOW_QUALITY_MONITOR,
|
||||||
OPTION_DISABLE_AUDIO,
|
OPTION_DISABLE_AUDIO,
|
||||||
OPTION_ENABLE_FILE_TRANSFER,
|
OPTION_ENABLE_FILE_COPY_PASTE,
|
||||||
OPTION_DISABLE_CLIPBOARD,
|
OPTION_DISABLE_CLIPBOARD,
|
||||||
OPTION_LOCK_AFTER_SESSION_END,
|
OPTION_LOCK_AFTER_SESSION_END,
|
||||||
OPTION_PRIVACY_MODE,
|
OPTION_PRIVACY_MODE,
|
||||||
@ -2081,6 +2094,16 @@ pub mod keys {
|
|||||||
OPTION_SYNC_AB_WITH_RECENT_SESSIONS,
|
OPTION_SYNC_AB_WITH_RECENT_SESSIONS,
|
||||||
OPTION_SYNC_AB_TAGS,
|
OPTION_SYNC_AB_TAGS,
|
||||||
OPTION_FILTER_AB_BY_INTERSECTION,
|
OPTION_FILTER_AB_BY_INTERSECTION,
|
||||||
|
OPTION_REMOTE_MENUBAR_DRAG_LEFT,
|
||||||
|
OPTION_REMOTE_MENUBAR_DRAG_RIGHT,
|
||||||
|
OPTION_HIDE_AB_TAGS_PANEL,
|
||||||
|
OPTION_FLUTTER_REMOTE_MENUBAR_STATE,
|
||||||
|
OPTION_FLUTTER_PEER_SORTING,
|
||||||
|
OPTION_FLUTTER_PEER_TAB_INDEX,
|
||||||
|
OPTION_FLUTTER_PEER_TAB_ORDER,
|
||||||
|
OPTION_FLUTTER_PEER_TAB_VISIBLE,
|
||||||
|
OPTION_FLUTTER_PEER_CARD_UI_TYLE,
|
||||||
|
OPTION_FLUTTER_CURRENT_AB_NAME,
|
||||||
];
|
];
|
||||||
// DEFAULT_SETTINGS, OVERWRITE_SETTINGS
|
// DEFAULT_SETTINGS, OVERWRITE_SETTINGS
|
||||||
pub const KEYS_SETTINGS: &[&str] = &[
|
pub const KEYS_SETTINGS: &[&str] = &[
|
||||||
|
@ -1503,9 +1503,9 @@ impl LoginConfigHandler {
|
|||||||
BoolOption::Yes
|
BoolOption::Yes
|
||||||
})
|
})
|
||||||
.into();
|
.into();
|
||||||
} else if name == "enable-file-transfer" {
|
} else if name == "enable-file-copy-paste" {
|
||||||
config.enable_file_transfer.v = !config.enable_file_transfer.v;
|
config.enable_file_copy_paste.v = !config.enable_file_copy_paste.v;
|
||||||
option.enable_file_transfer = (if config.enable_file_transfer.v {
|
option.enable_file_transfer = (if config.enable_file_copy_paste.v {
|
||||||
BoolOption::Yes
|
BoolOption::Yes
|
||||||
} else {
|
} else {
|
||||||
BoolOption::No
|
BoolOption::No
|
||||||
@ -1538,7 +1538,7 @@ impl LoginConfigHandler {
|
|||||||
option.disable_keyboard = f(false);
|
option.disable_keyboard = f(false);
|
||||||
option.disable_clipboard = f(self.get_toggle_option("disable-clipboard"));
|
option.disable_clipboard = f(self.get_toggle_option("disable-clipboard"));
|
||||||
option.show_remote_cursor = f(self.get_toggle_option("show-remote-cursor"));
|
option.show_remote_cursor = f(self.get_toggle_option("show-remote-cursor"));
|
||||||
option.enable_file_transfer = f(self.config.enable_file_transfer.v);
|
option.enable_file_transfer = f(self.config.enable_file_copy_paste.v);
|
||||||
option.lock_after_session_end = f(self.config.lock_after_session_end.v);
|
option.lock_after_session_end = f(self.config.lock_after_session_end.v);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1631,7 +1631,7 @@ impl LoginConfigHandler {
|
|||||||
if self.get_toggle_option("disable-audio") {
|
if self.get_toggle_option("disable-audio") {
|
||||||
msg.disable_audio = BoolOption::Yes.into();
|
msg.disable_audio = BoolOption::Yes.into();
|
||||||
}
|
}
|
||||||
if !view_only && self.get_toggle_option("enable-file-transfer") {
|
if !view_only && self.get_toggle_option(config::keys::OPTION_ENABLE_FILE_COPY_PASTE) {
|
||||||
msg.enable_file_transfer = BoolOption::Yes.into();
|
msg.enable_file_transfer = BoolOption::Yes.into();
|
||||||
}
|
}
|
||||||
if view_only || self.get_toggle_option("disable-clipboard") {
|
if view_only || self.get_toggle_option("disable-clipboard") {
|
||||||
@ -1704,8 +1704,8 @@ impl LoginConfigHandler {
|
|||||||
self.config.lock_after_session_end.v
|
self.config.lock_after_session_end.v
|
||||||
} else if name == "privacy-mode" {
|
} else if name == "privacy-mode" {
|
||||||
self.config.privacy_mode.v
|
self.config.privacy_mode.v
|
||||||
} else if name == "enable-file-transfer" {
|
} else if name == config::keys::OPTION_ENABLE_FILE_COPY_PASTE {
|
||||||
self.config.enable_file_transfer.v
|
self.config.enable_file_copy_paste.v
|
||||||
} else if name == "disable-audio" {
|
} else if name == "disable-audio" {
|
||||||
self.config.disable_audio.v
|
self.config.disable_audio.v
|
||||||
} else if name == "disable-clipboard" {
|
} else if name == "disable-clipboard" {
|
||||||
|
@ -319,8 +319,13 @@ impl<T: InvokeUiSession> Remote<T> {
|
|||||||
let is_stopping_allowed = clip.is_stopping_allowed();
|
let is_stopping_allowed = clip.is_stopping_allowed();
|
||||||
let server_file_transfer_enabled =
|
let server_file_transfer_enabled =
|
||||||
*self.handler.server_file_transfer_enabled.read().unwrap();
|
*self.handler.server_file_transfer_enabled.read().unwrap();
|
||||||
let file_transfer_enabled =
|
let file_transfer_enabled = self
|
||||||
self.handler.lc.read().unwrap().enable_file_transfer.v;
|
.handler
|
||||||
|
.lc
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.enable_file_copy_paste
|
||||||
|
.v;
|
||||||
let view_only = self.handler.lc.read().unwrap().view_only.v;
|
let view_only = self.handler.lc.read().unwrap().view_only.v;
|
||||||
let stop = is_stopping_allowed
|
let stop = is_stopping_allowed
|
||||||
&& (view_only
|
&& (view_only
|
||||||
@ -1760,7 +1765,13 @@ impl<T: InvokeUiSession> Remote<T> {
|
|||||||
))]
|
))]
|
||||||
{
|
{
|
||||||
let enabled = *self.handler.server_file_transfer_enabled.read().unwrap()
|
let enabled = *self.handler.server_file_transfer_enabled.read().unwrap()
|
||||||
&& self.handler.lc.read().unwrap().enable_file_transfer.v;
|
&& self
|
||||||
|
.handler
|
||||||
|
.lc
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.enable_file_copy_paste
|
||||||
|
.v;
|
||||||
ContextSend::enable(enabled);
|
ContextSend::enable(enabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1783,7 +1794,13 @@ impl<T: InvokeUiSession> Remote<T> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let is_stopping_allowed = clip.is_stopping_allowed_from_peer();
|
let is_stopping_allowed = clip.is_stopping_allowed_from_peer();
|
||||||
let file_transfer_enabled = self.handler.lc.read().unwrap().enable_file_transfer.v;
|
let file_transfer_enabled = self
|
||||||
|
.handler
|
||||||
|
.lc
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.enable_file_copy_paste
|
||||||
|
.v;
|
||||||
let stop = is_stopping_allowed && !file_transfer_enabled;
|
let stop = is_stopping_allowed && !file_transfer_enabled;
|
||||||
log::debug!(
|
log::debug!(
|
||||||
"Process clipboard message from server peer, stop: {}, is_stopping_allowed: {}, file_transfer_enabled: {}",
|
"Process clipboard message from server peer, stop: {}, is_stopping_allowed: {}, file_transfer_enabled: {}",
|
||||||
|
121
src/common.rs
121
src/common.rs
@ -1572,6 +1572,56 @@ pub fn load_custom_client() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn read_custom_client_advanced_settings(
|
||||||
|
settings: serde_json::Value,
|
||||||
|
map_display_settings: &HashMap<String, &&str>,
|
||||||
|
map_local_settings: &HashMap<String, &&str>,
|
||||||
|
map_settings: &HashMap<String, &&str>,
|
||||||
|
is_override: bool,
|
||||||
|
) {
|
||||||
|
let mut display_settings = if is_override {
|
||||||
|
config::OVERWRITE_DISPLAY_SETTINGS.write().unwrap()
|
||||||
|
} else {
|
||||||
|
config::DEFAULT_DISPLAY_SETTINGS.write().unwrap()
|
||||||
|
};
|
||||||
|
let mut local_settings = if is_override {
|
||||||
|
config::OVERWRITE_LOCAL_SETTINGS.write().unwrap()
|
||||||
|
} else {
|
||||||
|
config::DEFAULT_LOCAL_SETTINGS.write().unwrap()
|
||||||
|
};
|
||||||
|
let mut server_settings = if is_override {
|
||||||
|
config::OVERWRITE_SETTINGS.write().unwrap()
|
||||||
|
} else {
|
||||||
|
config::DEFAULT_SETTINGS.write().unwrap()
|
||||||
|
};
|
||||||
|
if let Some(settings) = settings.as_object() {
|
||||||
|
for (k, v) in settings {
|
||||||
|
let Some(v) = v.as_str() else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
if let Some(k2) = map_display_settings.get(k) {
|
||||||
|
display_settings.insert(k2.to_string(), v.to_owned());
|
||||||
|
} else if let Some(k2) = map_local_settings.get(k) {
|
||||||
|
local_settings.insert(k2.to_string(), v.to_owned());
|
||||||
|
} else if let Some(k2) = map_settings.get(k) {
|
||||||
|
server_settings.insert(k2.to_string(), v.to_owned());
|
||||||
|
} else {
|
||||||
|
let k2 = k.replace("_", "-");
|
||||||
|
let k = k2.replace("-", "_");
|
||||||
|
// display
|
||||||
|
display_settings.insert(k.clone(), v.to_owned());
|
||||||
|
display_settings.insert(k2.clone(), v.to_owned());
|
||||||
|
// local
|
||||||
|
local_settings.insert(k.clone(), v.to_owned());
|
||||||
|
local_settings.insert(k2.clone(), v.to_owned());
|
||||||
|
// server
|
||||||
|
server_settings.insert(k.clone(), v.to_owned());
|
||||||
|
server_settings.insert(k2.clone(), v.to_owned());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn read_custom_client(config: &str) {
|
pub fn read_custom_client(config: &str) {
|
||||||
let Ok(data) = decode64(config) else {
|
let Ok(data) = decode64(config) else {
|
||||||
log::error!("Failed to decode custom client config");
|
log::error!("Failed to decode custom client config");
|
||||||
@ -1611,66 +1661,23 @@ pub fn read_custom_client(config: &str) {
|
|||||||
for s in config::keys::KEYS_SETTINGS {
|
for s in config::keys::KEYS_SETTINGS {
|
||||||
map_settings.insert(s.replace("_", "-"), s);
|
map_settings.insert(s.replace("_", "-"), s);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(default_settings) = data.remove("default-settings") {
|
if let Some(default_settings) = data.remove("default-settings") {
|
||||||
if let Some(default_settings) = default_settings.as_object() {
|
read_custom_client_advanced_settings(
|
||||||
for (k, v) in default_settings {
|
default_settings,
|
||||||
let Some(v) = v.as_str() else {
|
&map_display_settings,
|
||||||
continue;
|
&map_local_settings,
|
||||||
};
|
&map_settings,
|
||||||
if let Some(k2) = map_display_settings.get(k) {
|
false,
|
||||||
config::DEFAULT_DISPLAY_SETTINGS
|
);
|
||||||
.write()
|
|
||||||
.unwrap()
|
|
||||||
.insert(k2.to_string(), v.to_owned());
|
|
||||||
} else if let Some(k2) = map_local_settings.get(k) {
|
|
||||||
config::DEFAULT_LOCAL_SETTINGS
|
|
||||||
.write()
|
|
||||||
.unwrap()
|
|
||||||
.insert(k2.to_string(), v.to_owned());
|
|
||||||
} else if let Some(k2) = map_settings.get(k) {
|
|
||||||
config::DEFAULT_SETTINGS
|
|
||||||
.write()
|
|
||||||
.unwrap()
|
|
||||||
.insert(k2.to_string(), v.to_owned());
|
|
||||||
} else {
|
|
||||||
config::DEFAULT_SETTINGS
|
|
||||||
.write()
|
|
||||||
.unwrap()
|
|
||||||
.insert(k.clone(), v.to_owned());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if let Some(overwrite_settings) = data.remove("override-settings") {
|
if let Some(overwrite_settings) = data.remove("override-settings") {
|
||||||
if let Some(overwrite_settings) = overwrite_settings.as_object() {
|
read_custom_client_advanced_settings(
|
||||||
for (k, v) in overwrite_settings {
|
overwrite_settings,
|
||||||
let Some(v) = v.as_str() else {
|
&map_display_settings,
|
||||||
continue;
|
&map_local_settings,
|
||||||
};
|
&map_settings,
|
||||||
if let Some(k2) = map_display_settings.get(k) {
|
true,
|
||||||
config::OVERWRITE_DISPLAY_SETTINGS
|
);
|
||||||
.write()
|
|
||||||
.unwrap()
|
|
||||||
.insert(k2.to_string(), v.to_owned());
|
|
||||||
} else if let Some(k2) = map_local_settings.get(k) {
|
|
||||||
config::OVERWRITE_LOCAL_SETTINGS
|
|
||||||
.write()
|
|
||||||
.unwrap()
|
|
||||||
.insert(k2.to_string(), v.to_owned());
|
|
||||||
} else if let Some(k2) = map_settings.get(k) {
|
|
||||||
config::OVERWRITE_SETTINGS
|
|
||||||
.write()
|
|
||||||
.unwrap()
|
|
||||||
.insert(k2.to_string(), v.to_owned());
|
|
||||||
} else {
|
|
||||||
config::OVERWRITE_SETTINGS
|
|
||||||
.write()
|
|
||||||
.unwrap()
|
|
||||||
.insert(k.clone(), v.to_owned());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (k, v) in data {
|
for (k, v) in data {
|
||||||
if let Some(v) = v.as_str() {
|
if let Some(v) = v.as_str() {
|
||||||
|
@ -775,7 +775,7 @@ pub fn main_get_error() -> String {
|
|||||||
|
|
||||||
pub fn main_show_option(_key: String) -> SyncReturn<bool> {
|
pub fn main_show_option(_key: String) -> SyncReturn<bool> {
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
if _key.eq(config::CONFIG_OPTION_ALLOW_LINUX_HEADLESS) {
|
if _key.eq(config::keys::OPTION_ALLOW_LINUX_HEADLESS) {
|
||||||
return SyncReturn(true);
|
return SyncReturn(true);
|
||||||
}
|
}
|
||||||
SyncReturn(false)
|
SyncReturn(false)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use super::{CursorData, ResultType};
|
use super::{CursorData, ResultType};
|
||||||
use desktop::Desktop;
|
use desktop::Desktop;
|
||||||
use hbb_common::config::CONFIG_OPTION_ALLOW_LINUX_HEADLESS;
|
use hbb_common::config::keys::OPTION_ALLOW_LINUX_HEADLESS;
|
||||||
pub use hbb_common::platform::linux::*;
|
pub use hbb_common::platform::linux::*;
|
||||||
use hbb_common::{
|
use hbb_common::{
|
||||||
allow_err,
|
allow_err,
|
||||||
@ -95,7 +95,7 @@ pub struct xcb_xfixes_get_cursor_image {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_headless_allowed() -> bool {
|
pub fn is_headless_allowed() -> bool {
|
||||||
Config::get_option(CONFIG_OPTION_ALLOW_LINUX_HEADLESS) == "Y"
|
Config::get_option(OPTION_ALLOW_LINUX_HEADLESS) == "Y"
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -28,7 +28,7 @@ use hbb_common::platform::linux::run_cmds;
|
|||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
use hbb_common::protobuf::EnumOrUnknown;
|
use hbb_common::protobuf::EnumOrUnknown;
|
||||||
use hbb_common::{
|
use hbb_common::{
|
||||||
config::Config,
|
config::{self, Config},
|
||||||
fs::{self, can_enable_overwrite_detection},
|
fs::{self, can_enable_overwrite_detection},
|
||||||
futures::{SinkExt, StreamExt},
|
futures::{SinkExt, StreamExt},
|
||||||
get_time, get_version_number,
|
get_time, get_version_number,
|
||||||
@ -337,7 +337,7 @@ impl Connection {
|
|||||||
clipboard: Connection::permission("enable-clipboard"),
|
clipboard: Connection::permission("enable-clipboard"),
|
||||||
audio: Connection::permission("enable-audio"),
|
audio: Connection::permission("enable-audio"),
|
||||||
// to-do: make sure is the option correct here
|
// to-do: make sure is the option correct here
|
||||||
file: Connection::permission("enable-file-transfer"),
|
file: Connection::permission(config::keys::OPTION_ENABLE_FILE_TRANSFER),
|
||||||
restart: Connection::permission("enable-remote-restart"),
|
restart: Connection::permission("enable-remote-restart"),
|
||||||
recording: Connection::permission("enable-record-session"),
|
recording: Connection::permission("enable-record-session"),
|
||||||
block_input: Connection::permission("enable-block-input"),
|
block_input: Connection::permission("enable-block-input"),
|
||||||
@ -1614,7 +1614,7 @@ impl Connection {
|
|||||||
}
|
}
|
||||||
match lr.union {
|
match lr.union {
|
||||||
Some(login_request::Union::FileTransfer(ft)) => {
|
Some(login_request::Union::FileTransfer(ft)) => {
|
||||||
if !Connection::permission("enable-file-transfer") {
|
if !Connection::permission(config::keys::OPTION_ENABLE_FILE_TRANSFER) {
|
||||||
self.send_login_error("No permission of file transfer")
|
self.send_login_error("No permission of file transfer")
|
||||||
.await;
|
.await;
|
||||||
sleep(1.).await;
|
sleep(1.).await;
|
||||||
|
@ -198,7 +198,7 @@ class Header: Reactor.Component {
|
|||||||
{<li #follow-remote-window .toggle-option><span>{svg_checkmark}</span>{translate('Follow remote window focus')}</li>}
|
{<li #follow-remote-window .toggle-option><span>{svg_checkmark}</span>{translate('Follow remote window focus')}</li>}
|
||||||
<li #show-quality-monitor .toggle-option><span>{svg_checkmark}</span>{translate('Show quality monitor')}</li>
|
<li #show-quality-monitor .toggle-option><span>{svg_checkmark}</span>{translate('Show quality monitor')}</li>
|
||||||
{audio_enabled ? <li #disable-audio .toggle-option><span>{svg_checkmark}</span>{translate('Mute')}</li> : ""}
|
{audio_enabled ? <li #disable-audio .toggle-option><span>{svg_checkmark}</span>{translate('Mute')}</li> : ""}
|
||||||
{(is_win && pi.platform == "Windows") && file_enabled ? <li #enable-file-transfer .toggle-option><span>{svg_checkmark}</span>{translate('Enable file copy and paste')}</li> : ""}
|
{(is_win && pi.platform == "Windows") && file_enabled ? <li #enable-file-copy-paste .toggle-option><span>{svg_checkmark}</span>{translate('Enable file copy and paste')}</li> : ""}
|
||||||
{keyboard_enabled && clipboard_enabled ? <li #disable-clipboard .toggle-option><span>{svg_checkmark}</span>{translate('Disable clipboard')}</li> : ""}
|
{keyboard_enabled && clipboard_enabled ? <li #disable-clipboard .toggle-option><span>{svg_checkmark}</span>{translate('Disable clipboard')}</li> : ""}
|
||||||
{keyboard_enabled ? <li #lock-after-session-end .toggle-option><span>{svg_checkmark}</span>{translate('Lock after session end')}</li> : ""}
|
{keyboard_enabled ? <li #lock-after-session-end .toggle-option><span>{svg_checkmark}</span>{translate('Lock after session end')}</li> : ""}
|
||||||
{keyboard_enabled && pi.platform == "Windows" ? <li #privacy-mode><span>{svg_checkmark}</span>{translate('Privacy mode')}</li> : ""}
|
{keyboard_enabled && pi.platform == "Windows" ? <li #privacy-mode><span>{svg_checkmark}</span>{translate('Privacy mode')}</li> : ""}
|
||||||
@ -481,7 +481,7 @@ function toggleMenuState() {
|
|||||||
for (var el in $$(menu#keyboard-options>li)) {
|
for (var el in $$(menu#keyboard-options>li)) {
|
||||||
el.attributes.toggleClass("selected", values.indexOf(el.id) >= 0);
|
el.attributes.toggleClass("selected", values.indexOf(el.id) >= 0);
|
||||||
}
|
}
|
||||||
for (var id in ["show-remote-cursor", "follow-remote-cursor", "follow-remote-window", "show-quality-monitor", "disable-audio", "enable-file-transfer", "disable-clipboard", "lock-after-session-end", "allow_swap_key", "i444"]) {
|
for (var id in ["show-remote-cursor", "follow-remote-cursor", "follow-remote-window", "show-quality-monitor", "disable-audio", "enable-file-copy-paste", "disable-clipboard", "lock-after-session-end", "allow_swap_key", "i444"]) {
|
||||||
var el = self.select('#' + id);
|
var el = self.select('#' + id);
|
||||||
if (el) {
|
if (el) {
|
||||||
var value = handler.get_toggle_option(id);
|
var value = handler.get_toggle_option(id);
|
||||||
|
@ -574,7 +574,9 @@ pub async fn start_ipc<T: InvokeUiCM>(cm: ConnectionManager<T>) {
|
|||||||
feature = "unix-file-copy-paste"
|
feature = "unix-file-copy-paste"
|
||||||
),
|
),
|
||||||
))]
|
))]
|
||||||
ContextSend::enable(Config::get_option("enable-file-transfer").is_empty());
|
ContextSend::enable(
|
||||||
|
Config::get_option(hbb_common::config::keys::OPTION_ENABLE_FILE_TRANSFER).is_empty(),
|
||||||
|
);
|
||||||
|
|
||||||
match ipc::new_listener("_cm").await {
|
match ipc::new_listener("_cm").await {
|
||||||
Ok(mut incoming) => {
|
Ok(mut incoming) => {
|
||||||
|
@ -1120,7 +1120,7 @@ async fn check_connect_status_(reconnect: bool, rx: mpsc::UnboundedReceiver<ipc:
|
|||||||
)
|
)
|
||||||
))]
|
))]
|
||||||
{
|
{
|
||||||
let b = OPTIONS.lock().unwrap().get("enable-file-transfer").map(|x| x.to_string()).unwrap_or_default();
|
let b = OPTIONS.lock().unwrap().get(config::keys::OPTION_ENABLE_FILE_TRANSFER).map(|x| x.to_string()).unwrap_or_default();
|
||||||
if b != enable_file_transfer {
|
if b != enable_file_transfer {
|
||||||
clipboard::ContextSend::enable(b.is_empty());
|
clipboard::ContextSend::enable(b.is_empty());
|
||||||
enable_file_transfer = b;
|
enable_file_transfer = b;
|
||||||
|
@ -312,7 +312,7 @@ impl<T: InvokeUiSession> Session<T> {
|
|||||||
pub fn toggle_option(&self, name: String) {
|
pub fn toggle_option(&self, name: String) {
|
||||||
let msg = self.lc.write().unwrap().toggle_option(name.clone());
|
let msg = self.lc.write().unwrap().toggle_option(name.clone());
|
||||||
#[cfg(not(feature = "flutter"))]
|
#[cfg(not(feature = "flutter"))]
|
||||||
if name == "enable-file-transfer" {
|
if name == hbb_common::config::keys::OPTION_ENABLE_FILE_COPY_PASTE {
|
||||||
self.send(Data::ToggleClipboardFile);
|
self.send(Data::ToggleClipboardFile);
|
||||||
}
|
}
|
||||||
if let Some(msg) = msg {
|
if let Some(msg) = msg {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user