From adafa38cfadc263255be9bd38b7d43339ed77238 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 8 Sep 2022 21:03:20 -0700 Subject: [PATCH 1/4] flutter_desktop: change cursor on scroll auto Signed-off-by: fufesou --- flutter/lib/desktop/pages/remote_page.dart | 28 +++++++++++---------- flutter/lib/desktop/widgets/popup_menu.dart | 2 +- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart index c03c2f3d4..96ade40f4 100644 --- a/flutter/lib/desktop/pages/remote_page.dart +++ b/flutter/lib/desktop/pages/remote_page.dart @@ -537,8 +537,17 @@ class ImagePaint extends StatelessWidget { Widget build(BuildContext context) { final m = Provider.of(context); var c = Provider.of(context); - final s = c.scale; + + mouseRegion({child}) => Obx(() => MouseRegion( + cursor: (cursorOverImage.isTrue && keyboardEnabled.isTrue) + ? (remoteCursorMoved.isTrue + ? SystemMouseCursors.none + : _buildCustomCursorLinux(context, s)) + : MouseCursor.defer, + onHover: (evt) {}, + child: child)); + if (c.scrollStyle == ScrollStyle.scrollbar) { final imageWidget = SizedBox( width: c.getDisplayWidth() * s, @@ -547,7 +556,6 @@ class ImagePaint extends StatelessWidget { painter: ImagePainter(image: m.image, x: 0, y: 0, scale: s), )); - Rx pos = Rx(const Offset(0.0, 0.0)); return Center( child: NotificationListener( onNotification: (notification) { @@ -562,16 +570,8 @@ class ImagePaint extends StatelessWidget { c.setScrollPercent(percentX, percentY); return false; }, - child: Obx(() => MouseRegion( - cursor: (cursorOverImage.isTrue && keyboardEnabled.isTrue) - ? (remoteCursorMoved.isTrue - ? SystemMouseCursors.none - : _buildCustomCursorLinux(context, s)) - : MouseCursor.defer, - onHover: (evt) { - pos.value = evt.position; - }, - child: _buildCrossScrollbar(_buildListener(imageWidget)))), + child: mouseRegion( + child: _buildCrossScrollbar(_buildListener(imageWidget))), ), ); } else { @@ -582,7 +582,7 @@ class ImagePaint extends StatelessWidget { painter: ImagePainter(image: m.image, x: c.x / s, y: c.y / s, scale: s), )); - return _buildListener(imageWidget); + return mouseRegion(child: _buildListener(imageWidget)); } } @@ -594,6 +594,8 @@ class ImagePaint extends StatelessWidget { } else { final key = cacheLinux.key(scale); cursor.addKeyLinux(key); + // debugPrint( + // 'REMOVE ME ================================= linux curor key: $key'); return FlutterCustomMemoryImageCursor( pixbuf: cacheLinux.data, key: key, diff --git a/flutter/lib/desktop/widgets/popup_menu.dart b/flutter/lib/desktop/widgets/popup_menu.dart index 02376ff71..3814561ee 100644 --- a/flutter/lib/desktop/widgets/popup_menu.dart +++ b/flutter/lib/desktop/widgets/popup_menu.dart @@ -8,7 +8,7 @@ import './material_mod_popup_menu.dart' as mod_menu; // https://stackoverflow.com/questions/68318314/flutter-popup-menu-inside-popup-menu class PopupMenuChildrenItem extends mod_menu.PopupMenuEntry { - PopupMenuChildrenItem({ + const PopupMenuChildrenItem({ key, this.height = kMinInteractiveDimension, this.padding, From ef0980a9b1535e02cfbf1c9774d49b1e0fc0275c Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 8 Sep 2022 21:05:26 -0700 Subject: [PATCH 2/4] flutter_desktop: fix local cursor (hotx,hoty) offset Signed-off-by: fufesou --- flutter/lib/desktop/pages/remote_page.dart | 4 ++-- flutter/lib/models/model.dart | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart index 96ade40f4..3d47dd1ce 100644 --- a/flutter/lib/desktop/pages/remote_page.dart +++ b/flutter/lib/desktop/pages/remote_page.dart @@ -599,8 +599,8 @@ class ImagePaint extends StatelessWidget { return FlutterCustomMemoryImageCursor( pixbuf: cacheLinux.data, key: key, - hotx: cacheLinux.hotx, - hoty: cacheLinux.hoty, + hotx: 0.0, + hoty: 0.0, imageWidth: (cacheLinux.width * scale).toInt(), imageHeight: (cacheLinux.height * scale).toInt(), ); diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index e907f3ded..6d8d68281 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -619,7 +619,7 @@ class CursorData { int _doubleToInt(double v) => (v * 10e6).round().toInt(); String key(double scale) => - '${peerId}_${id}_${_doubleToInt(hotx)}_${_doubleToInt(hoty)}_${_doubleToInt(width * scale)}_${_doubleToInt(height * scale)}'; + '${peerId}_${id}_${_doubleToInt(width * scale)}_${_doubleToInt(height * scale)}'; } class CursorModel with ChangeNotifier { From aa6e747e8aebb707ad756d2b5c432e235a32a0e8 Mon Sep 17 00:00:00 2001 From: fufesou Date: Sat, 10 Sep 2022 19:50:48 -0700 Subject: [PATCH 3/4] flutter_desktop: cursor image cache mismatch Signed-off-by: fufesou --- flutter/lib/common.dart | 2 + flutter/lib/desktop/pages/remote_page.dart | 4 +- flutter/lib/models/model.dart | 63 ++++++++++------------ flutter/lib/models/native_model.dart | 26 ++++----- flutter/lib/utils/image.dart | 49 +++++++++++++++++ 5 files changed, 94 insertions(+), 50 deletions(-) create mode 100644 flutter/lib/utils/image.dart diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index 249b45a0c..73334baae 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -33,6 +33,8 @@ late final DesktopType? desktopType; typedef F = String Function(String); typedef FMethod = String Function(String, dynamic); +typedef StreamEventHandler = Future Function(Map); + late final iconKeyboard = MemoryImage(Uint8List.fromList(base64Decode( "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAgVBMVEUAAAD///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9d3yJTAAAAKnRSTlMA0Gd/0y8ILZgbJffDPUwV2nvzt+TMqZxyU7CMb1pYQyzsvKunkXE4AwJnNC24AAAA+0lEQVQ4y83O2U7DMBCF4ZMxk9rZk26kpQs7nPd/QJy4EiLbLf01N5Y/2YP/qxDFQvGB5NPC/ZpVnfJx4b5xyGfF95rkHvNCWH1u+N6J6T0sC7gqRy8uGPfBLEbozPXUjlkQKwGaFPNizwQbwkx0TDvhCii34ExZCSQVBdzIOEOyeclSHgBGXkpeygXSQgStACtWx4Z8rr8COHOvfEP/IbbsQAToFUAAV1M408IIjIGYAPoCSNRP7DQutfQTqxuAiH7UUg1FaJR2AGrrx52sK2ye28LZ0wBAEyR6y8X+NADhm1B4fgiiHXbRrTrxpwEY9RdM9wsepnvFHfUDwYEeiwAJr/gAAAAASUVORK5CYII="))); late final iconClipboard = MemoryImage(Uint8List.fromList(base64Decode( diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart index 3d47dd1ce..4321376a2 100644 --- a/flutter/lib/desktop/pages/remote_page.dart +++ b/flutter/lib/desktop/pages/remote_page.dart @@ -594,8 +594,8 @@ class ImagePaint extends StatelessWidget { } else { final key = cacheLinux.key(scale); cursor.addKeyLinux(key); - // debugPrint( - // 'REMOVE ME ================================= linux curor key: $key'); + debugPrint( + 'REMOVE ME ================================= linux curor key: $key'); return FlutterCustomMemoryImageCursor( pixbuf: cacheLinux.data, key: key, diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index 6d8d68281..303157247 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -4,7 +4,6 @@ import 'dart:io'; import 'dart:math'; import 'dart:typed_data'; import 'dart:ui' as ui; -import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -21,6 +20,7 @@ import 'package:flutter_custom_cursor/flutter_custom_cursor.dart'; import '../common.dart'; import '../common/shared_state.dart'; +import '../utils/image.dart' as img; import '../mobile/widgets/dialog.dart'; import 'peer_model.dart'; import 'platform_model.dart'; @@ -127,8 +127,8 @@ class FfiModel with ChangeNotifier { _permissions.clear(); } - void Function(Map) startEventListener(String peerId) { - return (evt) { + StreamEventHandler startEventListener(String peerId) { + return (evt) async { var name = evt['name']; if (name == 'msgbox') { handleMsgBox(evt, peerId); @@ -140,11 +140,11 @@ class FfiModel with ChangeNotifier { } else if (name == 'switch_display') { handleSwitchDisplay(evt); } else if (name == 'cursor_data') { - parent.target?.cursorModel.updateCursorData(evt); + await parent.target?.cursorModel.updateCursorData(evt); } else if (name == 'cursor_id') { - parent.target?.cursorModel.updateCursorId(evt); + await parent.target?.cursorModel.updateCursorId(evt); } else if (name == 'cursor_position') { - parent.target?.cursorModel.updateCursorPosition(evt, peerId); + await parent.target?.cursorModel.updateCursorPosition(evt, peerId); } else if (name == 'clipboard') { Clipboard.setData(ClipboardData(text: evt['content'])); } else if (name == 'permission') { @@ -780,7 +780,7 @@ class CursorModel with ChangeNotifier { notifyListeners(); } - void updateCursorData(Map evt) { + updateCursorData(Map evt) async { var id = int.parse(evt['id']); _hotx = double.parse(evt['hotx']); _hoty = double.parse(evt['hoty']); @@ -789,34 +789,26 @@ class CursorModel with ChangeNotifier { List colors = json.decode(evt['colors']); final rgba = Uint8List.fromList(colors.map((s) => s as int).toList()); var pid = parent.target?.id; - ui.decodeImageFromPixels(rgba, width, height, ui.PixelFormat.rgba8888, - (image) { - () async { - if (parent.target?.id != pid) return; - _image = image; - _images[id] = Tuple3(image, _hotx, _hoty); - _updateCacheLinux(image, id, width, height); - try { - // my throw exception, because the listener maybe already dispose - notifyListeners(); - } catch (e) { - debugPrint('notify cursor: $e'); - } - }(); - }); + + final image = await img.decodeImageFromPixels( + rgba, width, height, ui.PixelFormat.rgba8888); + if (parent.target?.id != pid) return; + _image = image; + _images[id] = Tuple3(image, _hotx, _hoty); + await _updateCacheLinux(image, id, width, height); + try { + // my throw exception, because the listener maybe already dispose + notifyListeners(); + } catch (e) { + debugPrint('notify cursor: $e'); + } } - void _updateCacheLinux(ui.Image image, int id, int w, int h) async { - final data = await image.toByteData(format: ImageByteFormat.png); - late Uint8List? dataLinux; - if (data != null) { - dataLinux = data.buffer.asUint8List(); - } else { - dataLinux = null; - } + _updateCacheLinux(ui.Image image, int id, int w, int h) async { + final data = await image.toByteData(format: ui.ImageByteFormat.png); _cacheLinux = CursorData( peerId: this.id, - data: dataLinux, + data: data?.buffer.asUint8List(), id: id, hotx: _hotx, hoty: _hoty, @@ -826,9 +818,10 @@ class CursorModel with ChangeNotifier { _cacheMapLinux[id] = _cacheLinux!; } - void updateCursorId(Map evt) { - _cacheLinux = _cacheMapLinux[int.parse(evt['id'])]; - final tmp = _images[int.parse(evt['id'])]; + updateCursorId(Map evt) async { + final id = int.parse(evt['id']); + _cacheLinux = _cacheMapLinux[id]; + final tmp = _images[id]; if (tmp != null) { _image = tmp.item1; _hotx = tmp.item2; @@ -838,7 +831,7 @@ class CursorModel with ChangeNotifier { } /// Update the cursor position. - void updateCursorPosition(Map evt, String id) { + updateCursorPosition(Map evt, String id) async { _x = double.parse(evt['x']); _y = double.parse(evt['y']); try { diff --git a/flutter/lib/models/native_model.dart b/flutter/lib/models/native_model.dart index 0d356a7c2..a9081a160 100644 --- a/flutter/lib/models/native_model.dart +++ b/flutter/lib/models/native_model.dart @@ -30,15 +30,15 @@ class PlatformFFI { String _dir = ''; String _homeDir = ''; F2? _translate; - final _eventHandlers = Map>(); + final _eventHandlers = >{}; late RustdeskImpl _ffiBind; late String _appType; - void Function(Map)? _eventCallback; + StreamEventHandler? _eventCallback; PlatformFFI._(); static final PlatformFFI instance = PlatformFFI._(); - final _toAndroidChannel = MethodChannel("mChannel"); + final _toAndroidChannel = const MethodChannel("mChannel"); RustdeskImpl get ffiBind => _ffiBind; @@ -88,7 +88,7 @@ class PlatformFFI { } /// Init the FFI class, loads the native Rust core library. - Future init(String appType) async { + Future init(String appType) async { _appType = appType; // if (isDesktop) { // // TODO @@ -117,7 +117,7 @@ class PlatformFFI { _homeDir = (await getDownloadsDirectory())?.path ?? ""; } } catch (e) { - print("initialize failed: $e"); + debugPrint('initialize failed: $e'); } String id = 'NA'; String name = 'Flutter'; @@ -144,14 +144,14 @@ class PlatformFFI { name = macOsInfo.computerName; id = macOsInfo.systemGUID ?? ""; } - print( - "_appType:$_appType,info1-id:$id,info2-name:$name,dir:$_dir,homeDir:$_homeDir"); + debugPrint( + '_appType:$_appType,info1-id:$id,info2-name:$name,dir:$_dir,homeDir:$_homeDir'); await _ffiBind.mainDeviceId(id: id); await _ffiBind.mainDeviceName(name: name); await _ffiBind.mainSetHomeDir(home: _homeDir); await _ffiBind.mainInit(appDir: _dir); } catch (e) { - print("initialize failed: $e"); + debugPrint('initialize failed: $e'); } version = await getVersion(); } @@ -162,9 +162,9 @@ class PlatformFFI { final handlers = _eventHandlers[name]; if (handlers != null) { if (handlers.isNotEmpty) { - handlers.values.forEach((handler) { + for (var handler in handlers.values) { handler(evt); - }); + } return true; } } @@ -182,17 +182,17 @@ class PlatformFFI { // _tryHandle here may be more flexible than _eventCallback if (!_tryHandle(event)) { if (_eventCallback != null) { - _eventCallback!(event); + await _eventCallback!(event); } } } catch (e) { - print('json.decode fail(): $e'); + debugPrint('json.decode fail(): $e'); } } }(); } - void setEventCallback(void Function(Map) fun) async { + void setEventCallback(StreamEventHandler fun) async { _eventCallback = fun; } diff --git a/flutter/lib/utils/image.dart b/flutter/lib/utils/image.dart new file mode 100644 index 000000000..e92fdc6e5 --- /dev/null +++ b/flutter/lib/utils/image.dart @@ -0,0 +1,49 @@ +import 'dart:typed_data'; +import 'dart:ui' as ui; + +Future decodeImageFromPixels( + Uint8List pixels, + int width, + int height, + ui.PixelFormat format, { + int? rowBytes, + int? targetWidth, + int? targetHeight, + bool allowUpscaling = true, +}) async { + if (targetWidth != null) { + assert(allowUpscaling || targetWidth <= width); + } + if (targetHeight != null) { + assert(allowUpscaling || targetHeight <= height); + } + + final ui.ImmutableBuffer buffer = + await ui.ImmutableBuffer.fromUint8List(pixels); + final ui.ImageDescriptor descriptor = ui.ImageDescriptor.raw( + buffer, + width: width, + height: height, + rowBytes: rowBytes, + pixelFormat: format, + ); + if (!allowUpscaling) { + if (targetWidth != null && targetWidth! > descriptor.width) { + targetWidth = descriptor.width; + } + if (targetHeight != null && targetHeight! > descriptor.height) { + targetHeight = descriptor.height; + } + } + + final ui.Codec codec = await descriptor.instantiateCodec( + targetWidth: targetWidth, + targetHeight: targetHeight, + ); + + final ui.FrameInfo frameInfo = await codec.getNextFrame(); + codec.dispose(); + buffer.dispose(); + descriptor.dispose(); + return frameInfo.image; +} From efe6d080f37b9d371f95224257f098a284df95fa Mon Sep 17 00:00:00 2001 From: fufesou Date: Sun, 11 Sep 2022 19:52:38 -0700 Subject: [PATCH 4/4] flutter_desktop: set event func to async Signed-off-by: fufesou --- flutter/lib/desktop/pages/remote_page.dart | 2 - flutter/lib/main.dart | 4 +- flutter/lib/mobile/pages/remote_page.dart | 5 +- flutter/lib/models/model.dart | 55 ++++++++++------------ flutter/lib/models/native_model.dart | 8 ++-- flutter/lib/models/peer_model.dart | 4 +- flutter/lib/utils/image.dart | 4 +- 7 files changed, 37 insertions(+), 45 deletions(-) diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart index 4321376a2..34c365d68 100644 --- a/flutter/lib/desktop/pages/remote_page.dart +++ b/flutter/lib/desktop/pages/remote_page.dart @@ -594,8 +594,6 @@ class ImagePaint extends StatelessWidget { } else { final key = cacheLinux.key(scale); cursor.addKeyLinux(key); - debugPrint( - 'REMOVE ME ================================= linux curor key: $key'); return FlutterCustomMemoryImageCursor( pixbuf: cacheLinux.data, key: key, diff --git a/flutter/lib/main.dart b/flutter/lib/main.dart index 8efc7c6ad..0ae5b583d 100644 --- a/flutter/lib/main.dart +++ b/flutter/lib/main.dart @@ -273,13 +273,13 @@ _keepScaleBuilder() { _registerEventHandler() { if (desktopType != DesktopType.main) { - platformFFI.registerEventHandler('theme', 'theme', (evt) { + platformFFI.registerEventHandler('theme', 'theme', (evt) async { String? dark = evt['dark']; if (dark != null) { MyTheme.changeTo(dark == 'true'); } }); - platformFFI.registerEventHandler('language', 'language', (_) { + platformFFI.registerEventHandler('language', 'language', (_) async { Get.forceAppUpdate(); }); } diff --git a/flutter/lib/mobile/pages/remote_page.dart b/flutter/lib/mobile/pages/remote_page.dart index 419a98f3a..dd3742d32 100644 --- a/flutter/lib/mobile/pages/remote_page.dart +++ b/flutter/lib/mobile/pages/remote_page.dart @@ -1085,9 +1085,8 @@ void showOptions(String id, OverlayDialogManager dialogManager) async { mainAxisSize: MainAxisSize.min, children: displays + [ - getRadio('Original', 'original', viewStyle, setViewStyle), - getRadio('Shrink', 'shrink', viewStyle, setViewStyle), - getRadio('Stretch', 'stretch', viewStyle, setViewStyle), + getRadio('Scale Original', 'original', viewStyle, setViewStyle), + getRadio('Scale adaptive', 'adaptive', viewStyle, setViewStyle), Divider(color: MyTheme.border), getRadio('Good image quality', 'best', quality, setQuality), getRadio('Balanced', 'balanced', quality, setQuality), diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index 303157247..8416c5a8c 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -358,11 +358,11 @@ class ImageModel with ChangeNotifier { }); } - void update(ui.Image? image, double tabBarHeight) { + void update(ui.Image? image, double tabBarHeight) async { if (_image == null && image != null) { if (isWebDesktop || isDesktop) { - parent.target?.canvasModel.updateViewStyle(); - parent.target?.canvasModel.updateScrollStyle(); + await parent.target?.canvasModel.updateViewStyle(); + await parent.target?.canvasModel.updateScrollStyle(); } else { final size = MediaQueryData.fromWindow(ui.window).size; final canvasWidth = size.width; @@ -372,14 +372,12 @@ class ImageModel with ChangeNotifier { parent.target?.canvasModel.scale = min(xscale, yscale); } if (parent.target != null) { - initializeCursorAndCanvas(parent.target!); + await initializeCursorAndCanvas(parent.target!); + } + if (parent.target?.ffiModel.isPeerAndroid ?? false) { + bind.sessionPeerOption(id: _id, name: 'view-style', value: 'adaptive'); + parent.target?.canvasModel.updateViewStyle(); } - Future.delayed(Duration(milliseconds: 1), () { - if (parent.target?.ffiModel.isPeerAndroid ?? false) { - bind.sessionPeerOption(id: _id, name: 'view-style', value: 'shrink'); - parent.target?.canvasModel.updateViewStyle(); - } - }); } _image = image; if (image != null) notifyListeners(); @@ -445,7 +443,7 @@ class CanvasModel with ChangeNotifier { double get scrollX => _scrollX; double get scrollY => _scrollY; - void updateViewStyle() async { + updateViewStyle() async { final style = await bind.sessionGetOption(id: id, arg: 'view-style'); if (style == null) { return; @@ -457,7 +455,6 @@ class CanvasModel with ChangeNotifier { final s2 = size.height / getDisplayHeight(); _scale = s1 < s2 ? s1 : s2; } - _x = (size.width - getDisplayWidth() * _scale) / 2; _y = (size.height - getDisplayHeight() * _scale) / 2; notifyListeners(); @@ -475,7 +472,7 @@ class CanvasModel with ChangeNotifier { notifyListeners(); } - void update(double x, double y, double scale) { + update(double x, double y, double scale) { _x = x; _y = y; _scale = scale; @@ -508,19 +505,9 @@ class CanvasModel with ChangeNotifier { var dxOffset = 0; var dyOffset = 0; if (dw > size.width) { - final X_debugNanOrInfinite = x - dw * (x / size.width) - _x; - if (X_debugNanOrInfinite.isInfinite || X_debugNanOrInfinite.isNaN) { - debugPrint( - 'REMOVE ME ============================ X_debugNanOrInfinite $x,$dw,$_scale,${size.width},$_x'); - } dxOffset = (x - dw * (x / size.width) - _x).toInt(); } if (dh > size.height) { - final Y_debugNanOrInfinite = y - dh * (y / size.height) - _y; - if (Y_debugNanOrInfinite.isInfinite || Y_debugNanOrInfinite.isNaN) { - debugPrint( - 'REMOVE ME ============================ Y_debugNanOrInfinite $y,$dh,$_scale,${size.height},$_y'); - } dyOffset = (y - dh * (y / size.height) - _y).toInt(); } _x += dxOffset; @@ -789,7 +776,6 @@ class CursorModel with ChangeNotifier { List colors = json.decode(evt['colors']); final rgba = Uint8List.fromList(colors.map((s) => s as int).toList()); var pid = parent.target?.id; - final image = await img.decodeImageFromPixels( rgba, width, height, ui.PixelFormat.rgba8888); if (parent.target?.id != pid) return; @@ -1128,9 +1114,9 @@ class FFI { if (message is Event) { try { Map event = json.decode(message.field0); - cb(event); + await cb(event); } catch (e) { - print('json.decode fail(): $e'); + debugPrint('json.decode fail(): $e'); } } else if (message is Rgba) { imageModel.onRgba(message.field0, tabBarHeight); @@ -1292,6 +1278,15 @@ class Display { double y = 0; int width = 0; int height = 0; + + Display() { + width = (isDesktop || isWebDesktop) + ? kDesktopDefaultDisplayWidth + : kMobileDefaultDisplayWidth; + height = (isDesktop || isWebDesktop) + ? kDesktopDefaultDisplayHeight + : kMobileDefaultDisplayHeight; + } } class PeerInfo { @@ -1304,8 +1299,8 @@ class PeerInfo { List displays = []; } -Future savePreference(String id, double xCursor, double yCursor, - double xCanvas, double yCanvas, double scale, int currentDisplay) async { +savePreference(String id, double xCursor, double yCursor, double xCanvas, + double yCanvas, double scale, int currentDisplay) async { SharedPreferences prefs = await SharedPreferences.getInstance(); final p = {}; p['xCursor'] = xCursor; @@ -1326,12 +1321,12 @@ Future?> getPreference(String id) async { return m; } -void removePreference(String id) async { +removePreference(String id) async { SharedPreferences prefs = await SharedPreferences.getInstance(); prefs.remove('peer$id'); } -void initializeCursorAndCanvas(FFI ffi) async { +initializeCursorAndCanvas(FFI ffi) async { var p = await getPreference(ffi.id); int currentDisplay = 0; if (p != null) { diff --git a/flutter/lib/models/native_model.dart b/flutter/lib/models/native_model.dart index a9081a160..b1091c8ba 100644 --- a/flutter/lib/models/native_model.dart +++ b/flutter/lib/models/native_model.dart @@ -22,7 +22,7 @@ class RgbaFrame extends Struct { typedef F2 = Pointer Function(Pointer, Pointer); typedef F3 = void Function(Pointer, Pointer); -typedef HandleEvent = void Function(Map evt); +typedef HandleEvent = Future Function(Map evt); /// FFI wrapper around the native Rust core. /// Hides the platform differences. @@ -156,14 +156,14 @@ class PlatformFFI { version = await getVersion(); } - bool _tryHandle(Map evt) { + Future _tryHandle(Map evt) async { final name = evt['name']; if (name != null) { final handlers = _eventHandlers[name]; if (handlers != null) { if (handlers.isNotEmpty) { for (var handler in handlers.values) { - handler(evt); + await handler(evt); } return true; } @@ -180,7 +180,7 @@ class PlatformFFI { try { Map event = json.decode(message); // _tryHandle here may be more flexible than _eventCallback - if (!_tryHandle(event)) { + if (!await _tryHandle(event)) { if (_eventCallback != null) { await _eventCallback!(event); } diff --git a/flutter/lib/models/peer_model.dart b/flutter/lib/models/peer_model.dart index 79b71e6db..0857bfcf8 100644 --- a/flutter/lib/models/peer_model.dart +++ b/flutter/lib/models/peer_model.dart @@ -40,10 +40,10 @@ class Peers extends ChangeNotifier { static const _cbQueryOnlines = 'callback_query_onlines'; Peers({required this.name, required this.peers, required this.loadEvent}) { - platformFFI.registerEventHandler(_cbQueryOnlines, name, (evt) { + platformFFI.registerEventHandler(_cbQueryOnlines, name, (evt) async { _updateOnlineState(evt); }); - platformFFI.registerEventHandler(loadEvent, name, (evt) { + platformFFI.registerEventHandler(loadEvent, name, (evt) async { _updatePeers(evt); }); } diff --git a/flutter/lib/utils/image.dart b/flutter/lib/utils/image.dart index e92fdc6e5..1f0d5b0cd 100644 --- a/flutter/lib/utils/image.dart +++ b/flutter/lib/utils/image.dart @@ -28,10 +28,10 @@ Future decodeImageFromPixels( pixelFormat: format, ); if (!allowUpscaling) { - if (targetWidth != null && targetWidth! > descriptor.width) { + if (targetWidth != null && targetWidth > descriptor.width) { targetWidth = descriptor.width; } - if (targetHeight != null && targetHeight! > descriptor.height) { + if (targetHeight != null && targetHeight > descriptor.height) { targetHeight = descriptor.height; } }