refact, tab to window, remove rust cache data

Signed-off-by: dignow <linlong1265@gmail.com>
This commit is contained in:
dignow 2023-08-14 20:40:58 +08:00
parent e205577145
commit fad88c2718
15 changed files with 100 additions and 156 deletions

View File

@ -39,8 +39,7 @@ const String kWindowEventGetRemoteList = "get_remote_list";
const String kWindowEventGetSessionIdList = "get_session_id_list"; const String kWindowEventGetSessionIdList = "get_session_id_list";
const String kWindowEventMoveTabToNewWindow = "move_tab_to_new_window"; const String kWindowEventMoveTabToNewWindow = "move_tab_to_new_window";
const String kWindowEventCloseForSeparateWindow = "close_for_separate_window"; const String kWindowEventGetCachedSessionData = "get_cached_session_data";
const String kWindowEventSendNewWindowData = "send_new_window_data";
const String kOptionOpenNewConnInTabs = "enable-open-new-connections-in-tabs"; const String kOptionOpenNewConnInTabs = "enable-open-new-connections-in-tabs";
const String kOptionOpenInTabs = "allow-open-in-tabs"; const String kOptionOpenInTabs = "allow-open-in-tabs";

View File

@ -17,7 +17,6 @@ import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import 'package:url_launcher/url_launcher_string.dart'; import 'package:url_launcher/url_launcher_string.dart';
import 'package:flutter_hbb/desktop/widgets/scroll_wrapper.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/dialog.dart';
import '../../common/widgets/login.dart'; import '../../common/widgets/login.dart';

View File

@ -35,6 +35,7 @@ class RemotePage extends StatefulWidget {
Key? key, Key? key,
required this.id, required this.id,
required this.sessionId, required this.sessionId,
required this.tabWindowId,
required this.password, required this.password,
required this.toolbarState, required this.toolbarState,
required this.tabController, required this.tabController,
@ -44,6 +45,7 @@ class RemotePage extends StatefulWidget {
final String id; final String id;
final SessionID? sessionId; final SessionID? sessionId;
final int? tabWindowId;
final String? password; final String? password;
final ToolbarState toolbarState; final ToolbarState toolbarState;
final String? switchUuid; final String? switchUuid;
@ -106,6 +108,7 @@ class _RemotePageState extends State<RemotePage>
password: widget.password, password: widget.password,
switchUuid: widget.switchUuid, switchUuid: widget.switchUuid,
forceRelay: widget.forceRelay, forceRelay: widget.forceRelay,
tabWindowId: widget.tabWindowId,
); );
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []); SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);
@ -204,7 +207,7 @@ class _RemotePageState extends State<RemotePage>
// https://github.com/flutter/flutter/issues/64935 // https://github.com/flutter/flutter/issues/64935
super.dispose(); super.dispose();
debugPrint("REMOTE PAGE dispose session $sessionId ${widget.id}"); 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 // ensure we leave this session, this is a double check
bind.sessionEnterOrLeave(sessionId: sessionId, enter: false); bind.sessionEnterOrLeave(sessionId: sessionId, enter: false);
DesktopMultiWindow.removeListener(this); DesktopMultiWindow.removeListener(this);

View File

