mirror of
https://github.com/weyne85/rustdesk.git
synced 2025-10-29 17:00:05 +00:00
@@ -74,7 +74,11 @@ class ChatModel with ChangeNotifier {
|
||||
|
||||
final WeakReference<FFI> parent;
|
||||
|
||||
ChatModel(this.parent);
|
||||
late final SessionID sessionId;
|
||||
|
||||
ChatModel(this.parent) {
|
||||
sessionId = parent.target!.sessionId;
|
||||
}
|
||||
|
||||
FocusNode inputNode = FocusNode();
|
||||
|
||||
@@ -302,7 +306,7 @@ class ChatModel with ChangeNotifier {
|
||||
_messages[_currentID]?.insert(message);
|
||||
if (_currentID == clientModeID) {
|
||||
if (parent.target != null) {
|
||||
bind.sessionSendChat(id: parent.target!.id, text: message.text);
|
||||
bind.sessionSendChat(sessionId: sessionId, text: message.text);
|
||||
}
|
||||
} else {
|
||||
bind.cmSendChat(connId: _currentID, msg: message.text);
|
||||
@@ -347,8 +351,8 @@ class ChatModel with ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
void closeVoiceCall(String id) {
|
||||
bind.sessionCloseVoiceCall(id: id);
|
||||
void closeVoiceCall() {
|
||||
bind.sessionCloseVoiceCall(sessionId: sessionId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,11 +33,11 @@ class JobID {
|
||||
}
|
||||
}
|
||||
|
||||
typedef GetSessionID = String Function();
|
||||
typedef GetSessionID = SessionID Function();
|
||||
|
||||
class FileModel {
|
||||
final WeakReference<FFI> parent;
|
||||
// late final String sessionID;
|
||||
// late final String sessionId;
|
||||
late final FileFetcher fileFetcher;
|
||||
late final JobController jobController;
|
||||
|
||||
@@ -45,11 +45,11 @@ class FileModel {
|
||||
late final FileController remoteController;
|
||||
|
||||
late final GetSessionID getSessionID;
|
||||
String get sessionID => getSessionID();
|
||||
SessionID get sessionId => getSessionID();
|
||||
late final FileDialogEventLoop evtLoop;
|
||||
|
||||
FileModel(this.parent) {
|
||||
getSessionID = () => parent.target?.id ?? "";
|
||||
getSessionID = () => parent.target!.sessionId;
|
||||
fileFetcher = FileFetcher(getSessionID);
|
||||
jobController = JobController(getSessionID);
|
||||
localController = FileController(
|
||||
@@ -133,7 +133,7 @@ class FileModel {
|
||||
evtLoop.setSkip(!need_override);
|
||||
}
|
||||
await bind.sessionSetConfirmOverrideFile(
|
||||
id: sessionID,
|
||||
sessionId: sessionId,
|
||||
actId: id,
|
||||
fileNum: int.parse(evt['file_num']),
|
||||
needOverride: need_override,
|
||||
@@ -236,7 +236,7 @@ class DirectoryData {
|
||||
class FileController {
|
||||
final bool isLocal;
|
||||
final GetSessionID getSessionID;
|
||||
String get sessionID => getSessionID();
|
||||
SessionID get sessionId => getSessionID();
|
||||
|
||||
final FileFetcher fileFetcher;
|
||||
|
||||
@@ -287,7 +287,7 @@ class FileController {
|
||||
options.value.home = await bind.mainGetHomeDir();
|
||||
}
|
||||
options.value.showHidden = (await bind.sessionGetPeerOption(
|
||||
id: sessionID,
|
||||
sessionId: sessionId,
|
||||
name: isLocal ? "local_show_hidden" : "remote_show_hidden"))
|
||||
.isNotEmpty;
|
||||
options.value.isWindows = isLocal
|
||||
@@ -297,7 +297,7 @@ class FileController {
|
||||
await Future.delayed(Duration(milliseconds: 100));
|
||||
|
||||
final dir = (await bind.sessionGetPeerOption(
|
||||
id: sessionID, name: isLocal ? "local_dir" : "remote_dir"));
|
||||
sessionId: sessionId, name: isLocal ? "local_dir" : "remote_dir"));
|
||||
openDirectory(dir.isEmpty ? options.value.home : dir);
|
||||
|
||||
await Future.delayed(Duration(seconds: 1));
|
||||
@@ -315,7 +315,7 @@ class FileController {
|
||||
options.value.showHidden ? "Y" : "";
|
||||
for (final msg in msgMap.entries) {
|
||||
await bind.sessionPeerOption(
|
||||
id: sessionID, name: msg.key, value: msg.value);
|
||||
sessionId: sessionId, name: msg.key, value: msg.value);
|
||||
}
|
||||
directory.value.clear();
|
||||
options.value.clear();
|
||||
@@ -447,7 +447,7 @@ class FileController {
|
||||
for (var from in items.items) {
|
||||
final jobID = jobController.add(from, isRemoteToLocal);
|
||||
bind.sessionSendFiles(
|
||||
id: sessionID,
|
||||
sessionId: sessionId,
|
||||
actId: jobID,
|
||||
path: from.path,
|
||||
to: PathUtil.join(toPath, from.name, isWindows),
|
||||
@@ -547,7 +547,8 @@ class FileController {
|
||||
|
||||
Future<bool?> showRemoveDialog(
|
||||
String title, String content, bool showCheckbox) async {
|
||||
return await dialogManager?.show<bool>((setState, Function(bool v) close, context) {
|
||||
return await dialogManager?.show<bool>(
|
||||
(setState, Function(bool v) close, context) {
|
||||
cancel() => close(false);
|
||||
submit() => close(true);
|
||||
return CustomAlertDialog(
|
||||
@@ -611,7 +612,7 @@ class FileController {
|
||||
|
||||
void sendRemoveFile(String path, int fileNum) {
|
||||
bind.sessionRemoveFile(
|
||||
id: sessionID,
|
||||
sessionId: sessionId,
|
||||
actId: JobController.jobID.next(),
|
||||
path: path,
|
||||
isRemote: !isLocal,
|
||||
@@ -621,7 +622,7 @@ class FileController {
|
||||
void sendRemoveEmptyDir(String path, int fileNum) {
|
||||
history.removeWhere((element) => element.contains(path));
|
||||
bind.sessionRemoveAllEmptyDirs(
|
||||
id: sessionID,
|
||||
sessionId: sessionId,
|
||||
actId: JobController.jobID.next(),
|
||||
path: path,
|
||||
isRemote: !isLocal);
|
||||
@@ -629,7 +630,7 @@ class FileController {
|
||||
|
||||
Future<void> createDir(String path) async {
|
||||
bind.sessionCreateDir(
|
||||
id: sessionID,
|
||||
sessionId: sessionId,
|
||||
actId: JobController.jobID.next(),
|
||||
path: path,
|
||||
isRemote: !isLocal);
|
||||
@@ -641,7 +642,7 @@ class JobController {
|
||||
final jobTable = List<JobProgress>.empty(growable: true).obs;
|
||||
final jobResultListener = JobResultListener<Map<String, dynamic>>();
|
||||
final GetSessionID getSessionID;
|
||||
String get sessionID => getSessionID();
|
||||
SessionID get sessionId => getSessionID();
|
||||
|
||||
JobController(this.getSessionID);
|
||||
|
||||
@@ -719,7 +720,7 @@ class JobController {
|
||||
}
|
||||
|
||||
Future<void> cancelJob(int id) async {
|
||||
await bind.sessionCancelJob(id: sessionID, actId: id);
|
||||
await bind.sessionCancelJob(sessionId: sessionId, actId: id);
|
||||
}
|
||||
|
||||
void loadLastJob(Map<String, dynamic> evt) {
|
||||
@@ -745,7 +746,7 @@ class JobController {
|
||||
..state = JobState.paused;
|
||||
jobTable.add(jobProgress);
|
||||
bind.sessionAddJob(
|
||||
id: sessionID,
|
||||
sessionId: sessionId,
|
||||
isRemote: isRemote,
|
||||
includeHidden: showHidden,
|
||||
actId: currJobId,
|
||||
@@ -760,7 +761,7 @@ class JobController {
|
||||
if (jobIndex != -1) {
|
||||
final job = jobTable[jobIndex];
|
||||
bind.sessionResumeJob(
|
||||
id: sessionID, actId: job.id, isRemote: job.isRemoteToLocal);
|
||||
sessionId: sessionId, actId: job.id, isRemote: job.isRemoteToLocal);
|
||||
job.state = JobState.inProgress;
|
||||
jobTable.refresh();
|
||||
} else {
|
||||
@@ -831,7 +832,7 @@ class FileFetcher {
|
||||
Map<int, Completer<FileDirectory>> readRecursiveTasks = {};
|
||||
|
||||
final GetSessionID getSessionID;
|
||||
String get sessionID => getSessionID();
|
||||
SessionID get sessionId => getSessionID();
|
||||
|
||||
FileFetcher(this.getSessionID);
|
||||
|
||||
@@ -896,12 +897,12 @@ class FileFetcher {
|
||||
try {
|
||||
if (isLocal) {
|
||||
final res = await bind.sessionReadLocalDirSync(
|
||||
id: sessionID, path: path, showHidden: showHidden);
|
||||
sessionId: sessionId, path: path, showHidden: showHidden);
|
||||
final fd = FileDirectory.fromJson(jsonDecode(res));
|
||||
return fd;
|
||||
} else {
|
||||
await bind.sessionReadRemoteDir(
|
||||
id: sessionID, path: path, includeHidden: showHidden);
|
||||
sessionId: sessionId, path: path, includeHidden: showHidden);
|
||||
return registerReadTask(isLocal, path);
|
||||
}
|
||||
} catch (e) {
|
||||
@@ -914,7 +915,7 @@ class FileFetcher {
|
||||
// TODO test Recursive is show hidden default?
|
||||
try {
|
||||
await bind.sessionReadDirRecursive(
|
||||
id: sessionID,
|
||||
sessionId: sessionId,
|
||||
actId: actID,
|
||||
path: path,
|
||||
isRemote: !isLocal,
|
||||
|
||||
@@ -59,9 +59,13 @@ class InputModel {
|
||||
|
||||
get id => parent.target?.id ?? "";
|
||||
|
||||
late final SessionID sessionId;
|
||||
|
||||
bool get keyboardPerm => parent.target!.ffiModel.keyboard;
|
||||
|
||||
InputModel(this.parent);
|
||||
InputModel(this.parent) {
|
||||
sessionId = parent.target!.sessionId;
|
||||
}
|
||||
|
||||
KeyEventResult handleRawKeyEvent(FocusNode data, RawKeyEvent e) {
|
||||
if (isDesktop && !stateGlobal.grabKeyboard) {
|
||||
@@ -70,7 +74,7 @@ class InputModel {
|
||||
|
||||
// * Currently mobile does not enable map mode
|
||||
if (isDesktop) {
|
||||
bind.sessionGetKeyboardMode(id: id).then((result) {
|
||||
bind.sessionGetKeyboardMode(sessionId: sessionId).then((result) {
|
||||
keyboardMode = result.toString();
|
||||
});
|
||||
}
|
||||
@@ -169,7 +173,7 @@ class InputModel {
|
||||
lockModes |= (1 << scrolllock);
|
||||
}
|
||||
bind.sessionHandleFlutterKeyEvent(
|
||||
id: id,
|
||||
sessionId: sessionId,
|
||||
name: name,
|
||||
platformCode: platformCode,
|
||||
positionCode: positionCode,
|
||||
@@ -204,7 +208,7 @@ class InputModel {
|
||||
void inputKey(String name, {bool? down, bool? press}) {
|
||||
if (!keyboardPerm) return;
|
||||
bind.sessionInputKey(
|
||||
id: id,
|
||||
sessionId: sessionId,
|
||||
name: name,
|
||||
down: down ?? false,
|
||||
press: press ?? true,
|
||||
@@ -264,7 +268,7 @@ class InputModel {
|
||||
/// Send scroll event with scroll distance [y].
|
||||
void scroll(int y) {
|
||||
bind.sessionSendMouse(
|
||||
id: id,
|
||||
sessionId: sessionId,
|
||||
msg: json
|
||||
.encode(modify({'id': id, 'type': 'wheel', 'y': y.toString()})));
|
||||
}
|
||||
@@ -287,7 +291,7 @@ class InputModel {
|
||||
void sendMouse(String type, MouseButtons button) {
|
||||
if (!keyboardPerm) return;
|
||||
bind.sessionSendMouse(
|
||||
id: id,
|
||||
sessionId: sessionId,
|
||||
msg: json.encode(modify({'type': type, 'buttons': button.value})));
|
||||
}
|
||||
|
||||
@@ -297,7 +301,7 @@ class InputModel {
|
||||
resetModifiers();
|
||||
}
|
||||
_flingTimer?.cancel();
|
||||
bind.sessionEnterOrLeave(id: id, enter: enter);
|
||||
bind.sessionEnterOrLeave(sessionId: sessionId, enter: enter);
|
||||
}
|
||||
|
||||
/// Send mouse movement event with distance in [x] and [y].
|
||||
@@ -306,7 +310,8 @@ class InputModel {
|
||||
var x2 = x.toInt();
|
||||
var y2 = y.toInt();
|
||||
bind.sessionSendMouse(
|
||||
id: id, msg: json.encode(modify({'x': '$x2', 'y': '$y2'})));
|
||||
sessionId: sessionId,
|
||||
msg: json.encode(modify({'x': '$x2', 'y': '$y2'})));
|
||||
}
|
||||
|
||||
void onPointHoverImage(PointerHoverEvent e) {
|
||||
@@ -333,7 +338,8 @@ class InputModel {
|
||||
var y = delta.dy.toInt();
|
||||
if (x != 0 || y != 0) {
|
||||
bind.sessionSendMouse(
|
||||
id: id, msg: '{"type": "trackpad", "x": "$x", "y": "$y"}');
|
||||
sessionId: sessionId,
|
||||
msg: '{"type": "trackpad", "x": "$x", "y": "$y"}');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -364,7 +370,8 @@ class InputModel {
|
||||
}
|
||||
|
||||
bind.sessionSendMouse(
|
||||
id: id, msg: '{"type": "trackpad", "x": "$dx", "y": "$dy"}');
|
||||
sessionId: sessionId,
|
||||
msg: '{"type": "trackpad", "x": "$dx", "y": "$dy"}');
|
||||
_scheduleFling(x, y, delay);
|
||||
});
|
||||
}
|
||||
@@ -439,7 +446,8 @@ class InputModel {
|
||||
dy = 1;
|
||||
}
|
||||
bind.sessionSendMouse(
|
||||
id: id, msg: '{"type": "wheel", "x": "$dx", "y": "$dy"}');
|
||||
sessionId: sessionId,
|
||||
msg: '{"type": "wheel", "x": "$dx", "y": "$dy"}');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -632,7 +640,7 @@ class InputModel {
|
||||
break;
|
||||
}
|
||||
evt['buttons'] = buttons;
|
||||
bind.sessionSendMouse(id: id, msg: json.encode(evt));
|
||||
bind.sessionSendMouse(sessionId: sessionId, msg: json.encode(evt));
|
||||
}
|
||||
|
||||
/// Web only
|
||||
|
||||
@@ -27,6 +27,7 @@ import 'package:image/image.dart' as img2;
|
||||
import 'package:flutter_custom_cursor/cursor_manager.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
|
||||
import '../common.dart';
|
||||
@@ -36,7 +37,7 @@ import 'input_model.dart';
|
||||
import 'platform_model.dart';
|
||||
|
||||
typedef HandleMsgBox = Function(Map<String, dynamic> evt, String id);
|
||||
typedef ReconnectHandle = Function(OverlayDialogManager, String, bool);
|
||||
typedef ReconnectHandle = Function(OverlayDialogManager, SessionID, bool);
|
||||
final _waitForImage = <String, bool>{};
|
||||
|
||||
class FfiModel with ChangeNotifier {
|
||||
@@ -52,6 +53,7 @@ class FfiModel with ChangeNotifier {
|
||||
var _reconnects = 1;
|
||||
bool _viewOnly = false;
|
||||
WeakReference<FFI> parent;
|
||||
late final SessionID sessionId;
|
||||
|
||||
Map<String, bool> get permissions => _permissions;
|
||||
|
||||
@@ -77,6 +79,7 @@ class FfiModel with ChangeNotifier {
|
||||
|
||||
FfiModel(this.parent) {
|
||||
clear();
|
||||
sessionId = parent.target!.sessionId;
|
||||
}
|
||||
|
||||
toggleTouchMode() {
|
||||
@@ -139,20 +142,21 @@ class FfiModel with ChangeNotifier {
|
||||
_permissions.clear();
|
||||
}
|
||||
|
||||
StreamEventHandler startEventListener(String peerId) {
|
||||
// todo: why called by two position
|
||||
StreamEventHandler startEventListener(SessionID sessionId, String peerId) {
|
||||
return (evt) async {
|
||||
var name = evt['name'];
|
||||
if (name == 'msgbox') {
|
||||
handleMsgBox(evt, peerId);
|
||||
handleMsgBox(evt, sessionId, peerId);
|
||||
} else if (name == 'peer_info') {
|
||||
handlePeerInfo(evt, peerId);
|
||||
} else if (name == 'sync_peer_info') {
|
||||
handleSyncPeerInfo(evt, peerId);
|
||||
handleSyncPeerInfo(evt, sessionId);
|
||||
} else if (name == 'connection_ready') {
|
||||
setConnectionType(
|
||||
peerId, evt['secure'] == 'true', evt['direct'] == 'true');
|
||||
} else if (name == 'switch_display') {
|
||||
handleSwitchDisplay(evt, peerId);
|
||||
handleSwitchDisplay(evt, sessionId, peerId);
|
||||
} else if (name == 'cursor_data') {
|
||||
await parent.target?.cursorModel.updateCursorData(evt);
|
||||
} else if (name == 'cursor_id') {
|
||||
@@ -193,7 +197,7 @@ class FfiModel with ChangeNotifier {
|
||||
} else if (name == 'update_block_input_state') {
|
||||
updateBlockInputState(evt, peerId);
|
||||
} else if (name == 'update_privacy_mode') {
|
||||
updatePrivacyMode(evt, peerId);
|
||||
updatePrivacyMode(evt, sessionId, peerId);
|
||||
} else if (name == 'new_connection') {
|
||||
var uni_links = evt['uni_links'].toString();
|
||||
if (uni_links.startsWith(kUniLinksPrefix)) {
|
||||
@@ -205,10 +209,10 @@ class FfiModel with ChangeNotifier {
|
||||
final show = evt['show'].toString() == 'true';
|
||||
parent.target?.serverModel.setShowElevation(show);
|
||||
} else if (name == 'cancel_msgbox') {
|
||||
cancelMsgBox(evt, peerId);
|
||||
cancelMsgBox(evt, sessionId);
|
||||
} else if (name == 'switch_back') {
|
||||
final peer_id = evt['peer_id'].toString();
|
||||
await bind.sessionSwitchSides(id: peer_id);
|
||||
await bind.sessionSwitchSides(sessionId: sessionId);
|
||||
closeConnection(id: peer_id);
|
||||
} else if (name == 'portable_service_running') {
|
||||
parent.target?.elevationModel.onPortableServiceRunning(evt);
|
||||
@@ -234,12 +238,12 @@ class FfiModel with ChangeNotifier {
|
||||
} else if (name == 'plugin_manager') {
|
||||
pluginManager.handleEvent(evt);
|
||||
} else if (name == 'plugin_event') {
|
||||
handlePluginEvent(
|
||||
evt, peerId, (Map<String, dynamic> e) => handleMsgBox(e, peerId));
|
||||
handlePluginEvent(evt,
|
||||
(Map<String, dynamic> e) => handleMsgBox(e, sessionId, peerId));
|
||||
} else if (name == 'plugin_reload') {
|
||||
handleReloading(evt, peerId);
|
||||
handleReloading(evt);
|
||||
} else if (name == 'plugin_option') {
|
||||
handleOption(evt, peerId);
|
||||
handleOption(evt);
|
||||
} else {
|
||||
debugPrint('Unknown event name: $name');
|
||||
}
|
||||
@@ -271,8 +275,8 @@ class FfiModel with ChangeNotifier {
|
||||
}
|
||||
|
||||
/// Bind the event listener to receive events from the Rust core.
|
||||
updateEventListener(String peerId) {
|
||||
platformFFI.setEventCallback(startEventListener(peerId));
|
||||
updateEventListener(SessionID sessionId, String peerId) {
|
||||
platformFFI.setEventCallback(startEventListener(sessionId, peerId));
|
||||
}
|
||||
|
||||
handleAliasChanged(Map<String, dynamic> evt) {
|
||||
@@ -282,18 +286,19 @@ class FfiModel with ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
_updateCurDisplay(String peerId, Display newDisplay) {
|
||||
_updateCurDisplay(SessionID sessionId, Display newDisplay) {
|
||||
if (newDisplay != _display) {
|
||||
if (newDisplay.x != _display.x || newDisplay.y != _display.y) {
|
||||
parent.target?.cursorModel
|
||||
.updateDisplayOrigin(newDisplay.x, newDisplay.y);
|
||||
}
|
||||
_display = newDisplay;
|
||||
_updateSessionWidthHeight(peerId);
|
||||
_updateSessionWidthHeight(sessionId);
|
||||
}
|
||||
}
|
||||
|
||||
handleSwitchDisplay(Map<String, dynamic> evt, String peerId) {
|
||||
handleSwitchDisplay(
|
||||
Map<String, dynamic> evt, SessionID sessionId, String peerId) {
|
||||
_pi.currentDisplay = int.parse(evt['display']);
|
||||
var newDisplay = Display();
|
||||
newDisplay.x = double.tryParse(evt['x']) ?? newDisplay.x;
|
||||
@@ -306,7 +311,7 @@ class FfiModel with ChangeNotifier {
|
||||
newDisplay.originalHeight =
|
||||
int.tryParse(evt['original_height']) ?? kInvalidResolutionValue;
|
||||
|
||||
_updateCurDisplay(peerId, newDisplay);
|
||||
_updateCurDisplay(sessionId, newDisplay);
|
||||
|
||||
try {
|
||||
CurrentDisplayState.find(peerId).value = _pi.currentDisplay;
|
||||
@@ -318,15 +323,15 @@ class FfiModel with ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
cancelMsgBox(Map<String, dynamic> evt, String id) {
|
||||
cancelMsgBox(Map<String, dynamic> evt, SessionID sessionId) {
|
||||
if (parent.target == null) return;
|
||||
final dialogManager = parent.target!.dialogManager;
|
||||
final tag = '$id-${evt['tag']}';
|
||||
final tag = '$sessionId-${evt['tag']}';
|
||||
dialogManager.dismissByTag(tag);
|
||||
}
|
||||
|
||||
/// Handle the message box event based on [evt] and [id].
|
||||
handleMsgBox(Map<String, dynamic> evt, String id) {
|
||||
handleMsgBox(Map<String, dynamic> evt, SessionID sessionId, String peerId) {
|
||||
if (parent.target == null) return;
|
||||
final dialogManager = parent.target!.dialogManager;
|
||||
final type = evt['type'];
|
||||
@@ -334,43 +339,43 @@ class FfiModel with ChangeNotifier {
|
||||
final text = evt['text'];
|
||||
final link = evt['link'];
|
||||
if (type == 're-input-password') {
|
||||
wrongPasswordDialog(id, dialogManager, type, title, text);
|
||||
wrongPasswordDialog(sessionId, dialogManager, type, title, text);
|
||||
} else if (type == 'input-password') {
|
||||
enterPasswordDialog(id, dialogManager);
|
||||
enterPasswordDialog(sessionId, dialogManager);
|
||||
} else if (type == 'session-login' || type == 'session-re-login') {
|
||||
enterUserLoginDialog(id, dialogManager);
|
||||
enterUserLoginDialog(sessionId, dialogManager);
|
||||
} else if (type == 'session-login-password' ||
|
||||
type == 'session-login-password') {
|
||||
enterUserLoginAndPasswordDialog(id, dialogManager);
|
||||
enterUserLoginAndPasswordDialog(sessionId, dialogManager);
|
||||
} else if (type == 'restarting') {
|
||||
showMsgBox(id, type, title, text, link, false, dialogManager,
|
||||
showMsgBox(sessionId, type, title, text, link, false, dialogManager,
|
||||
hasCancel: false);
|
||||
} else if (type == 'wait-remote-accept-nook') {
|
||||
showWaitAcceptDialog(id, type, title, text, dialogManager);
|
||||
showWaitAcceptDialog(sessionId, type, title, text, dialogManager);
|
||||
} else if (type == 'on-uac' || type == 'on-foreground-elevated') {
|
||||
showOnBlockDialog(id, type, title, text, dialogManager);
|
||||
showOnBlockDialog(sessionId, type, title, text, dialogManager);
|
||||
} else if (type == 'wait-uac') {
|
||||
showWaitUacDialog(id, dialogManager, type);
|
||||
showWaitUacDialog(sessionId, dialogManager, type);
|
||||
} else if (type == 'elevation-error') {
|
||||
showElevationError(id, type, title, text, dialogManager);
|
||||
showElevationError(sessionId, type, title, text, dialogManager);
|
||||
} else if (type == 'relay-hint') {
|
||||
showRelayHintDialog(id, type, title, text, dialogManager);
|
||||
showRelayHintDialog(sessionId, type, title, text, dialogManager);
|
||||
} else {
|
||||
var hasRetry = evt['hasRetry'] == 'true';
|
||||
showMsgBox(id, type, title, text, link, hasRetry, dialogManager);
|
||||
showMsgBox(sessionId, type, title, text, link, hasRetry, dialogManager);
|
||||
}
|
||||
}
|
||||
|
||||
/// Show a message box with [type], [title] and [text].
|
||||
showMsgBox(String id, String type, String title, String text, String link,
|
||||
bool hasRetry, OverlayDialogManager dialogManager,
|
||||
showMsgBox(SessionID sessionId, String type, String title, String text,
|
||||
String link, bool hasRetry, OverlayDialogManager dialogManager,
|
||||
{bool? hasCancel}) {
|
||||
msgBox(id, type, title, text, link, dialogManager,
|
||||
msgBox(sessionId, type, title, text, link, dialogManager,
|
||||
hasCancel: hasCancel, reconnect: reconnect);
|
||||
_timer?.cancel();
|
||||
if (hasRetry) {
|
||||
_timer = Timer(Duration(seconds: _reconnects), () {
|
||||
reconnect(dialogManager, id, false);
|
||||
reconnect(dialogManager, sessionId, false);
|
||||
});
|
||||
_reconnects *= 2;
|
||||
} else {
|
||||
@@ -378,17 +383,17 @@ class FfiModel with ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
void reconnect(
|
||||
OverlayDialogManager dialogManager, String id, bool forceRelay) {
|
||||
bind.sessionReconnect(id: id, forceRelay: forceRelay);
|
||||
void reconnect(OverlayDialogManager dialogManager, SessionID sessionId,
|
||||
bool forceRelay) {
|
||||
bind.sessionReconnect(sessionId: sessionId, forceRelay: forceRelay);
|
||||
clearPermissions();
|
||||
dialogManager.showLoading(translate('Connecting...'),
|
||||
onCancel: closeConnection);
|
||||
}
|
||||
|
||||
void showRelayHintDialog(String id, String type, String title, String text,
|
||||
OverlayDialogManager dialogManager) {
|
||||
dialogManager.show(tag: '$id-$type', (setState, close, context) {
|
||||
void showRelayHintDialog(SessionID sessionId, String type, String title,
|
||||
String text, OverlayDialogManager dialogManager) {
|
||||
dialogManager.show(tag: '$sessionId-$type', (setState, close, context) {
|
||||
onClose() {
|
||||
closeConnection();
|
||||
close();
|
||||
@@ -403,15 +408,17 @@ class FfiModel with ChangeNotifier {
|
||||
actions: [
|
||||
dialogButton('Close', onPressed: onClose, isOutline: true),
|
||||
dialogButton('Retry',
|
||||
onPressed: () => reconnect(dialogManager, id, false)),
|
||||
onPressed: () => reconnect(dialogManager, sessionId, false)),
|
||||
dialogButton('Connect via relay',
|
||||
onPressed: () => reconnect(dialogManager, id, true),
|
||||
onPressed: () => reconnect(dialogManager, sessionId, true),
|
||||
buttonStyle: style),
|
||||
dialogButton('Always connect via relay', onPressed: () {
|
||||
const option = 'force-always-relay';
|
||||
bind.sessionPeerOption(
|
||||
id: id, name: option, value: bool2option(option, true));
|
||||
reconnect(dialogManager, id, true);
|
||||
sessionId: sessionId,
|
||||
name: option,
|
||||
value: bool2option(option, true));
|
||||
reconnect(dialogManager, sessionId, true);
|
||||
}, buttonStyle: style),
|
||||
],
|
||||
onCancel: onClose,
|
||||
@@ -419,13 +426,14 @@ class FfiModel with ChangeNotifier {
|
||||
});
|
||||
}
|
||||
|
||||
_updateSessionWidthHeight(String id) {
|
||||
_updateSessionWidthHeight(SessionID sessionId) {
|
||||
parent.target?.canvasModel.updateViewStyle();
|
||||
if (display.width <= 0 || display.height <= 0) {
|
||||
debugPrintStack(
|
||||
label: 'invalid display size (${display.width},${display.height})');
|
||||
} else {
|
||||
bind.sessionSetSize(id: id, width: display.width, height: display.height);
|
||||
bind.sessionSetSize(
|
||||
sessionId: sessionId, width: display.width, height: display.height);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -461,8 +469,9 @@ class FfiModel with ChangeNotifier {
|
||||
.showMobileActionsOverlay(ffi: parent.target!));
|
||||
}
|
||||
} else {
|
||||
_touchMode =
|
||||
await bind.sessionGetOption(id: peerId, arg: 'touch-mode') != '';
|
||||
_touchMode = await bind.sessionGetOption(
|
||||
sessionId: sessionId, arg: 'touch-mode') !=
|
||||
'';
|
||||
}
|
||||
|
||||
if (connType == ConnType.fileTransfer) {
|
||||
@@ -476,7 +485,7 @@ class FfiModel with ChangeNotifier {
|
||||
stateGlobal.displaysCount.value = _pi.displays.length;
|
||||
if (_pi.currentDisplay < _pi.displays.length) {
|
||||
_display = _pi.displays[_pi.currentDisplay];
|
||||
_updateSessionWidthHeight(peerId);
|
||||
_updateSessionWidthHeight(sessionId);
|
||||
}
|
||||
if (displays.isNotEmpty) {
|
||||
parent.target?.dialogManager.showLoading(
|
||||
@@ -491,8 +500,10 @@ class FfiModel with ChangeNotifier {
|
||||
parent.target?.elevationModel.onPeerInfo(_pi);
|
||||
}
|
||||
if (connType == ConnType.defaultConn) {
|
||||
setViewOnly(peerId,
|
||||
bind.sessionGetToggleOptionSync(id: peerId, arg: 'view-only'));
|
||||
setViewOnly(
|
||||
peerId,
|
||||
bind.sessionGetToggleOptionSync(
|
||||
sessionId: sessionId, arg: 'view-only'));
|
||||
}
|
||||
if (connType == ConnType.defaultConn) {
|
||||
final platform_additions = evt['platform_additions'];
|
||||
@@ -547,7 +558,7 @@ class FfiModel with ChangeNotifier {
|
||||
}
|
||||
|
||||
/// Handle the peer info synchronization event based on [evt].
|
||||
handleSyncPeerInfo(Map<String, dynamic> evt, String peerId) async {
|
||||
handleSyncPeerInfo(Map<String, dynamic> evt, SessionID sessionId) async {
|
||||
if (evt['displays'] != null) {
|
||||
List<dynamic> displays = json.decode(evt['displays']);
|
||||
List<Display> newDisplays = [];
|
||||
@@ -557,7 +568,7 @@ class FfiModel with ChangeNotifier {
|
||||
_pi.displays = newDisplays;
|
||||
stateGlobal.displaysCount.value = _pi.displays.length;
|
||||
if (_pi.currentDisplay >= 0 && _pi.currentDisplay < _pi.displays.length) {
|
||||
_updateCurDisplay(peerId, _pi.displays[_pi.currentDisplay]);
|
||||
_updateCurDisplay(sessionId, _pi.displays[_pi.currentDisplay]);
|
||||
}
|
||||
}
|
||||
notifyListeners();
|
||||
@@ -573,11 +584,12 @@ class FfiModel with ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
updatePrivacyMode(Map<String, dynamic> evt, String peerId) {
|
||||
updatePrivacyMode(
|
||||
Map<String, dynamic> evt, SessionID sessionId, String peerId) {
|
||||
notifyListeners();
|
||||
try {
|
||||
PrivacyModeState.find(peerId).value =
|
||||
bind.sessionGetToggleOptionSync(id: peerId, arg: 'privacy-mode');
|
||||
PrivacyModeState.find(peerId).value = bind.sessionGetToggleOptionSync(
|
||||
sessionId: sessionId, arg: 'privacy-mode');
|
||||
} catch (e) {
|
||||
//
|
||||
}
|
||||
@@ -592,8 +604,8 @@ class FfiModel with ChangeNotifier {
|
||||
if (value) {
|
||||
ShowRemoteCursorState.find(id).value = value;
|
||||
} else {
|
||||
ShowRemoteCursorState.find(id).value =
|
||||
bind.sessionGetToggleOptionSync(id: id, arg: 'show-remote-cursor');
|
||||
ShowRemoteCursorState.find(id).value = bind.sessionGetToggleOptionSync(
|
||||
sessionId: sessionId, arg: 'show-remote-cursor');
|
||||
}
|
||||
} catch (e) {
|
||||
//
|
||||
@@ -612,11 +624,15 @@ class ImageModel with ChangeNotifier {
|
||||
|
||||
String id = '';
|
||||
|
||||
late final SessionID sessionId;
|
||||
|
||||
WeakReference<FFI> parent;
|
||||
|
||||
final List<Function(String)> callbacksOnFirstImage = [];
|
||||
|
||||
ImageModel(this.parent);
|
||||
ImageModel(this.parent) {
|
||||
sessionId = parent.target!.sessionId;
|
||||
}
|
||||
|
||||
addCallbackOnFirstImage(Function(String) cb) => callbacksOnFirstImage.add(cb);
|
||||
|
||||
@@ -645,7 +661,7 @@ class ImageModel with ChangeNotifier {
|
||||
isWeb ? ui.PixelFormat.rgba8888 : ui.PixelFormat.bgra8888,
|
||||
onPixelsCopied: () {
|
||||
// Unlock the rgba memory from rust codes.
|
||||
platformFFI.nextRgba(id);
|
||||
platformFFI.nextRgba(sessionId);
|
||||
}).then((image) {
|
||||
if (parent.target?.id != pid) return;
|
||||
try {
|
||||
@@ -674,7 +690,7 @@ class ImageModel with ChangeNotifier {
|
||||
await initializeCursorAndCanvas(parent.target!);
|
||||
}
|
||||
if (parent.target?.ffiModel.isPeerAndroid ?? false) {
|
||||
bind.sessionSetViewStyle(id: id, value: 'adaptive');
|
||||
bind.sessionSetViewStyle(sessionId: sessionId, value: 'adaptive');
|
||||
parent.target?.canvasModel.updateViewStyle();
|
||||
}
|
||||
}
|
||||
@@ -793,6 +809,7 @@ class CanvasModel with ChangeNotifier {
|
||||
// double windowBorderWidth = 0.0;
|
||||
// remote id
|
||||
String id = '';
|
||||
late final SessionID sessionId;
|
||||
// scroll offset x percent
|
||||
double _scrollX = 0.0;
|
||||
// scroll offset y percent
|
||||
@@ -804,7 +821,9 @@ class CanvasModel with ChangeNotifier {
|
||||
|
||||
WeakReference<FFI> parent;
|
||||
|
||||
CanvasModel(this.parent);
|
||||
CanvasModel(this.parent) {
|
||||
sessionId = parent.target!.sessionId;
|
||||
}
|
||||
|
||||
double get x => _x;
|
||||
double get y => _y;
|
||||
@@ -847,7 +866,7 @@ class CanvasModel with ChangeNotifier {
|
||||
return Size(w < 0 ? 0 : w, h < 0 ? 0 : h);
|
||||
}
|
||||
|
||||
final style = await bind.sessionGetViewStyle(id: id);
|
||||
final style = await bind.sessionGetViewStyle(sessionId: sessionId);
|
||||
if (style == null) {
|
||||
return;
|
||||
}
|
||||
@@ -883,7 +902,7 @@ class CanvasModel with ChangeNotifier {
|
||||
}
|
||||
|
||||
updateScrollStyle() async {
|
||||
final style = await bind.sessionGetScrollStyle(id: id);
|
||||
final style = await bind.sessionGetScrollStyle(sessionId: sessionId);
|
||||
if (style == kRemoteScrollStyleBar) {
|
||||
_scrollStyle = ScrollStyle.scrollbar;
|
||||
_resetScroll();
|
||||
@@ -1358,8 +1377,8 @@ class CursorModel with ChangeNotifier {
|
||||
Future<bool> _updateCache(
|
||||
Uint8List rgba, ui.Image image, int id, int w, int h) async {
|
||||
Uint8List? data;
|
||||
img2.Image imgOrigin =
|
||||
img2.Image.fromBytes(width: w, height:h, bytes: rgba.buffer, order: img2.ChannelOrder.rgba);
|
||||
img2.Image imgOrigin = img2.Image.fromBytes(
|
||||
width: w, height: h, bytes: rgba.buffer, order: img2.ChannelOrder.rgba);
|
||||
if (Platform.isWindows) {
|
||||
data = imgOrigin.getBytes(order: img2.ChannelOrder.bgra);
|
||||
} else {
|
||||
@@ -1474,9 +1493,9 @@ class QualityMonitorModel with ChangeNotifier {
|
||||
bool get show => _show;
|
||||
QualityMonitorData get data => _data;
|
||||
|
||||
checkShowQualityMonitor(String id) async {
|
||||
checkShowQualityMonitor(SessionID sessionId) async {
|
||||
final show = await bind.sessionGetToggleOption(
|
||||
id: id, arg: 'show-quality-monitor') ==
|
||||
sessionId: sessionId, arg: 'show-quality-monitor') ==
|
||||
true;
|
||||
if (_show != show) {
|
||||
_show = show;
|
||||
@@ -1510,32 +1529,35 @@ class RecordingModel with ChangeNotifier {
|
||||
|
||||
onSwitchDisplay() {
|
||||
if (isIOS || !_start) return;
|
||||
var id = parent.target?.id;
|
||||
final sessionId = parent.target?.sessionId;
|
||||
int? width = parent.target?.canvasModel.getDisplayWidth();
|
||||
int? height = parent.target?.canvasModel.getDisplayHeight();
|
||||
if (id == null || width == null || height == null) return;
|
||||
bind.sessionRecordScreen(id: id, start: true, width: width, height: height);
|
||||
if (sessionId == null || width == null || height == null) return;
|
||||
bind.sessionRecordScreen(
|
||||
sessionId: sessionId, start: true, width: width, height: height);
|
||||
}
|
||||
|
||||
toggle() {
|
||||
if (isIOS) return;
|
||||
var id = parent.target?.id;
|
||||
if (id == null) return;
|
||||
final sessionId = parent.target?.sessionId;
|
||||
if (sessionId == null) return;
|
||||
_start = !_start;
|
||||
notifyListeners();
|
||||
if (_start) {
|
||||
bind.sessionRefresh(id: id);
|
||||
bind.sessionRefresh(sessionId: sessionId);
|
||||
} else {
|
||||
bind.sessionRecordScreen(id: id, start: false, width: 0, height: 0);
|
||||
bind.sessionRecordScreen(
|
||||
sessionId: sessionId, start: false, width: 0, height: 0);
|
||||
}
|
||||
}
|
||||
|
||||
onClose() {
|
||||
if (isIOS) return;
|
||||
var id = parent.target?.id;
|
||||
if (id == null) return;
|
||||
final sessionId = parent.target?.sessionId;
|
||||
if (sessionId == null) return;
|
||||
_start = false;
|
||||
bind.sessionRecordScreen(id: id, start: false, width: 0, height: 0);
|
||||
bind.sessionRecordScreen(
|
||||
sessionId: sessionId, start: false, width: 0, height: 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1558,6 +1580,7 @@ enum ConnType { defaultConn, fileTransfer, portForward, rdp }
|
||||
|
||||
/// Flutter state manager and data communication with the Rust core.
|
||||
class FFI {
|
||||
final sessionId = Uuid().v4obj();
|
||||
var id = '';
|
||||
var version = '';
|
||||
var connType = ConnType.defaultConn;
|
||||
@@ -1610,10 +1633,8 @@ class FFI {
|
||||
assert(!(isFileTransfer && isPortForward), 'more than one connect type');
|
||||
if (isFileTransfer) {
|
||||
connType = ConnType.fileTransfer;
|
||||
id = 'ft_$id';
|
||||
} else if (isPortForward) {
|
||||
connType = ConnType.portForward;
|
||||
id = 'pf_$id';
|
||||
} else {
|
||||
chatModel.resetClientMode();
|
||||
connType = ConnType.defaultConn;
|
||||
@@ -1623,6 +1644,7 @@ class FFI {
|
||||
}
|
||||
// ignore: unused_local_variable
|
||||
final addRes = bind.sessionAddSync(
|
||||
sessionId: sessionId,
|
||||
id: id,
|
||||
isFileTransfer: isFileTransfer,
|
||||
isPortForward: isPortForward,
|
||||
@@ -1631,8 +1653,8 @@ class FFI {
|
||||
forceRelay: forceRelay ?? false,
|
||||
password: password ?? "",
|
||||
);
|
||||
final stream = bind.sessionStart(id: id);
|
||||
final cb = ffiModel.startEventListener(id);
|
||||
final stream = bind.sessionStart(sessionId: sessionId, id: id);
|
||||
final cb = ffiModel.startEventListener(sessionId, id);
|
||||
() async {
|
||||
final useTextureRender = bind.mainUseTextureRender();
|
||||
// Preserved for the rgba data.
|
||||
@@ -1664,11 +1686,11 @@ class FFI {
|
||||
}
|
||||
} else {
|
||||
// Fetch the image buffer from rust codes.
|
||||
final sz = platformFFI.getRgbaSize(id);
|
||||
final sz = platformFFI.getRgbaSize(sessionId);
|
||||
if (sz == null || sz == 0) {
|
||||
return;
|
||||
}
|
||||
final rgba = platformFFI.getRgba(id, sz);
|
||||
final rgba = platformFFI.getRgba(sessionId, sz);
|
||||
if (rgba != null) {
|
||||
imageModel.onRgba(rgba);
|
||||
}
|
||||
@@ -1682,10 +1704,10 @@ class FFI {
|
||||
}
|
||||
|
||||
/// Login with [password], choose if the client should [remember] it.
|
||||
void login(String osUsername, String osPassword, String id, String password,
|
||||
bool remember) {
|
||||
void login(String osUsername, String osPassword, SessionID sessionId,
|
||||
String password, bool remember) {
|
||||
bind.sessionLogin(
|
||||
id: id,
|
||||
sessionId: sessionId,
|
||||
osUsername: osUsername,
|
||||
osPassword: osPassword,
|
||||
password: password,
|
||||
@@ -1696,15 +1718,21 @@ class FFI {
|
||||
Future<void> close() async {
|
||||
chatModel.close();
|
||||
if (imageModel.image != null && !isWebDesktop) {
|
||||
await setCanvasConfig(id, cursorModel.x, cursorModel.y, canvasModel.x,
|
||||
canvasModel.y, canvasModel.scale, ffiModel.pi.currentDisplay);
|
||||
await setCanvasConfig(
|
||||
sessionId,
|
||||
cursorModel.x,
|
||||
cursorModel.y,
|
||||
canvasModel.x,
|
||||
canvasModel.y,
|
||||
canvasModel.scale,
|
||||
ffiModel.pi.currentDisplay);
|
||||
}
|
||||
imageModel.update(null);
|
||||
cursorModel.clear();
|
||||
ffiModel.clear();
|
||||
canvasModel.clear();
|
||||
inputModel.resetModifiers();
|
||||
await bind.sessionClose(id: id);
|
||||
await bind.sessionClose(sessionId: sessionId);
|
||||
debugPrint('model $id closed');
|
||||
id = '';
|
||||
}
|
||||
@@ -1795,8 +1823,14 @@ class PeerInfo {
|
||||
|
||||
const canvasKey = 'canvas';
|
||||
|
||||
Future<void> setCanvasConfig(String id, double xCursor, double yCursor,
|
||||
double xCanvas, double yCanvas, double scale, int currentDisplay) async {
|
||||
Future<void> setCanvasConfig(
|
||||
SessionID sessionId,
|
||||
double xCursor,
|
||||
double yCursor,
|
||||
double xCanvas,
|
||||
double yCanvas,
|
||||
double scale,
|
||||
int currentDisplay) async {
|
||||
final p = <String, dynamic>{};
|
||||
p['xCursor'] = xCursor;
|
||||
p['yCursor'] = yCursor;
|
||||
@@ -1804,12 +1838,14 @@ Future<void> setCanvasConfig(String id, double xCursor, double yCursor,
|
||||
p['yCanvas'] = yCanvas;
|
||||
p['scale'] = scale;
|
||||
p['currentDisplay'] = currentDisplay;
|
||||
await bind.sessionSetFlutterConfig(id: id, k: canvasKey, v: jsonEncode(p));
|
||||
await bind.sessionSetFlutterConfig(
|
||||
sessionId: sessionId, k: canvasKey, v: jsonEncode(p));
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>?> getCanvasConfig(String id) async {
|
||||
Future<Map<String, dynamic>?> getCanvasConfig(SessionID sessionId) async {
|
||||
if (!isWebDesktop) return null;
|
||||
var p = await bind.sessionGetFlutterConfig(id: id, k: canvasKey);
|
||||
var p =
|
||||
await bind.sessionGetFlutterConfig(sessionId: sessionId, k: canvasKey);
|
||||
if (p == null || p.isEmpty) return null;
|
||||
try {
|
||||
Map<String, dynamic> m = json.decode(p);
|
||||
@@ -1819,12 +1855,8 @@ Future<Map<String, dynamic>?> getCanvasConfig(String id) async {
|
||||
}
|
||||
}
|
||||
|
||||
void removePreference(String id) async {
|
||||
await bind.sessionSetFlutterConfig(id: id, k: canvasKey, v: '');
|
||||
}
|
||||
|
||||
Future<void> initializeCursorAndCanvas(FFI ffi) async {
|
||||
var p = await getCanvasConfig(ffi.id);
|
||||
var p = await getCanvasConfig(ffi.sessionId);
|
||||
int currentDisplay = 0;
|
||||
if (p != null) {
|
||||
currentDisplay = p['currentDisplay'];
|
||||
|
||||
@@ -104,9 +104,10 @@ class PlatformFFI {
|
||||
return res;
|
||||
}
|
||||
|
||||
Uint8List? getRgba(String id, int bufSize) {
|
||||
Uint8List? getRgba(SessionID sessionId, int bufSize) {
|
||||
if (_session_get_rgba == null) return null;
|
||||
var a = id.toNativeUtf8();
|
||||
final sessionIdStr = sessionId.toString();
|
||||
var a = sessionIdStr.toNativeUtf8();
|
||||
try {
|
||||
final buffer = _session_get_rgba!(a);
|
||||
if (buffer == nullptr) {
|
||||
@@ -119,24 +120,27 @@ class PlatformFFI {
|
||||
}
|
||||
}
|
||||
|
||||
int? getRgbaSize(String id) {
|
||||
int? getRgbaSize(SessionID sessionId) {
|
||||
if (_session_get_rgba_size == null) return null;
|
||||
var a = id.toNativeUtf8();
|
||||
final sessionIdStr = sessionId.toString();
|
||||
var a = sessionIdStr.toNativeUtf8();
|
||||
final bufferSize = _session_get_rgba_size!(a);
|
||||
malloc.free(a);
|
||||
return bufferSize;
|
||||
}
|
||||
|
||||
void nextRgba(String id) {
|
||||
void nextRgba(SessionID sessionId) {
|
||||
if (_session_next_rgba == null) return;
|
||||
final a = id.toNativeUtf8();
|
||||
final sessionIdStr = sessionId.toString();
|
||||
final a = sessionIdStr.toNativeUtf8();
|
||||
_session_next_rgba!(a);
|
||||
malloc.free(a);
|
||||
}
|
||||
|
||||
void registerTexture(String id, int ptr) {
|
||||
void registerTexture(SessionID sessionId, int ptr) {
|
||||
if (_session_register_texture == null) return;
|
||||
final a = id.toNativeUtf8();
|
||||
final sessionIdStr = sessionId.toString();
|
||||
final a = sessionIdStr.toNativeUtf8();
|
||||
_session_register_texture!(a, ptr);
|
||||
malloc.free(a);
|
||||
}
|
||||
|
||||
@@ -343,7 +343,7 @@ class ServerModel with ChangeNotifier {
|
||||
Future<void> startService() async {
|
||||
_isStart = true;
|
||||
notifyListeners();
|
||||
parent.target?.ffiModel.updateEventListener("");
|
||||
parent.target?.ffiModel.updateEventListener(parent.target!.sessionId, "");
|
||||
await parent.target?.invokeMethod("init_service");
|
||||
// ugly is here, because for desktop, below is useless
|
||||
await bind.mainStartService();
|
||||
|
||||
Reference in New Issue
Block a user