switch sides

Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
21pages
2023-01-17 13:28:33 +08:00
parent 45c0e10102
commit 333092f983
49 changed files with 373 additions and 61 deletions

View File

@@ -1606,3 +1606,16 @@ Widget dialogButton(String text,
));
}
}
int get_version_num(String version) {
final list = version.split('.');
var n = 0;
for (var i = 0; i < list.length; i++) {
n = n * 1000 + (int.tryParse(list[i]) ?? 0);
}
return n;
}
int version_cmp(String v1, String v2) {
return get_version_num(v1) - get_version_num(v2);
}

View File

@@ -33,10 +33,12 @@ class RemotePage extends StatefulWidget {
Key? key,
required this.id,
required this.menubarState,
this.switchUuid,
}) : super(key: key);
final String id;
final MenubarState menubarState;
final String? switchUuid;
final SimpleWrapper<State<RemotePage>?> _lastState = SimpleWrapper(null);
FFI get ffi => (_lastState.value! as _RemotePageState)._ffi;
@@ -100,7 +102,10 @@ class _RemotePageState extends State<RemotePage>
showKBLayoutTypeChooserIfNeeded(
_ffi.ffiModel.pi.platform, _ffi.dialogManager);
});
_ffi.start(widget.id);
_ffi.start(
widget.id,
switchUuid: widget.switchUuid,
);
WidgetsBinding.instance.addPostFrameCallback((_) {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);
_ffi.dialogManager

View File

@@ -64,6 +64,7 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
key: ValueKey(peerId),
id: peerId,
menubarState: _menubarState,
switchUuid: params['switch_uuid'],
),
));
_update_remote_count();
@@ -84,6 +85,7 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
if (call.method == "new_remote_desktop") {
final args = jsonDecode(call.arguments);
final id = args['id'];
final switchUuid = args['switch_uuid'];
window_on_top(windowId());
ConnectionTypeState.init(id);
tabController.add(TabInfo(
@@ -96,6 +98,7 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
key: ValueKey(id),
id: id,
menubarState: _menubarState,
switchUuid: switchUuid,
),
));
} else if (call.method == "onDestroy") {

View File

@@ -516,6 +516,15 @@ class _CmControlPanel extends StatelessWidget {
return Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Offstage(
offstage: !client.fromSwitch,
child: buildButton(context,
color: Colors.purple,
onClick: () => handleSwitchBack(context),
icon: Icon(Icons.reply, color: Colors.white),
text: "Switch Sides",
textColor: Colors.white),
),
Offstage(
offstage: !showElevation,
child: buildButton(context, color: Colors.green[700], onClick: () {
@@ -674,6 +683,10 @@ class _CmControlPanel extends StatelessWidget {
windowManager.close();
}
}
void handleSwitchBack(BuildContext context) {
bind.cmSwitchBack(connId: client.id);
}
}
void checkClickTime(int id, Function() callback) async {

View File

@@ -509,6 +509,7 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
List<MenuEntryBase<String>> _getControlMenu(BuildContext context) {
final pi = widget.ffi.ffiModel.pi;
final perms = widget.ffi.ffiModel.permissions;
final peer_version = widget.ffi.ffiModel.pi.version;
const EdgeInsets padding = EdgeInsets.only(left: 14.0, right: 5.0);
final List<MenuEntryBase<String>> displayMenu = [];
displayMenu.addAll([
@@ -651,6 +652,18 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
dismissOnClicked: true,
));
}
if (version_cmp(peer_version, '1.2.0') >= 0) {
displayMenu.add(MenuEntryButton<String>(
childBuilder: (TextStyle? style) => Text(
translate('Switch Sides'),
style: style,
),
proc: () =>
showConfirmSwitchSidesDialog(widget.id, widget.ffi.dialogManager),
padding: padding,
dismissOnClicked: true,
));
}
}
if (pi.version.isNotEmpty) {
@@ -721,6 +734,7 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
List<MenuEntryBase<String>> _getDisplayMenu(
dynamic futureData, int remoteCount) {
const EdgeInsets padding = EdgeInsets.only(left: 18.0, right: 8.0);
final peer_version = widget.ffi.ffiModel.pi.version;
final displayMenu = [
MenuEntryRadios<String>(
text: translate('Ratio'),
@@ -880,9 +894,7 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
final fpsSlider = Offstage(
offstage:
(await bind.mainIsUsingPublicServer() && direct != true) ||
(await bind.versionToNumber(
v: widget.ffi.ffiModel.pi.version) <
await bind.versionToNumber(v: '1.2.0')),
version_cmp(peer_version, '1.2.0') < 0,
child: Row(
children: [
Obx((() => Slider(
@@ -1391,16 +1403,33 @@ void showAuditDialog(String id, dialogManager) async {
focusNode: focusNode,
)),
actions: [
TextButton(
style: flatButtonStyle,
onPressed: close,
child: Text(translate('Cancel')),
),
TextButton(
style: flatButtonStyle,
onPressed: submit,
child: Text(translate('OK')),
),
dialogButton('Cancel', onPressed: close, isOutline: true),
dialogButton('OK', onPressed: submit)
],
onSubmit: submit,
onCancel: close,
);
});
}
void showConfirmSwitchSidesDialog(
String id, OverlayDialogManager dialogManager) async {
dialogManager.show((setState, close) {
submit() async {
await bind.sessionSwitchSides(id: id);
closeConnection(id: id);
}
return CustomAlertDialog(
title: Text(translate('Switch Sides')),
content: Column(
children: [
Text(translate('Please confirm if you want to share your desktop?')),
],
),
actions: [
dialogButton('Cancel', onPressed: close, isOutline: true),
dialogButton('OK', onPressed: submit),
],
onSubmit: submit,
onCancel: close,

View File

@@ -199,6 +199,16 @@ class FfiModel with ChangeNotifier {
parent.target?.serverModel.setShowElevation(show);
} else if (name == 'cancel_msgbox') {
cancelMsgBox(evt, peerId);
} else if (name == 'switch_sides') {
final peer_id = evt['peer_id'].toString();
final uuid = evt['uuid'].toString();
Future.delayed(Duration.zero, () {
rustDeskWinManager.newRemoteDesktop(peer_id, switch_uuid: uuid);
});
} else if (name == 'switch_back') {
final peer_id = evt['peer_id'].toString();
await bind.sessionSwitchSides(id: peer_id);
closeConnection(id: peer_id);
}
};
}
@@ -1289,7 +1299,9 @@ class FFI {
/// Start with the given [id]. Only transfer file if [isFileTransfer], only port forward if [isPortForward].
void start(String id,
{bool isFileTransfer = false, bool isPortForward = false}) {
{bool isFileTransfer = false,
bool isPortForward = false,
String? switchUuid}) {
assert(!(isFileTransfer && isPortForward), 'more than one connect type');
if (isFileTransfer) {
connType = ConnType.fileTransfer;
@@ -1305,7 +1317,11 @@ class FFI {
}
// ignore: unused_local_variable
final addRes = bind.sessionAddSync(
id: id, isFileTransfer: isFileTransfer, isPortForward: isPortForward);
id: id,
isFileTransfer: isFileTransfer,
isPortForward: isPortForward,
switchUuid: switchUuid ?? "",
);
final stream = bind.sessionStart(id: id);
final cb = ffiModel.startEventListener(id);
() async {

View File

@@ -601,6 +601,7 @@ class Client {
bool restart = false;
bool recording = false;
bool disconnected = false;
bool fromSwitch = false;
RxBool hasUnreadChatMessage = false.obs;
@@ -621,6 +622,7 @@ class Client {
restart = json['restart'];
recording = json['recording'];
disconnected = json['disconnected'];
fromSwitch = json['from_switch'];
}
Map<String, dynamic> toJson() {
@@ -638,6 +640,7 @@ class Client {
data['restart'] = restart;
data['recording'] = recording;
data['disconnected'] = disconnected;
data['from_switch'] = fromSwitch;
return data;
}

View File

@@ -40,9 +40,13 @@ class RustDeskMultiWindowManager {
int? _fileTransferWindowId;
int? _portForwardWindowId;
Future<dynamic> newRemoteDesktop(String remoteId) async {
final msg =
jsonEncode({"type": WindowType.RemoteDesktop.index, "id": remoteId});
Future<dynamic> newRemoteDesktop(String remoteId,
{String? switch_uuid}) async {
final msg = jsonEncode({
"type": WindowType.RemoteDesktop.index,
"id": remoteId,
"switch_uuid": switch_uuid ?? ""
});
try {
final ids = await DesktopMultiWindow.getAllSubWindowIds();
@@ -208,7 +212,7 @@ class RustDeskMultiWindowManager {
}
/// Remove active window which has [`windowId`]
///
///
/// [Availability]
/// This function should only be called from main window.
/// For other windows, please post a unregister(hide) event to main window handler: