mirror of
https://github.com/weyne85/rustdesk.git
synced 2025-10-29 17:00:05 +00:00
refact, tab to window, remove rust cache data
Signed-off-by: dignow <linlong1265@gmail.com>
This commit is contained in:
@@ -39,8 +39,7 @@ const String kWindowEventGetRemoteList = "get_remote_list";
|
||||
const String kWindowEventGetSessionIdList = "get_session_id_list";
|
||||
|
||||
const String kWindowEventMoveTabToNewWindow = "move_tab_to_new_window";
|
||||
const String kWindowEventCloseForSeparateWindow = "close_for_separate_window";
|
||||
const String kWindowEventSendNewWindowData = "send_new_window_data";
|
||||
const String kWindowEventGetCachedSessionData = "get_cached_session_data";
|
||||
|
||||
const String kOptionOpenNewConnInTabs = "enable-open-new-connections-in-tabs";
|
||||
const String kOptionOpenInTabs = "allow-open-in-tabs";
|
||||
|
||||
@@ -17,7 +17,6 @@ import 'package:provider/provider.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
import 'package:flutter_hbb/desktop/widgets/scroll_wrapper.dart';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
|
||||
import '../../common/widgets/dialog.dart';
|
||||
import '../../common/widgets/login.dart';
|
||||
|
||||
@@ -35,6 +35,7 @@ class RemotePage extends StatefulWidget {
|
||||
Key? key,
|
||||
required this.id,
|
||||
required this.sessionId,
|
||||
required this.tabWindowId,
|
||||
required this.password,
|
||||
required this.toolbarState,
|
||||
required this.tabController,
|
||||
@@ -44,6 +45,7 @@ class RemotePage extends StatefulWidget {
|
||||
|
||||
final String id;
|
||||
final SessionID? sessionId;
|
||||
final int? tabWindowId;
|
||||
final String? password;
|
||||
final ToolbarState toolbarState;
|
||||
final String? switchUuid;
|
||||
@@ -106,6 +108,7 @@ class _RemotePageState extends State<RemotePage>
|
||||
password: widget.password,
|
||||
switchUuid: widget.switchUuid,
|
||||
forceRelay: widget.forceRelay,
|
||||
tabWindowId: widget.tabWindowId,
|
||||
);
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);
|
||||
@@ -204,7 +207,7 @@ class _RemotePageState extends State<RemotePage>
|
||||
// https://github.com/flutter/flutter/issues/64935
|
||||
super.dispose();
|
||||
debugPrint("REMOTE PAGE dispose session $sessionId ${widget.id}");
|
||||
await _renderTexture.destroy();
|
||||
await _renderTexture.destroy(widget.tabWindowId != null);
|
||||
// ensure we leave this session, this is a double check
|
||||
bind.sessionEnterOrLeave(sessionId: sessionId, enter: false);
|
||||
DesktopMultiWindow.removeListener(this);
|
||||
|
||||
@@ -7,7 +7,6 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hbb/common.dart';
|
||||
import 'package:flutter_hbb/common/shared_state.dart';
|
||||
import 'package:flutter_hbb/consts.dart';
|
||||
import 'package:flutter_hbb/models/model.dart';
|
||||
import 'package:flutter_hbb/models/state_model.dart';
|
||||
import 'package:flutter_hbb/desktop/pages/remote_page.dart';
|
||||
import 'package:flutter_hbb/desktop/widgets/remote_toolbar.dart';
|
||||
@@ -56,6 +55,7 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
|
||||
RemoteCountState.init();
|
||||
peerId = params['id'];
|
||||
final sessionId = params['session_id'];
|
||||
final tabWindowId = params['tab_window_id'];
|
||||
if (peerId != null) {
|
||||
ConnectionTypeState.init(peerId!);
|
||||
tabController.onSelected = (id) {
|
||||
@@ -78,6 +78,7 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
|
||||
key: ValueKey(peerId),
|
||||
id: peerId!,
|
||||
sessionId: sessionId == null ? null : SessionID(sessionId),
|
||||
tabWindowId: tabWindowId,
|
||||
password: params['password'],
|
||||
toolbarState: _toolbarState,
|
||||
tabController: tabController,
|
||||
@@ -99,12 +100,14 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
|
||||
print(
|
||||
"[Remote Page] call ${call.method} with args ${call.arguments} from window $fromWindowId");
|
||||
|
||||
dynamic returnValue;
|
||||
// for simplify, just replace connectionId
|
||||
if (call.method == kWindowEventNewRemoteDesktop) {
|
||||
final args = jsonDecode(call.arguments);
|
||||
final id = args['id'];
|
||||
final switchUuid = args['switch_uuid'];
|
||||
final sessionId = args['session_id'];
|
||||
final tabWindowId = args['tab_window_id'];
|
||||
windowOnTop(windowId());
|
||||
ConnectionTypeState.init(id);
|
||||
_toolbarState.setShow(
|
||||
@@ -119,6 +122,7 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
|
||||
key: ValueKey(id),
|
||||
id: id,
|
||||
sessionId: sessionId == null ? null : SessionID(sessionId),
|
||||
tabWindowId: tabWindowId,
|
||||
password: args['password'],
|
||||
toolbarState: _toolbarState,
|
||||
tabController: tabController,
|
||||
@@ -148,43 +152,24 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
|
||||
.map((e) => '${e.key},${(e.page as RemotePage).ffi.sessionId}')
|
||||
.toList()
|
||||
.join(';');
|
||||
} else if (call.method == kWindowEventCloseForSeparateWindow) {
|
||||
debugPrint('REMOVE ME ============================= ${call.arguments}');
|
||||
final peerId = call.arguments['peerId'];
|
||||
final newWindowId = call.arguments['newWindowId'];
|
||||
late RemotePage page;
|
||||
} else if (call.method == kWindowEventGetCachedSessionData) {
|
||||
// Ready to show new window and close old tab.
|
||||
final peerId = call.arguments;
|
||||
try {
|
||||
page = tabController.state.value.tabs.firstWhere((tab) {
|
||||
return tab.key == peerId;
|
||||
}).page as RemotePage;
|
||||
final remotePage = tabController.state.value.tabs
|
||||
.firstWhere((tab) => tab.key == peerId)
|
||||
.page as RemotePage;
|
||||
returnValue = remotePage.ffi.ffiModel.cachedPeerData.toString();
|
||||
} catch (e) {
|
||||
debugPrint('Failed to find tab for peerId $peerId');
|
||||
return false;
|
||||
debugPrint('Failed to get cached session data: $e');
|
||||
}
|
||||
final sendRes = await rustDeskWinManager.call(
|
||||
newWindowId,
|
||||
kWindowEventSendNewWindowData,
|
||||
page.ffi.ffiModel.cachedPeerData) as bool;
|
||||
if (!sendRes) {
|
||||
return false;
|
||||
if (returnValue != null) {
|
||||
closeSessionOnDispose[peerId] = false;
|
||||
tabController.closeBy(peerId);
|
||||
}
|
||||
// Pass the required data to new window.
|
||||
closeSessionOnDispose[peerId] = false;
|
||||
tabController.closeBy(peerId);
|
||||
return true;
|
||||
} else if (call.method == kWindowEventSendNewWindowData) {
|
||||
if (peerId == null) {
|
||||
return false;
|
||||
}
|
||||
if (tabController.state.value.tabs.isEmpty) {
|
||||
return false;
|
||||
}
|
||||
final page = tabController.state.value.tabs[0].page as RemotePage;
|
||||
page.ffi.ffiModel
|
||||
.handleCachedPeerData(call.arguments as CachedPeerData, peerId!);
|
||||
return true;
|
||||
}
|
||||
_update_remote_count();
|
||||
return returnValue;
|
||||
});
|
||||
Future.delayed(Duration.zero, () {
|
||||
restoreWindowPosition(
|
||||
|
||||
@@ -771,7 +771,7 @@ class ScreenAdjustor {
|
||||
updateScreen() async {
|
||||
final v = await rustDeskWinManager.call(
|
||||
WindowType.Main, kWindowGetWindowInfo, '');
|
||||
final String valueStr = v;
|
||||
final String valueStr = v.result;
|
||||
if (valueStr.isEmpty) {
|
||||
_screen = null;
|
||||
} else {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:texture_rgba_renderer/texture_rgba_renderer.dart';
|
||||
|
||||
@@ -21,7 +20,6 @@ class RenderTexture {
|
||||
_sessionId = sessionId;
|
||||
|
||||
textureRenderer.createTexture(_textureKey).then((id) async {
|
||||
debugPrint("id: $id, texture_key: $_textureKey");
|
||||
if (id != -1) {
|
||||
final ptr = await textureRenderer.getTexturePtr(_textureKey);
|
||||
platformFFI.registerTexture(sessionId, ptr);
|
||||
@@ -31,9 +29,11 @@ class RenderTexture {
|
||||
}
|
||||
}
|
||||
|
||||
destroy() async {
|
||||
destroy(bool unregisterTexture) async {
|
||||
if (useTextureRender && _textureKey != -1 && _sessionId != null) {
|
||||
platformFFI.registerTexture(_sessionId!, 0);
|
||||
if (unregisterTexture) {
|
||||
platformFFI.registerTexture(_sessionId!, 0);
|
||||
}
|
||||
await textureRenderer.closeTexture(_textureKey);
|
||||
_textureKey = -1;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'dart:io';
|
||||
import 'dart:math';
|
||||
import 'dart:ui' as ui;
|
||||
|
||||
import 'package:desktop_multi_window/desktop_multi_window.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_hbb/consts.dart';
|
||||
@@ -50,6 +51,37 @@ class CachedPeerData {
|
||||
bool direct = false;
|
||||
|
||||
CachedPeerData();
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return jsonEncode({
|
||||
'updatePrivacyMode': updatePrivacyMode,
|
||||
'peerInfo': peerInfo,
|
||||
'cursorDataList': cursorDataList,
|
||||
'lastCursorId': lastCursorId,
|
||||
'secure': secure,
|
||||
'direct': direct,
|
||||
});
|
||||
}
|
||||
|
||||
static CachedPeerData? fromString(String s) {
|
||||
try {
|
||||
final map = jsonDecode(s);
|
||||
final data = CachedPeerData();
|
||||
data.updatePrivacyMode = map['updatePrivacyMode'];
|
||||
data.peerInfo = map['peerInfo'];
|
||||
for (final cursorData in map['cursorDataList']) {
|
||||
data.cursorDataList.add(cursorData);
|
||||
}
|
||||
data.lastCursorId = map['lastCursorId'];
|
||||
data.secure = map['secure'];
|
||||
data.direct = map['direct'];
|
||||
return data;
|
||||
} catch (e) {
|
||||
debugPrint('Failed to parse CachedPeerData: $e');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class FfiModel with ChangeNotifier {
|
||||
@@ -1628,7 +1660,6 @@ class FFI {
|
||||
/// dialogManager use late to ensure init after main page binding [globalKey]
|
||||
late final dialogManager = OverlayDialogManager();
|
||||
|
||||
late final bool isSessionAdded;
|
||||
late final SessionID sessionId;
|
||||
late final ImageModel imageModel; // session
|
||||
late final FfiModel ffiModel; // session
|
||||
@@ -1647,7 +1678,6 @@ class FFI {
|
||||
late final ElevationModel elevationModel; // session
|
||||
|
||||
FFI(SessionID? sId) {
|
||||
isSessionAdded = sId != null;
|
||||
sessionId = sId ?? (isDesktop ? Uuid().v4obj() : _constSessionId);
|
||||
imageModel = ImageModel(WeakReference(this));
|
||||
ffiModel = FfiModel(WeakReference(this));
|
||||
@@ -1673,7 +1703,8 @@ class FFI {
|
||||
bool isRdp = false,
|
||||
String? switchUuid,
|
||||
String? password,
|
||||
bool? forceRelay}) {
|
||||
bool? forceRelay,
|
||||
int? tabWindowId}) {
|
||||
closed = false;
|
||||
auditNote = '';
|
||||
assert(!(isFileTransfer && isPortForward), 'more than one connect type');
|
||||
@@ -1688,7 +1719,9 @@ class FFI {
|
||||
imageModel.id = id;
|
||||
cursorModel.id = id;
|
||||
}
|
||||
if (!isSessionAdded) {
|
||||
// If tabWindowId != null, this session is a "tab -> window" one.
|
||||
// Else this session is a new one.
|
||||
if (tabWindowId == null) {
|
||||
// ignore: unused_local_variable
|
||||
final addRes = bind.sessionAddSync(
|
||||
sessionId: sessionId,
|
||||
@@ -1709,9 +1742,25 @@ class FFI {
|
||||
// Preserved for the rgba data.
|
||||
stream.listen((message) {
|
||||
if (closed) return;
|
||||
if (isSessionAdded && !isToNewWindowNotified.value) {
|
||||
// bind.sessionReadyToNewWindow(sessionId: sessionId);
|
||||
bind.sessionRefresh(sessionId: sessionId);
|
||||
if (tabWindowId != null && !isToNewWindowNotified.value) {
|
||||
// Session is read to be moved to a new window.
|
||||
// Get the cached data and handle the cached data.
|
||||
Future.delayed(Duration.zero, () async {
|
||||
final cachedData = await DesktopMultiWindow.invokeMethod(
|
||||
tabWindowId, kWindowEventGetCachedSessionData, id);
|
||||
if (cachedData == null) {
|
||||
// unreachable
|
||||
debugPrint('Unreachable, the cached data is empty.');
|
||||
return;
|
||||
}
|
||||
final data = CachedPeerData.fromString(cachedData);
|
||||
if (data == null) {
|
||||
debugPrint('Unreachable, the cached data cannot be decoded.');
|
||||
return;
|
||||
}
|
||||
ffiModel.handleCachedPeerData(data, id);
|
||||
await bind.sessionRefresh(sessionId: sessionId);
|
||||
});
|
||||
isToNewWindowNotified.value = true;
|
||||
}
|
||||
() async {
|
||||
|
||||
@@ -54,12 +54,10 @@ class RustDeskMultiWindowManager {
|
||||
var params = {
|
||||
'type': WindowType.RemoteDesktop.index,
|
||||
'id': peerId,
|
||||
'tab_window_id': windowId,
|
||||
'session_id': sessionId,
|
||||
};
|
||||
// It's better to use the window id that returned by _newSession.
|
||||
// Do not pass original window id to _newSession,
|
||||
// as this function cann't promise the necessary data is passed to new window.
|
||||
final multiWindowRes = await _newSession(
|
||||
await _newSession(
|
||||
false,
|
||||
WindowType.RemoteDesktop,
|
||||
kWindowEventNewRemoteDesktop,
|
||||
@@ -67,12 +65,6 @@ class RustDeskMultiWindowManager {
|
||||
_remoteDesktopWindows,
|
||||
jsonEncode(params),
|
||||
);
|
||||
// kWindowEventCloseForSeparateWindow will not only close the tab, but also pass the required data to new window.
|
||||
await DesktopMultiWindow.invokeMethod(
|
||||
windowId, kWindowEventCloseForSeparateWindow, {
|
||||
'peerId': peerId,
|
||||
'newWindowId': multiWindowRes.windowId,
|
||||
});
|
||||
}
|
||||
|
||||
Future<int> newSessionWindow(
|
||||
|
||||
Reference in New Issue
Block a user