@ -7,7 +7,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_hbb/common.dart'; import 'package:flutter_hbb/common.dart';
import 'package:flutter_hbb/common/shared_state.dart'; import 'package:flutter_hbb/common/shared_state.dart';
import 'package:flutter_hbb/consts.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/models/state_model.dart';
import 'package:flutter_hbb/desktop/pages/remote_page.dart'; import 'package:flutter_hbb/desktop/pages/remote_page.dart';
import 'package:flutter_hbb/desktop/widgets/remote_toolbar.dart'; import 'package:flutter_hbb/desktop/widgets/remote_toolbar.dart';
@ -56,6 +55,7 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
RemoteCountState.init(); RemoteCountState.init();
peerId = params['id']; peerId = params['id'];
final sessionId = params['session_id']; final sessionId = params['session_id'];
final tabWindowId = params['tab_window_id'];
if (peerId != null) { if (peerId != null) {
ConnectionTypeState.init(peerId!); ConnectionTypeState.init(peerId!);
tabController.onSelected = (id) { tabController.onSelected = (id) {
@ -78,6 +78,7 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
key: ValueKey(peerId), key: ValueKey(peerId),
id: peerId!, id: peerId!,
sessionId: sessionId == null ? null : SessionID(sessionId), sessionId: sessionId == null ? null : SessionID(sessionId),
tabWindowId: tabWindowId,
password: params['password'], password: params['password'],
toolbarState: _toolbarState, toolbarState: _toolbarState,
tabController: tabController, tabController: tabController,
@ -99,12 +100,14 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
print( print(
"[Remote Page] call ${call.method} with args ${call.arguments} from window $fromWindowId"); "[Remote Page] call ${call.method} with args ${call.arguments} from window $fromWindowId");
dynamic returnValue;
// for simplify, just replace connectionId // for simplify, just replace connectionId
if (call.method == kWindowEventNewRemoteDesktop) { if (call.method == kWindowEventNewRemoteDesktop) {
final args = jsonDecode(call.arguments); final args = jsonDecode(call.arguments);
final id = args['id']; final id = args['id'];
final switchUuid = args['switch_uuid']; final switchUuid = args['switch_uuid'];
final sessionId = args['session_id']; final sessionId = args['session_id'];
final tabWindowId = args['tab_window_id'];
windowOnTop(windowId()); windowOnTop(windowId());
ConnectionTypeState.init(id); ConnectionTypeState.init(id);
_toolbarState.setShow( _toolbarState.setShow(
@ -119,6 +122,7 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
key: ValueKey(id), key: ValueKey(id),
id: id, id: id,
sessionId: sessionId == null ? null : SessionID(sessionId), sessionId: sessionId == null ? null : SessionID(sessionId),
tabWindowId: tabWindowId,
password: args['password'], password: args['password'],
toolbarState: _toolbarState, toolbarState: _toolbarState,
tabController: tabController, tabController: tabController,
@ -148,43 +152,24 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
.map((e) => '${e.key},${(e.page as RemotePage).ffi.sessionId}') .map((e) => '${e.key},${(e.page as RemotePage).ffi.sessionId}')
.toList() .toList()
.join(';'); .join(';');
} else if (call.method == kWindowEventCloseForSeparateWindow) { } else if (call.method == kWindowEventGetCachedSessionData) {
debugPrint('REMOVE ME ============================= ${call.arguments}'); // Ready to show new window and close old tab.
final peerId = call.arguments['peerId']; final peerId = call.arguments;
final newWindowId = call.arguments['newWindowId'];
late RemotePage page;
try { try {
page = tabController.state.value.tabs.firstWhere((tab) { final remotePage = tabController.state.value.tabs
return tab.key == peerId; .firstWhere((tab) => tab.key == peerId)
}).page as RemotePage; .page as RemotePage;
returnValue = remotePage.ffi.ffiModel.cachedPeerData.toString();
} catch (e) { } catch (e) {
debugPrint('Failed to find tab for peerId $peerId'); debugPrint('Failed to get cached session data: $e');
return false;
} }
final sendRes = await rustDeskWinManager.call( if (returnValue != null) {
newWindowId,
kWindowEventSendNewWindowData,
page.ffi.ffiModel.cachedPeerData) as bool;
if (!sendRes) {
return false;
}
// Pass the required data to new window.
closeSessionOnDispose[peerId] = false; closeSessionOnDispose[peerId] = false;
tabController.closeBy(peerId); 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(); _update_remote_count();
return returnValue;
}); });
Future.delayed(Duration.zero, () { Future.delayed(Duration.zero, () {
restoreWindowPosition( restoreWindowPosition(

View File

@ -771,7 +771,7 @@ class ScreenAdjustor {
updateScreen() async { updateScreen() async {
final v = await rustDeskWinManager.call( final v = await rustDeskWinManager.call(
WindowType.Main, kWindowGetWindowInfo, ''); WindowType.Main, kWindowGetWindowInfo, '');
final String valueStr = v; final String valueStr = v.result;
if (valueStr.isEmpty) { if (valueStr.isEmpty) {
_screen = null; _screen = null;
} else { } else {

View File

@ -1,4 +1,3 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:texture_rgba_renderer/texture_rgba_renderer.dart'; import 'package:texture_rgba_renderer/texture_rgba_renderer.dart';
@ -21,7 +20,6 @@ class RenderTexture {
_sessionId = sessionId; _sessionId = sessionId;
textureRenderer.createTexture(_textureKey).then((id) async { textureRenderer.createTexture(_textureKey).then((id) async {
debugPrint("id: $id, texture_key: $_textureKey");
if (id != -1) { if (id != -1) {
final ptr = await textureRenderer.getTexturePtr(_textureKey); final ptr = await textureRenderer.getTexturePtr(_textureKey);
platformFFI.registerTexture(sessionId, ptr); platformFFI.registerTexture(sessionId, ptr);
@ -31,9 +29,11 @@ class RenderTexture {
} }
} }
destroy() async { destroy(bool unregisterTexture) async {
if (useTextureRender && _textureKey != -1 && _sessionId != null) { if (useTextureRender && _textureKey != -1 && _sessionId != null) {
if (unregisterTexture) {
platformFFI.registerTexture(_sessionId!, 0); platformFFI.registerTexture(_sessionId!, 0);
}
await textureRenderer.closeTexture(_textureKey); await textureRenderer.closeTexture(_textureKey);
_textureKey = -1; _textureKey = -1;
} }

View File

@ -4,6 +4,7 @@ import 'dart:io';
import 'dart:math'; import 'dart:math';
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:desktop_multi_window/desktop_multi_window.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_hbb/consts.dart'; import 'package:flutter_hbb/consts.dart';
@ -50,6 +51,37 @@ class CachedPeerData {
bool direct = false; bool direct = false;
CachedPeerData(); 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 { class FfiModel with ChangeNotifier {
@ -1628,7 +1660,6 @@ class FFI {
/// dialogManager use late to ensure init after main page binding [globalKey] /// dialogManager use late to ensure init after main page binding [globalKey]
late final dialogManager = OverlayDialogManager(); late final dialogManager = OverlayDialogManager();
late final bool isSessionAdded;
late final SessionID sessionId; late final SessionID sessionId;
late final ImageModel imageModel; // session late final ImageModel imageModel; // session
late final FfiModel ffiModel; // session late final FfiModel ffiModel; // session
@ -1647,7 +1678,6 @@ class FFI {
late final ElevationModel elevationModel; // session late final ElevationModel elevationModel; // session
FFI(SessionID? sId) { FFI(SessionID? sId) {
isSessionAdded = sId != null;
sessionId = sId ?? (isDesktop ? Uuid().v4obj() : _constSessionId); sessionId = sId ?? (isDesktop ? Uuid().v4obj() : _constSessionId);
imageModel = ImageModel(WeakReference(this)); imageModel = ImageModel(WeakReference(this));
ffiModel = FfiModel(WeakReference(this)); ffiModel = FfiModel(WeakReference(this));
@ -1673,7 +1703,8 @@ class FFI {
bool isRdp = false, bool isRdp = false,
String? switchUuid, String? switchUuid,
String? password, String? password,
bool? forceRelay}) { bool? forceRelay,
int? tabWindowId}) {
closed = false; closed = false;
auditNote = ''; auditNote = '';
assert(!(isFileTransfer && isPortForward), 'more than one connect type'); assert(!(isFileTransfer && isPortForward), 'more than one connect type');
@ -1688,7 +1719,9 @@ class FFI {
imageModel.id = id; imageModel.id = id;
cursorModel.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 // ignore: unused_local_variable
final addRes = bind.sessionAddSync( final addRes = bind.sessionAddSync(
sessionId: sessionId, sessionId: sessionId,
@ -1709,9 +1742,25 @@ class FFI {
// Preserved for the rgba data. // Preserved for the rgba data.
stream.listen((message) { stream.listen((message) {
if (closed) return; if (closed) return;
if (isSessionAdded && !isToNewWindowNotified.value) { if (tabWindowId != null && !isToNewWindowNotified.value) {
// bind.sessionReadyToNewWindow(sessionId: sessionId); // Session is read to be moved to a new window.
bind.sessionRefresh(sessionId: sessionId); // 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; isToNewWindowNotified.value = true;
} }
() async { () async {

View File

@ -54,12 +54,10 @@ class RustDeskMultiWindowManager {
var params = { var params = {
'type': WindowType.RemoteDesktop.index, 'type': WindowType.RemoteDesktop.index,
'id': peerId, 'id': peerId,
'tab_window_id': windowId,
'session_id': sessionId, 'session_id': sessionId,
}; };
// It's better to use the window id that returned by _newSession. await _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(
false, false,
WindowType.RemoteDesktop, WindowType.RemoteDesktop,
kWindowEventNewRemoteDesktop, kWindowEventNewRemoteDesktop,
@ -67,12 +65,6 @@ class RustDeskMultiWindowManager {
_remoteDesktopWindows, _remoteDesktopWindows,
jsonEncode(params), 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( Future<int> newSessionWindow(

View File

@ -2366,7 +2366,7 @@ pub trait Interface: Send + Clone + 'static + Sized {
fn send(&self, data: Data); fn send(&self, data: Data);
fn msgbox(&self, msgtype: &str, title: &str, text: &str, link: &str); fn msgbox(&self, msgtype: &str, title: &str, text: &str, link: &str);
fn handle_login_error(&mut self, err: &str) -> bool; fn handle_login_error(&mut self, err: &str) -> bool;
fn handle_peer_info(&mut self, pi: PeerInfo, is_cached_pi: bool); fn handle_peer_info(&mut self, pi: PeerInfo);
fn on_error(&self, err: &str) { fn on_error(&self, err: &str) {
self.msgbox("error", "Error", err, ""); self.msgbox("error", "Error", err, "");
} }

View File

@ -125,18 +125,7 @@ impl<T: InvokeUiSession> Remote<T> {
.await .await
{ {
Ok((mut peer, direct, pk)) => { Ok((mut peer, direct, pk)) => {
let is_secured = peer.is_secured(); self.handler.set_connection_type(peer.is_secured(), direct); // flutter -> connection_ready
#[cfg(feature = "flutter")]
#[cfg(not(any(target_os = "android", target_os = "ios")))]
{
self.handler
.cache_flutter
.write()
.unwrap()
.is_secured_direct
.replace((is_secured, direct));
}
self.handler.set_connection_type(is_secured, direct); // flutter -> connection_ready
self.handler.update_direct(Some(direct)); self.handler.update_direct(Some(direct));
if conn_type == ConnType::DEFAULT_CONN { if conn_type == ConnType::DEFAULT_CONN {
self.handler self.handler
@ -1021,12 +1010,7 @@ impl<T: InvokeUiSession> Remote<T> {
} }
} }
Some(login_response::Union::PeerInfo(pi)) => { Some(login_response::Union::PeerInfo(pi)) => {
#[cfg(feature = "flutter")] self.handler.handle_peer_info(pi);
#[cfg(not(any(target_os = "android", target_os = "ios")))]
{
self.handler.cache_flutter.write().unwrap().pi = pi.clone();
}
self.handler.handle_peer_info(pi, false);
#[cfg(not(feature = "flutter"))] #[cfg(not(feature = "flutter"))]
self.check_clipboard_file_context(); self.check_clipboard_file_context();
if !(self.handler.is_file_transfer() || self.handler.is_port_forward()) { if !(self.handler.is_file_transfer() || self.handler.is_port_forward()) {
@ -1073,22 +1057,9 @@ impl<T: InvokeUiSession> Remote<T> {
_ => {} _ => {}
}, },
Some(message::Union::CursorData(cd)) => { Some(message::Union::CursorData(cd)) => {
#[cfg(feature = "flutter")]
#[cfg(not(any(target_os = "android", target_os = "ios")))]
{
let mut lock = self.handler.cache_flutter.write().unwrap();
if !lock.cursor_data.contains_key(&cd.id) {
lock.cursor_data.insert(cd.id, cd.clone());
}
}
self.handler.set_cursor_data(cd); self.handler.set_cursor_data(cd);
} }
Some(message::Union::CursorId(id)) => { Some(message::Union::CursorId(id)) => {
#[cfg(feature = "flutter")]
#[cfg(not(any(target_os = "android", target_os = "ios")))]
{
self.handler.cache_flutter.write().unwrap().cursor_id = id;
}
self.handler.set_cursor_id(id.to_string()); self.handler.set_cursor_id(id.to_string());
} }
Some(message::Union::CursorPosition(cp)) => { Some(message::Union::CursorPosition(cp)) => {
@ -1305,16 +1276,6 @@ impl<T: InvokeUiSession> Remote<T> {
} }
} }
Some(misc::Union::SwitchDisplay(s)) => { Some(misc::Union::SwitchDisplay(s)) => {
#[cfg(feature = "flutter")]
#[cfg(not(any(target_os = "android", target_os = "ios")))]
{
self.handler
.cache_flutter
.write()
.unwrap()
.sp
.replace(s.clone());
}
self.handler.handle_peer_switch_display(&s); self.handler.handle_peer_switch_display(&s);
self.video_sender.send(MediaData::Reset).ok(); self.video_sender.send(MediaData::Reset).ok();
if s.width > 0 && s.height > 0 { if s.width > 0 && s.height > 0 {
@ -1506,12 +1467,6 @@ impl<T: InvokeUiSession> Remote<T> {
} }
} }
Some(message::Union::PeerInfo(pi)) => { Some(message::Union::PeerInfo(pi)) => {
#[cfg(feature = "flutter")]
#[cfg(not(any(target_os = "android", target_os = "ios")))]
{
self.handler.cache_flutter.write().unwrap().pi.displays =
pi.displays.clone();
}
self.handler.set_displays(&pi.displays); self.handler.set_displays(&pi.displays);
} }
_ => {} _ => {}

View File

@ -36,9 +36,11 @@ pub(crate) const APP_TYPE_CM: &str = "cm";
#[cfg(any(target_os = "android", target_os = "ios"))] #[cfg(any(target_os = "android", target_os = "ios"))]
pub(crate) const APP_TYPE_CM: &str = "main"; pub(crate) const APP_TYPE_CM: &str = "main";
pub(crate) const APP_TYPE_DESKTOP_REMOTE: &str = "remote"; // Do not remove the following constants.
pub(crate) const APP_TYPE_DESKTOP_FILE_TRANSFER: &str = "file transfer"; // Uncomment them when they are used.
pub(crate) const APP_TYPE_DESKTOP_PORT_FORWARD: &str = "port forward"; // pub(crate) const APP_TYPE_DESKTOP_REMOTE: &str = "remote";
// pub(crate) const APP_TYPE_DESKTOP_FILE_TRANSFER: &str = "file transfer";
// pub(crate) const APP_TYPE_DESKTOP_PORT_FORWARD: &str = "port forward";
lazy_static::lazy_static! { lazy_static::lazy_static! {
pub(crate) static ref CUR_SESSION_ID: RwLock<SessionID> = Default::default(); pub(crate) static ref CUR_SESSION_ID: RwLock<SessionID> = Default::default();

View File

@ -597,14 +597,6 @@ pub fn session_change_resolution(session_id: SessionID, display: i32, width: i32
} }
} }
pub fn session_ready_to_new_window(session_id: SessionID) {
#[cfg(not(any(target_os = "android", target_os = "ios")))]
if let Some(session) = SESSIONS.write().unwrap().get_mut(&session_id) {
session.restore_flutter_cache();
session.refresh_video();
}
}
pub fn session_set_size(_session_id: SessionID, _width: usize, _height: usize) { pub fn session_set_size(_session_id: SessionID, _width: usize, _height: usize) {
#[cfg(feature = "flutter_texture_render")] #[cfg(feature = "flutter_texture_render")]
if let Some(session) = SESSIONS.write().unwrap().get_mut(&_session_id) { if let Some(session) = SESSIONS.write().unwrap().get_mut(&_session_id) {

View File

@ -146,7 +146,7 @@ async fn connect_and_login(
return Ok(None); return Ok(None);
} }
Some(login_response::Union::PeerInfo(pi)) => { Some(login_response::Union::PeerInfo(pi)) => {
interface.handle_peer_info(pi, false); interface.handle_peer_info(pi);
break; break;
} }
_ => {} _ => {}

View File

@ -325,6 +325,7 @@ impl<T: InvokeUiCM> IpcTaskRunner<T> {
// for tmp use, without real conn id // for tmp use, without real conn id
let mut write_jobs: Vec<fs::TransferJob> = Vec::new(); let mut write_jobs: Vec<fs::TransferJob> = Vec::new();
#[cfg(windows)]
let is_authorized = self.cm.is_authorized(self.conn_id); let is_authorized = self.cm.is_authorized(self.conn_id);
#[cfg(windows)] #[cfg(windows)]

View File

@ -48,17 +48,6 @@ pub static IS_IN: AtomicBool = AtomicBool::new(false);
const CHANGE_RESOLUTION_VALID_TIMEOUT_SECS: u64 = 15; const CHANGE_RESOLUTION_VALID_TIMEOUT_SECS: u64 = 15;
#[cfg(feature = "flutter")]
#[cfg(not(any(target_os = "android", target_os = "ios")))]
#[derive(Default)]
pub struct CacheFlutter {
pub pi: PeerInfo,
pub sp: Option<SwitchDisplay>,
pub cursor_data: HashMap<u64, CursorData>,
pub cursor_id: u64,
pub is_secured_direct: Option<(bool, bool)>,
}
#[derive(Clone, Default)] #[derive(Clone, Default)]
pub struct Session<T: InvokeUiSession> { pub struct Session<T: InvokeUiSession> {
pub session_id: SessionID, // different from the one in LoginConfigHandler, used for flutter UI message pass pub session_id: SessionID, // different from the one in LoginConfigHandler, used for flutter UI message pass
@ -73,9 +62,6 @@ pub struct Session<T: InvokeUiSession> {
pub server_file_transfer_enabled: Arc<RwLock<bool>>, pub server_file_transfer_enabled: Arc<RwLock<bool>>,
pub server_clipboard_enabled: Arc<RwLock<bool>>, pub server_clipboard_enabled: Arc<RwLock<bool>>,
pub last_change_display: Arc<Mutex<ChangeDisplayRecord>>, pub last_change_display: Arc<Mutex<ChangeDisplayRecord>>,
#[cfg(feature = "flutter")]
#[cfg(not(any(target_os = "android", target_os = "ios")))]
pub cache_flutter: Arc<RwLock<CacheFlutter>>,
} }
#[derive(Clone)] #[derive(Clone)]
@ -1095,7 +1081,7 @@ impl<T: InvokeUiSession> Interface for Session<T> {
handle_login_error(self.lc.clone(), err, self) handle_login_error(self.lc.clone(), err, self)
} }
fn handle_peer_info(&mut self, mut pi: PeerInfo, is_cached_pi: bool) { fn handle_peer_info(&mut self, mut pi: PeerInfo) {
log::debug!("handle_peer_info :{:?}", pi); log::debug!("handle_peer_info :{:?}", pi);
pi.username = self.lc.read().unwrap().get_username(&pi); pi.username = self.lc.read().unwrap().get_username(&pi);
if pi.current_display as usize >= pi.displays.len() { if pi.current_display as usize >= pi.displays.len() {
@ -1116,13 +1102,11 @@ impl<T: InvokeUiSession> Interface for Session<T> {
self.msgbox("error", "Remote Error", "No Display", ""); self.msgbox("error", "Remote Error", "No Display", "");
return; return;
} }
if !is_cached_pi {
self.try_change_init_resolution(pi.current_display); self.try_change_init_resolution(pi.current_display);
let p = self.lc.read().unwrap().should_auto_login(); let p = self.lc.read().unwrap().should_auto_login();
if !p.is_empty() { if !p.is_empty() {
input_os_password(p, true, self.clone()); input_os_password(p, true, self.clone());
} }
}
let current = &pi.displays[pi.current_display as usize]; let current = &pi.displays[pi.current_display as usize];
self.set_display( self.set_display(
current.x, current.x,
@ -1222,23 +1206,6 @@ impl<T: InvokeUiSession> Session<T> {
pub fn ctrl_alt_del(&self) { pub fn ctrl_alt_del(&self) {
self.send_key_event(&crate::keyboard::client::event_ctrl_alt_del()); self.send_key_event(&crate::keyboard::client::event_ctrl_alt_del());
} }
#[cfg(feature = "flutter")]
#[cfg(not(any(target_os = "android", target_os = "ios")))]
pub fn restore_flutter_cache(&mut self) {
if let Some((is_secured, direct)) = self.cache_flutter.read().unwrap().is_secured_direct {
self.set_connection_type(is_secured, direct);
}
let pi = self.cache_flutter.read().unwrap().pi.clone();
self.handle_peer_info(pi, true);
if let Some(sp) = self.cache_flutter.read().unwrap().sp.as_ref() {
self.handle_peer_switch_display(sp);
}
for (_, cd) in self.cache_flutter.read().unwrap().cursor_data.iter() {
self.set_cursor_data(cd.clone());
}
self.set_cursor_id(self.cache_flutter.read().unwrap().cursor_id.to_string());
}
} }
#[tokio::main(flavor = "current_thread")] #[tokio::main(flavor = "current_thread")]