From 8dba3942052b322b2772fb929821940e8437f239 Mon Sep 17 00:00:00 2001 From: fufesou Date: Wed, 1 Feb 2023 20:58:21 +0800 Subject: [PATCH 1/7] scale system cursor image Signed-off-by: fufesou --- flutter/lib/desktop/pages/remote_page.dart | 1 - .../lib/desktop/widgets/remote_menubar.dart | 37 +++++++++---------- flutter/lib/models/model.dart | 34 ++++++++--------- 3 files changed, 32 insertions(+), 40 deletions(-) diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart index 2e4668159..1687f348e 100644 --- a/flutter/lib/desktop/pages/remote_page.dart +++ b/flutter/lib/desktop/pages/remote_page.dart @@ -3,7 +3,6 @@ import 'dart:io'; import 'dart:ui' as ui; import 'package:desktop_multi_window/desktop_multi_window.dart'; -import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_custom_cursor/cursor_manager.dart' diff --git a/flutter/lib/desktop/widgets/remote_menubar.dart b/flutter/lib/desktop/widgets/remote_menubar.dart index 517dc9750..4f16f8227 100644 --- a/flutter/lib/desktop/widgets/remote_menubar.dart +++ b/flutter/lib/desktop/widgets/remote_menubar.dart @@ -1133,26 +1133,23 @@ class _RemoteMenubarState extends State { }()); } - /// Show remote cursor scaling with image - if (widget.state.viewStyle.value != kRemoteViewStyleOriginal) { - displayMenu.add(() { - final opt = 'zoom-cursor'; - final state = PeerBoolOption.find(widget.id, opt); - return MenuEntrySwitch2( - switchType: SwitchType.scheckbox, - text: translate('Zoom cursor'), - getter: () { - return state; - }, - setter: (bool v) async { - state.value = v; - await bind.sessionToggleOption(id: widget.id, value: opt); - }, - padding: padding, - dismissOnClicked: true, - ); - }()); - } + displayMenu.add(() { + final opt = 'zoom-cursor'; + final state = PeerBoolOption.find(widget.id, opt); + return MenuEntrySwitch2( + switchType: SwitchType.scheckbox, + text: translate('Zoom cursor'), + getter: () { + return state; + }, + setter: (bool v) async { + state.value = v; + await bind.sessionToggleOption(id: widget.id, value: opt); + }, + padding: padding, + dismissOnClicked: true, + ); + }()); /// Show quality monitor displayMenu.add(MenuEntrySwitch( diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index 1eac1be39..78e6ce6af 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -778,28 +778,24 @@ class CursorData { scale = 1.0; } else { // Update data if scale changed. - if (Platform.isWindows) { - final tgtWidth = (width * scale).toInt(); - final tgtHeight = (width * scale).toInt(); - if (tgtWidth < kMinCursorSize || tgtHeight < kMinCursorSize) { - double sw = kMinCursorSize.toDouble() / width; - double sh = kMinCursorSize.toDouble() / height; - scale = sw < sh ? sh : sw; - } + final tgtWidth = (width * scale).toInt(); + final tgtHeight = (width * scale).toInt(); + if (tgtWidth < kMinCursorSize || tgtHeight < kMinCursorSize) { + double sw = kMinCursorSize.toDouble() / width; + double sh = kMinCursorSize.toDouble() / height; + scale = sw < sh ? sh : sw; } } - if (Platform.isWindows) { - if (_doubleToInt(oldScale) != _doubleToInt(scale)) { - data = img2 - .copyResize( - image!, - width: (width * scale).toInt(), - height: (height * scale).toInt(), - interpolation: img2.Interpolation.average, - ) - .getBytes(format: img2.Format.bgra); - } + if (_doubleToInt(oldScale) != _doubleToInt(scale)) { + data = img2 + .copyResize( + image!, + width: (width * scale).toInt(), + height: (height * scale).toInt(), + interpolation: img2.Interpolation.average, + ) + .getBytes(format: img2.Format.bgra); } this.scale = scale; From 8881462f748068a6118196212c9f98aebe4e3a31 Mon Sep 17 00:00:00 2001 From: fufesou Date: Wed, 1 Feb 2023 22:12:28 +0800 Subject: [PATCH 2/7] debug macos Signed-off-by: fufesou --- flutter/lib/models/model.dart | 37 +++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index 78e6ce6af..b2df5faac 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -747,7 +747,7 @@ class CanvasModel with ChangeNotifier { class CursorData { final String peerId; final int id; - final img2.Image? image; + final img2.Image image; double scale; Uint8List? data; final double hotxOrigin; @@ -788,14 +788,27 @@ class CursorData { } if (_doubleToInt(oldScale) != _doubleToInt(scale)) { - data = img2 - .copyResize( - image!, - width: (width * scale).toInt(), - height: (height * scale).toInt(), - interpolation: img2.Interpolation.average, - ) - .getBytes(format: img2.Format.bgra); + if (Platform.isWindows) { + data = img2 + .copyResize( + image, + width: (width * scale).toInt(), + height: (height * scale).toInt(), + interpolation: img2.Interpolation.average, + ) + .getBytes(format: img2.Format.bgra); + } else { + data = Uint8List.fromList( + img2.encodePng( + img2.copyResize( + image, + width: (width * scale).toInt(), + height: (height * scale).toInt(), + interpolation: img2.Interpolation.average, + ), + ), + ); + } } this.scale = scale; @@ -863,7 +876,7 @@ class PredefinedCursor { _cache = CursorData( peerId: '', id: id, - image: _image2?.clone(), + image: _image2!.clone(), scale: scale, data: data, hotxOrigin: @@ -1063,9 +1076,9 @@ class CursorModel with ChangeNotifier { Future _updateCache( Uint8List rgba, ui.Image image, int id, int w, int h) async { Uint8List? data; - img2.Image? imgOrigin; + img2.Image imgOrigin = + img2.Image.fromBytes(w, h, rgba, format: img2.Format.rgba); if (Platform.isWindows) { - imgOrigin = img2.Image.fromBytes(w, h, rgba, format: img2.Format.rgba); data = imgOrigin.getBytes(format: img2.Format.bgra); } else { ByteData? imgBytes = From b5fbc23cb9b9fc7ba915e1024085d8ac7ad1bf18 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 2 Feb 2023 12:39:39 +0800 Subject: [PATCH 3/7] zoom system cursor when view scale is adaptive Signed-off-by: fufesou --- flutter/lib/desktop/pages/remote_page.dart | 21 ++++++----- .../lib/desktop/widgets/remote_menubar.dart | 37 ++++++++++--------- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart index 1687f348e..1ce9dec4a 100644 --- a/flutter/lib/desktop/pages/remote_page.dart +++ b/flutter/lib/desktop/pages/remote_page.dart @@ -362,10 +362,10 @@ class _RemotePageState extends State class ImagePaint extends StatefulWidget { final String id; - final Rx zoomCursor; - final Rx cursorOverImage; - final Rx keyboardEnabled; - final Rx remoteCursorMoved; + final RxBool zoomCursor; + final RxBool cursorOverImage; + final RxBool keyboardEnabled; + final RxBool remoteCursorMoved; final Widget Function(Widget)? listenerBuilder; ImagePaint( @@ -388,10 +388,10 @@ class _ImagePaintState extends State { final ScrollController _vertical = ScrollController(); String get id => widget.id; - Rx get zoomCursor => widget.zoomCursor; - Rx get cursorOverImage => widget.cursorOverImage; - Rx get keyboardEnabled => widget.keyboardEnabled; - Rx get remoteCursorMoved => widget.remoteCursorMoved; + RxBool get zoomCursor => widget.zoomCursor; + RxBool get cursorOverImage => widget.cursorOverImage; + RxBool get keyboardEnabled => widget.keyboardEnabled; + RxBool get remoteCursorMoved => widget.remoteCursorMoved; Widget Function(Widget)? get listenerBuilder => widget.listenerBuilder; @override @@ -466,7 +466,10 @@ class _ImagePaintState extends State { if (cache == null) { return MouseCursor.defer; } else { - final key = cache.updateGetKey(scale, zoomCursor.value); + final isViewAdaptive = + Provider.of(context, listen: false).viewStyle.style == + kRemoteViewStyleAdaptive; + final key = cache.updateGetKey(scale, zoomCursor.value && isViewAdaptive); if (!cursor.cachedKeys.contains(key)) { debugPrint("Register custom cursor with key $key"); // [Safety] diff --git a/flutter/lib/desktop/widgets/remote_menubar.dart b/flutter/lib/desktop/widgets/remote_menubar.dart index 4f16f8227..517dc9750 100644 --- a/flutter/lib/desktop/widgets/remote_menubar.dart +++ b/flutter/lib/desktop/widgets/remote_menubar.dart @@ -1133,23 +1133,26 @@ class _RemoteMenubarState extends State { }()); } - displayMenu.add(() { - final opt = 'zoom-cursor'; - final state = PeerBoolOption.find(widget.id, opt); - return MenuEntrySwitch2( - switchType: SwitchType.scheckbox, - text: translate('Zoom cursor'), - getter: () { - return state; - }, - setter: (bool v) async { - state.value = v; - await bind.sessionToggleOption(id: widget.id, value: opt); - }, - padding: padding, - dismissOnClicked: true, - ); - }()); + /// Show remote cursor scaling with image + if (widget.state.viewStyle.value != kRemoteViewStyleOriginal) { + displayMenu.add(() { + final opt = 'zoom-cursor'; + final state = PeerBoolOption.find(widget.id, opt); + return MenuEntrySwitch2( + switchType: SwitchType.scheckbox, + text: translate('Zoom cursor'), + getter: () { + return state; + }, + setter: (bool v) async { + state.value = v; + await bind.sessionToggleOption(id: widget.id, value: opt); + }, + padding: padding, + dismissOnClicked: true, + ); + }()); + } /// Show quality monitor displayMenu.add(MenuEntrySwitch( From 77ee60c8dc730af4b6658119b452cd1d417bba66 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 2 Feb 2023 12:47:39 +0800 Subject: [PATCH 4/7] scale remote cursor when view style is adaptive Signed-off-by: fufesou --- flutter/lib/desktop/pages/remote_page.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart index 1ce9dec4a..858157853 100644 --- a/flutter/lib/desktop/pages/remote_page.dart +++ b/flutter/lib/desktop/pages/remote_page.dart @@ -635,7 +635,8 @@ class CursorPaint extends StatelessWidget { double x = (m.x - hotx) * c.scale + cx; double y = (m.y - hoty) * c.scale + cy; double scale = 1.0; - if (zoomCursor.isTrue) { + final isViewAdaptive = c.viewStyle.style == kRemoteViewStyleAdaptive; + if (zoomCursor.isTrue && isViewAdaptive) { x = m.x - hotx + cx / c.scale; y = m.y - hoty + cy / c.scale; scale = c.scale; From aafc2e0a8e4d0525b19ad011936354d6802bfb84 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 2 Feb 2023 13:08:41 +0800 Subject: [PATCH 5/7] zoom cursor on different OSs Signed-off-by: fufesou --- flutter/lib/desktop/pages/remote_page.dart | 28 +++++++++++++++++----- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart index 858157853..dd71797f3 100644 --- a/flutter/lib/desktop/pages/remote_page.dart +++ b/flutter/lib/desktop/pages/remote_page.dart @@ -466,10 +466,19 @@ class _ImagePaintState extends State { if (cache == null) { return MouseCursor.defer; } else { - final isViewAdaptive = - Provider.of(context, listen: false).viewStyle.style == - kRemoteViewStyleAdaptive; - final key = cache.updateGetKey(scale, zoomCursor.value && isViewAdaptive); + bool shouldScale = false; + if (Platform.isWindows) { + final isViewAdaptive = + Provider.of(context, listen: false).viewStyle.style == + kRemoteViewStyleAdaptive; + shouldScale = zoomCursor.value && isViewAdaptive; + } else { + final isViewOriginal = + Provider.of(context, listen: false).viewStyle.style == + kRemoteViewStyleOriginal; + shouldScale = zoomCursor.value || isViewOriginal; + } + final key = cache.updateGetKey(scale, shouldScale); if (!cursor.cachedKeys.contains(key)) { debugPrint("Register custom cursor with key $key"); // [Safety] @@ -635,8 +644,15 @@ class CursorPaint extends StatelessWidget { double x = (m.x - hotx) * c.scale + cx; double y = (m.y - hoty) * c.scale + cy; double scale = 1.0; - final isViewAdaptive = c.viewStyle.style == kRemoteViewStyleAdaptive; - if (zoomCursor.isTrue && isViewAdaptive) { + bool shouldScale = false; + if (Platform.isWindows) { + final isViewAdaptive = c.viewStyle.style == kRemoteViewStyleAdaptive; + shouldScale = zoomCursor.value && isViewAdaptive; + } else { + final isViewOriginal = c.viewStyle.style == kRemoteViewStyleOriginal; + shouldScale = zoomCursor.value || isViewOriginal; + } + if (shouldScale) { x = m.x - hotx + cx / c.scale; y = m.y - hoty + cy / c.scale; scale = c.scale; From d511d1e27a024847a50d31ec85392478907dccd6 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 2 Feb 2023 13:40:13 +0800 Subject: [PATCH 6/7] zoom remote cursor when view style is original Signed-off-by: fufesou --- flutter/lib/desktop/pages/remote_page.dart | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart index dd71797f3..f38cdfb6e 100644 --- a/flutter/lib/desktop/pages/remote_page.dart +++ b/flutter/lib/desktop/pages/remote_page.dart @@ -644,15 +644,8 @@ class CursorPaint extends StatelessWidget { double x = (m.x - hotx) * c.scale + cx; double y = (m.y - hoty) * c.scale + cy; double scale = 1.0; - bool shouldScale = false; - if (Platform.isWindows) { - final isViewAdaptive = c.viewStyle.style == kRemoteViewStyleAdaptive; - shouldScale = zoomCursor.value && isViewAdaptive; - } else { - final isViewOriginal = c.viewStyle.style == kRemoteViewStyleOriginal; - shouldScale = zoomCursor.value || isViewOriginal; - } - if (shouldScale) { + final isViewOriginal = c.viewStyle.style == kRemoteViewStyleOriginal; + if (zoomCursor.value || isViewOriginal) { x = m.x - hotx + cx / c.scale; y = m.y - hoty + cy / c.scale; scale = c.scale; From f9e3a3f074ffc3cfc43e398abb712d631497e930 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 2 Feb 2023 14:39:58 +0800 Subject: [PATCH 7/7] zoom cursor with dpi Signed-off-by: fufesou --- flutter/lib/desktop/pages/remote_page.dart | 32 ++++++++++++---------- flutter/lib/models/model.dart | 15 +++++----- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart index f38cdfb6e..f7889d008 100644 --- a/flutter/lib/desktop/pages/remote_page.dart +++ b/flutter/lib/desktop/pages/remote_page.dart @@ -399,6 +399,20 @@ class _ImagePaintState extends State { final m = Provider.of(context); var c = Provider.of(context); final s = c.scale; + var cursorScale = 1.0; + + if (Platform.isWindows) { + // debug win10 + final isViewAdaptive = c.viewStyle.style == kRemoteViewStyleAdaptive; + if (zoomCursor.value && isViewAdaptive) { + cursorScale = s * c.devicePixelRatio; + } + } else { + final isViewOriginal = c.viewStyle.style == kRemoteViewStyleOriginal; + if (zoomCursor.value || isViewOriginal) { + cursorScale = s; + } + } mouseRegion({child}) => Obx(() => MouseRegion( cursor: cursorOverImage.isTrue @@ -414,10 +428,10 @@ class _ImagePaintState extends State { _lastRemoteCursorMoved = false; _firstEnterImage.value = true; } - return _buildCustomCursor(context, s); + return _buildCustomCursor(context, cursorScale); } }()) - : _buildDisabledCursor(context, s) + : _buildDisabledCursor(context, cursorScale) : MouseCursor.defer, onHover: (evt) {}, child: child)); @@ -466,19 +480,7 @@ class _ImagePaintState extends State { if (cache == null) { return MouseCursor.defer; } else { - bool shouldScale = false; - if (Platform.isWindows) { - final isViewAdaptive = - Provider.of(context, listen: false).viewStyle.style == - kRemoteViewStyleAdaptive; - shouldScale = zoomCursor.value && isViewAdaptive; - } else { - final isViewOriginal = - Provider.of(context, listen: false).viewStyle.style == - kRemoteViewStyleOriginal; - shouldScale = zoomCursor.value || isViewOriginal; - } - final key = cache.updateGetKey(scale, shouldScale); + final key = cache.updateGetKey(scale); if (!cursor.cachedKeys.contains(key)) { debugPrint("Register custom cursor with key $key"); // [Safety] diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index b2df5faac..f49bb270c 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -540,6 +540,7 @@ class CanvasModel with ChangeNotifier { double _y = 0; // image scale double _scale = 1.0; + double _devicePixelRatio = 1.0; Size _size = Size.zero; // the tabbar over the image // double tabBarHeight = 0.0; @@ -563,6 +564,7 @@ class CanvasModel with ChangeNotifier { double get x => _x; double get y => _y; double get scale => _scale; + double get devicePixelRatio => _devicePixelRatio; Size get size => _size; ScrollStyle get scrollStyle => _scrollStyle; ViewStyle get viewStyle => _lastViewStyle; @@ -611,8 +613,9 @@ class CanvasModel with ChangeNotifier { _lastViewStyle = viewStyle; _scale = viewStyle.scale; + _devicePixelRatio = ui.window.devicePixelRatio; if (kIgnoreDpi && style == kRemoteViewStyleOriginal) { - _scale = 1.0 / ui.window.devicePixelRatio; + _scale = 1.0 / _devicePixelRatio; } _x = (size.width - displayWidth * _scale) / 2; _y = (size.height - displayHeight * _scale) / 2; @@ -772,11 +775,9 @@ class CursorData { int _doubleToInt(double v) => (v * 10e6).round().toInt(); - double _checkUpdateScale(double scale, bool shouldScale) { + double _checkUpdateScale(double scale) { double oldScale = this.scale; - if (!shouldScale) { - scale = 1.0; - } else { + if (scale != 1.0) { // Update data if scale changed. final tgtWidth = (width * scale).toInt(); final tgtHeight = (width * scale).toInt(); @@ -817,8 +818,8 @@ class CursorData { return scale; } - String updateGetKey(double scale, bool shouldScale) { - scale = _checkUpdateScale(scale, shouldScale); + String updateGetKey(double scale) { + scale = _checkUpdateScale(scale); return '${peerId}_${id}_${_doubleToInt(width * scale)}_${_doubleToInt(height * scale)}'; } }