Merge pull request #2276 from fufesou/fix_cursor_win_forbidden

fix predefined win forbidden cursor
This commit is contained in:
RustDesk 2022-11-22 21:47:12 +08:00 committed by GitHub
commit 5d24bc93c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 88 additions and 84 deletions

View File

@ -356,9 +356,8 @@ class _ImagePaintState extends State<ImagePaint> {
} }
} }
MouseCursor _buildCustomCursor(BuildContext context, double scale) { MouseCursor _buildCursorOfCache(
final cursor = Provider.of<CursorModel>(context); CursorModel cursor, double scale, CursorData? cache) {
final cache = cursor.cache ?? cursor.defaultCache;
if (cache == null) { if (cache == null) {
return MouseCursor.defer; return MouseCursor.defer;
} else { } else {
@ -375,26 +374,16 @@ class _ImagePaintState extends State<ImagePaint> {
} }
} }
MouseCursor _buildCustomCursor(BuildContext context, double scale) {
final cursor = Provider.of<CursorModel>(context);
final cache = cursor.cache ?? preDefaultCursor.cache;
return _buildCursorOfCache(cursor, scale, cache);
}
MouseCursor _buildDisabledCursor(BuildContext context, double scale) { MouseCursor _buildDisabledCursor(BuildContext context, double scale) {
final cursor = Provider.of<CursorModel>(context); final cursor = Provider.of<CursorModel>(context);
final cache = cursor.cache; final cache = preForbiddenCursor.cache;
if (cache == null) { return _buildCursorOfCache(cursor, scale, cache);
return MouseCursor.defer;
} else {
if (cursor.cachedForbidmemoryCursorData == null) {
cursor.updateForbiddenCursorBuffer();
}
final key = 'disabled_cursor_key';
cursor.addKey(key);
return FlutterCustomMemoryImageCursor(
pixbuf: cursor.cachedForbidmemoryCursorData,
key: key,
hotx: 0,
hoty: 0,
imageWidth: 32,
imageHeight: 32,
);
}
} }
Widget _buildCrossScrollbarFromLayout( Widget _buildCrossScrollbarFromLayout(
@ -521,22 +510,22 @@ class CursorPaint extends StatelessWidget {
double hotx = m.hotx; double hotx = m.hotx;
double hoty = m.hoty; double hoty = m.hoty;
if (m.image == null) { if (m.image == null) {
if (m.defaultCache != null) { if (preDefaultCursor.image != null) {
hotx = m.defaultImage!.width / 2; hotx = preDefaultCursor.image!.width / 2;
hoty = m.defaultImage!.height / 2; hoty = preDefaultCursor.image!.height / 2;
} }
} }
return zoomCursor.isTrue return zoomCursor.isTrue
? CustomPaint( ? CustomPaint(
painter: ImagePainter( painter: ImagePainter(
image: m.image ?? m.defaultImage, image: m.image ?? preDefaultCursor.image,
x: m.x - hotx + c.x / c.scale, x: m.x - hotx + c.x / c.scale,
y: m.y - hoty + c.y / c.scale, y: m.y - hoty + c.y / c.scale,
scale: c.scale), scale: c.scale),
) )
: CustomPaint( : CustomPaint(
painter: ImagePainter( painter: ImagePainter(
image: m.image ?? m.defaultImage, image: m.image ?? preDefaultCursor.image,
x: (m.x - hotx) * c.scale + c.x, x: (m.x - hotx) * c.scale + c.x,
y: (m.y - hoty) * c.scale + c.y, y: (m.y - hoty) * c.scale + c.y,
scale: 1.0), scale: 1.0),

View File

@ -865,14 +865,14 @@ class CursorPaint extends StatelessWidget {
double hotx = m.hotx; double hotx = m.hotx;
double hoty = m.hoty; double hoty = m.hoty;
if (m.image == null) { if (m.image == null) {
if (m.defaultCache != null) { if (preDefaultCursor.image != null) {
hotx = m.defaultImage!.width / 2; hotx = preDefaultCursor.image!.width / 2;
hoty = m.defaultImage!.height / 2; hoty = preDefaultCursor.image!.height / 2;
} }
} }
return CustomPaint( return CustomPaint(
painter: ImagePainter( painter: ImagePainter(
image: m.image ?? m.defaultImage, image: m.image ?? preDefaultCursor.image,
x: m.x * s - hotx * s + c.x, x: m.x * s - hotx * s + c.x,
y: m.y * s - hoty * s + c.y - adjust, y: m.y * s - hoty * s + c.y - adjust,
scale: 1), scale: 1),

View File

@ -763,13 +763,78 @@ class CursorData {
} }
} }
const _forbiddenCursorPng =
'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAAXNSR0IB2cksfwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAkZQTFRFAAAA2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4GWAwCAAAAAAAA2B4GAAAAMTExAAAAAAAA2B4G2B4G2B4GAAAAmZmZkZGRAQEBAAAA2B4G2B4G2B4G////oKCgAwMDag8D2B4G2B4G2B4Gra2tBgYGbg8D2B4G2B4Gubm5CQkJTwsCVgwC2B4GxcXFDg4OAAAAAAAA2B4G2B4Gz8/PFBQUAAAAAAAA2B4G2B4G2B4G2B4G2B4G2B4G2B4GDgIA2NjYGxsbAAAAAAAA2B4GFwMB4eHhIyMjAAAAAAAA2B4G6OjoLCwsAAAAAAAA2B4G2B4G2B4G2B4G2B4GCQEA4ODgv7+/iYmJY2NjAgICAAAA9PT0Ojo6AAAAAAAAAAAA+/v7SkpKhYWFr6+vAAAAAAAA8/PzOTk5ERER9fX1KCgoAAAAgYGBKioqAAAAAAAApqamlpaWAAAAAAAAAAAAAAAAAAAAAAAALi4u/v7+GRkZAAAAAAAAAAAAAAAAAAAAfn5+AAAAAAAAV1dXkJCQAAAAAAAAAQEBAAAAAAAAAAAA7Hz6BAAAAMJ0Uk5TAAIWEwEynNz6//fVkCAatP2fDUHs6cDD8d0mPfT5fiEskiIR584A0gejr3AZ+P4plfALf5ZiTL85a4ziD6697fzN3UYE4v/4TwrNHuT///tdRKZh///+1U/ZBv///yjb///eAVL//50Cocv//6oFBbPvpGZCbfT//7cIhv///8INM///zBEcWYSZmO7//////1P////ts/////8vBv//////gv//R/z///QQz9sevP///2waXhNO/+fc//8mev/5gAe2r90MAAAByUlEQVR4nGNggANGJmYWBpyAlY2dg5OTi5uHF6s0H78AJxRwCAphyguLgKRExcQlQLSkFLq8tAwnp6ycPNABjAqKQKNElVDllVU4OVVhVquJA81Q10BRoAkUUYbJa4Edoo0sr6PLqaePLG/AyWlohKTAmJPTBFnelAFoixmSAnNOTgsUeQZLTk4rJAXWnJw2EHlbiDyDPCenHZICe04HFrh+RydnBgYWPU5uJAWinJwucPNd3dw9GDw5Ob2QFHBzcnrD7ffx9fMPCOTkDEINhmC4+3x8Q0LDwlEDIoKTMzIKKg9SEBIdE8sZh6SAJZ6Tkx0qD1YQkpCYlIwclCng0AXLQxSEpKalZyCryATKZwkhKQjJzsnNQ1KQXwBUUVhUXBJYWgZREFJeUVmFpMKlWg+anmqgCkJq6+obkG1pLEBTENLU3NKKrIKhrb2js8u4G6Kgpze0r3/CRAZMAHbkpJDJU6ZMmTqtFbuC6TNmhsyaMnsOFlmwgrnzpsxfELJwEXZ5Bp/FS3yWLlsesmLlKuwKVk9Ys5Zh3foN0zduwq5g85atDAzbpqSGbN9RhV0FGOzctWH3lD14FOzdt3H/gQw8Cg4u2gQPAwBYDXXdIH+wqAAAAABJRU5ErkJggg==';
const _defaultCursorPng =
'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARzQklUCAgICHwIZIgAAAFmSURBVFiF7dWxSlxREMbx34QFDRowYBchZSxSCWlMCOwD5FGEFHap06UI7KPsAyyEEIQFqxRaCqYTsqCJFsKkuAeRXb17wrqV918dztw55zszc2fo6Oh47MR/e3zO1/iAHWmznHKGQwx9ip/LEbCfazbsoY8j/JLOhcC6sCW9wsjEwJf483AC9nPNc1+lFRwI13d+l3rYFS799rFGxJMqARv2pBXh+72XQ7gWvklPS7TmMl9Ak/M+DqrENvxAv/guKKApuKPWl0/TROK4+LbSqzhuB+OZ3fRSeFPWY+Fkyn56Y29hfgTSpnQ+s98cvorVey66uPlNFxKwZOYLCGfCs5n9NMYVrsp6mvXSoFqpqYFDvMBkStgJJe93dZOwVXxbqUnBENulydSReqUrDhcX0PT2EXarBYS3GNXMhboinBgIl9K71kg0L3+PvyYGdVpruT2MwrF0iotiXfIwus0Dj+OOjo6Of+e7ab74RkpgAAAAAElFTkSuQmCC';
final preForbiddenCursor = PredefinedCursor(
png: _forbiddenCursorPng,
id: -2,
);
final preDefaultCursor = PredefinedCursor(
png: _defaultCursorPng,
id: -1,
hotxGetter: (double w) => w / 2,
hotyGetter: (double h) => h / 2,
);
class PredefinedCursor {
ui.Image? _image;
img2.Image? _image2;
CursorData? _cache;
String png;
int id;
double Function(double)? hotxGetter;
double Function(double)? hotyGetter;
PredefinedCursor(
{required this.png, required this.id, this.hotxGetter, this.hotyGetter}) {
init();
}
ui.Image? get image => _image;
CursorData? get cache => _cache;
init() {
_image2 = img2.decodePng(base64Decode(png));
if (_image2 != null) {
() async {
final defaultImg = _image2!;
// This function is called only one time, no need to care about the performance.
Uint8List data = defaultImg.getBytes(format: img2.Format.rgba);
_image = await img.decodeImageFromPixels(
data, defaultImg.width, defaultImg.height, ui.PixelFormat.rgba8888);
double scale = 1.0;
if (Platform.isWindows) {
data = _image2!.getBytes(format: img2.Format.bgra);
} else {
data = Uint8List.fromList(img2.encodePng(_image2!));
}
_cache = CursorData(
peerId: '',
id: id,
image: _image2?.clone(),
scale: scale,
data: data,
hotxOrigin:
hotxGetter != null ? hotxGetter!(_image2!.width.toDouble()) : 0,
hotyOrigin:
hotyGetter != null ? hotyGetter!(_image2!.height.toDouble()) : 0,
width: _image2!.width,
height: _image2!.height,
);
}();
}
}
}
class CursorModel with ChangeNotifier { class CursorModel with ChangeNotifier {
ui.Image? _image; ui.Image? _image;
ui.Image? _defaultImage;
final _images = <int, Tuple3<ui.Image, double, double>>{}; final _images = <int, Tuple3<ui.Image, double, double>>{};
CursorData? _cache; CursorData? _cache;
final _defaultCacheId = -1;
CursorData? _defaultCache;
final _cacheMap = <int, CursorData>{}; final _cacheMap = <int, CursorData>{};
final _cacheKeys = <String>{}; final _cacheKeys = <String>{};
double _x = -10000; double _x = -10000;
@ -785,9 +850,7 @@ class CursorModel with ChangeNotifier {
WeakReference<FFI> parent; WeakReference<FFI> parent;
ui.Image? get image => _image; ui.Image? get image => _image;
ui.Image? get defaultImage => _defaultImage;
CursorData? get cache => _cache; CursorData? get cache => _cache;
CursorData? get defaultCache => _getDefaultCache();
double get x => _x - _displayOriginX; double get x => _x - _displayOriginX;
double get y => _y - _displayOriginY; double get y => _y - _displayOriginY;
@ -801,50 +864,11 @@ class CursorModel with ChangeNotifier {
DateTime.now().difference(_lastPeerMouse).inMilliseconds < DateTime.now().difference(_lastPeerMouse).inMilliseconds <
kMouseControlTimeoutMSec; kMouseControlTimeoutMSec;
CursorModel(this.parent) { CursorModel(this.parent);
_getDefaultImage();
_getDefaultCache();
}
Set<String> get cachedKeys => _cacheKeys; Set<String> get cachedKeys => _cacheKeys;
addKey(String key) => _cacheKeys.add(key); addKey(String key) => _cacheKeys.add(key);
Future<ui.Image?> _getDefaultImage() async {
if (_defaultImage == null) {
final defaultImg = defaultCursorImage!;
// This function is called only one time, no need to care about the performance.
Uint8List data = defaultImg.getBytes(format: img2.Format.rgba);
_defaultImage = await img.decodeImageFromPixels(
data, defaultImg.width, defaultImg.height, ui.PixelFormat.rgba8888);
}
return _defaultImage;
}
CursorData? _getDefaultCache() {
if (_defaultCache == null) {
Uint8List data;
double scale = 1.0;
if (Platform.isWindows) {
data = defaultCursorImage!.getBytes(format: img2.Format.bgra);
} else {
data = Uint8List.fromList(img2.encodePng(defaultCursorImage!));
}
_defaultCache = CursorData(
peerId: id,
id: _defaultCacheId,
image: defaultCursorImage?.clone(),
scale: scale,
data: data,
hotxOrigin: defaultCursorImage!.width / 2,
hotyOrigin: defaultCursorImage!.height / 2,
width: defaultCursorImage!.width,
height: defaultCursorImage!.height,
);
}
return _defaultCache;
}
// remote physical display coordinate // remote physical display coordinate
Rect getVisibleRect() { Rect getVisibleRect() {
final size = MediaQueryData.fromWindow(ui.window).size; final size = MediaQueryData.fromWindow(ui.window).size;
@ -1085,15 +1109,6 @@ class CursorModel with ChangeNotifier {
customCursorController.freeCache(k); customCursorController.freeCache(k);
} }
} }
Uint8List? cachedForbidmemoryCursorData;
void updateForbiddenCursorBuffer() {
cachedForbidmemoryCursorData ??= base64Decode(
'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAAXNSR0IB2cksfwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAkZQTFRFAAAA2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4G2B4GWAwCAAAAAAAA2B4GAAAAMTExAAAAAAAA2B4G2B4G2B4GAAAAmZmZkZGRAQEBAAAA2B4G2B4G2B4G////oKCgAwMDag8D2B4G2B4G2B4Gra2tBgYGbg8D2B4G2B4Gubm5CQkJTwsCVgwC2B4GxcXFDg4OAAAAAAAA2B4G2B4Gz8/PFBQUAAAAAAAA2B4G2B4G2B4G2B4G2B4G2B4G2B4GDgIA2NjYGxsbAAAAAAAA2B4GFwMB4eHhIyMjAAAAAAAA2B4G6OjoLCwsAAAAAAAA2B4G2B4G2B4G2B4G2B4GCQEA4ODgv7+/iYmJY2NjAgICAAAA9PT0Ojo6AAAAAAAAAAAA+/v7SkpKhYWFr6+vAAAAAAAA8/PzOTk5ERER9fX1KCgoAAAAgYGBKioqAAAAAAAApqamlpaWAAAAAAAAAAAAAAAAAAAAAAAALi4u/v7+GRkZAAAAAAAAAAAAAAAAAAAAfn5+AAAAAAAAV1dXkJCQAAAAAAAAAQEBAAAAAAAAAAAA7Hz6BAAAAMJ0Uk5TAAIWEwEynNz6//fVkCAatP2fDUHs6cDD8d0mPfT5fiEskiIR584A0gejr3AZ+P4plfALf5ZiTL85a4ziD6697fzN3UYE4v/4TwrNHuT///tdRKZh///+1U/ZBv///yjb///eAVL//50Cocv//6oFBbPvpGZCbfT//7cIhv///8INM///zBEcWYSZmO7//////1P////ts/////8vBv//////gv//R/z///QQz9sevP///2waXhNO/+fc//8mev/5gAe2r90MAAAByUlEQVR4nGNggANGJmYWBpyAlY2dg5OTi5uHF6s0H78AJxRwCAphyguLgKRExcQlQLSkFLq8tAwnp6ycPNABjAqKQKNElVDllVU4OVVhVquJA81Q10BRoAkUUYbJa4Edoo0sr6PLqaePLG/AyWlohKTAmJPTBFnelAFoixmSAnNOTgsUeQZLTk4rJAXWnJw2EHlbiDyDPCenHZICe04HFrh+RydnBgYWPU5uJAWinJwucPNd3dw9GDw5Ob2QFHBzcnrD7ffx9fMPCOTkDEINhmC4+3x8Q0LDwlEDIoKTMzIKKg9SEBIdE8sZh6SAJZ6Tkx0qD1YQkpCYlIwclCng0AXLQxSEpKalZyCryATKZwkhKQjJzsnNQ1KQXwBUUVhUXBJYWgZREFJeUVmFpMKlWg+anmqgCkJq6+obkG1pLEBTENLU3NKKrIKhrb2js8u4G6Kgpze0r3/CRAZMAHbkpJDJU6ZMmTqtFbuC6TNmhsyaMnsOFlmwgrnzpsxfELJwEXZ5Bp/FS3yWLlsesmLlKuwKVk9Ys5Zh3foN0zduwq5g85atDAzbpqSGbN9RhV0FGOzctWH3lD14FOzdt3H/gQw8Cg4u2gQPAwBYDXXdIH+wqAAAAABJRU5ErkJggg==');
}
img2.Image? defaultCursorImage = img2.decodePng(base64Decode(
'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARzQklUCAgICHwIZIgAAAFmSURBVFiF7dWxSlxREMbx34QFDRowYBchZSxSCWlMCOwD5FGEFHap06UI7KPsAyyEEIQFqxRaCqYTsqCJFsKkuAeRXb17wrqV918dztw55zszc2fo6Oh47MR/e3zO1/iAHWmznHKGQwx9ip/LEbCfazbsoY8j/JLOhcC6sCW9wsjEwJf483AC9nPNc1+lFRwI13d+l3rYFS799rFGxJMqARv2pBXh+72XQ7gWvklPS7TmMl9Ak/M+DqrENvxAv/guKKApuKPWl0/TROK4+LbSqzhuB+OZ3fRSeFPWY+Fkyn56Y29hfgTSpnQ+s98cvorVey66uPlNFxKwZOYLCGfCs5n9NMYVrsp6mvXSoFqpqYFDvMBkStgJJe93dZOwVXxbqUnBENulydSReqUrDhcX0PT2EXarBYS3GNXMhboinBgIl9K71kg0L3+PvyYGdVpruT2MwrF0iotiXfIwus0Dj+OOjo6Of+e7ab74RkpgAAAAAElFTkSuQmCC'));
} }
class QualityMonitorData { class QualityMonitorData {