mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-09-21 11:50:59 +03:00
Preserve Windows cursor alpha during native image decoding
This commit is contained in:
@@ -3461,9 +3461,10 @@ class CursorModel with ChangeNotifier {
|
|||||||
List<dynamic> colors = json.decode(evt['colors']);
|
List<dynamic> colors = json.decode(evt['colors']);
|
||||||
final rgba = Uint8List.fromList(colors.map((s) => s as int).toList());
|
final rgba = Uint8List.fromList(colors.map((s) => s as int).toList());
|
||||||
final ui.Image? image;
|
final ui.Image? image;
|
||||||
|
final platform = parent.target?.ffiModel.pi.platform;
|
||||||
if (!isWeb &&
|
if (!isWeb &&
|
||||||
parent.target?.ffiModel.pi.platform == kPeerPlatformMacOS) {
|
(platform == kPeerPlatformMacOS || platform == kPeerPlatformWindows)) {
|
||||||
image = await _decodeMacCursor(rgba, width, height);
|
image = await _decodeStraightAlphaCursor(rgba, width, height);
|
||||||
} else {
|
} else {
|
||||||
image = await img.decodeImageFromPixels(
|
image = await img.decodeImageFromPixels(
|
||||||
rgba, width, height, ui.PixelFormat.rgba8888);
|
rgba, width, height, ui.PixelFormat.rgba8888);
|
||||||
@@ -3484,10 +3485,10 @@ class CursorModel with ChangeNotifier {
|
|||||||
_updateCurData();
|
_updateCurData();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<ui.Image?> _decodeMacCursor(
|
Future<ui.Image?> _decodeStraightAlphaCursor(
|
||||||
Uint8List rgba, int width, int height) async {
|
Uint8List rgba, int width, int height) async {
|
||||||
// macOS packets keep straight alpha, regardless of density metadata.
|
// macOS and Win32 capture send straight alpha; XFixes/DRM are premultiplied.
|
||||||
// Premultiply only for native ui.Image; the PNG cache needs straight colors.
|
// Convert a copy for native ui.Image, preserving the wire and PNG cache colors.
|
||||||
final source = img2.Image.fromBytes(
|
final source = img2.Image.fromBytes(
|
||||||
width: width, height: height, bytes: rgba.buffer, order: img2.ChannelOrder.rgba);
|
width: width, height: height, bytes: rgba.buffer, order: img2.ChannelOrder.rgba);
|
||||||
for (final pixel in source) {
|
for (final pixel in source) {
|
||||||
|
|||||||
@@ -69,6 +69,8 @@ void main() {
|
|||||||
(kPeerPlatformMacOS, '0', [64, 32, 16, 128]),
|
(kPeerPlatformMacOS, '0', [64, 32, 16, 128]),
|
||||||
(kPeerPlatformMacOS, '1', [64, 32, 16, 128]),
|
(kPeerPlatformMacOS, '1', [64, 32, 16, 128]),
|
||||||
(kPeerPlatformMacOS, '2', [64, 32, 16, 128]),
|
(kPeerPlatformMacOS, '2', [64, 32, 16, 128]),
|
||||||
|
(kPeerPlatformWindows, null, [64, 32, 16, 128]),
|
||||||
|
(kPeerPlatformWindows, '0', [64, 32, 16, 128]),
|
||||||
(kPeerPlatformLinux, '0', [32, 16, 8, 128]),
|
(kPeerPlatformLinux, '0', [32, 16, 8, 128]),
|
||||||
]) {
|
]) {
|
||||||
for (final dpr in [1.0, 2.0]) {
|
for (final dpr in [1.0, 2.0]) {
|
||||||
@@ -119,6 +121,8 @@ Future<void> _checkCursor((String, String?, List<int>) testCase, double dpr,
|
|||||||
bytes: straight!.buffer,
|
bytes: straight!.buffer,
|
||||||
bytesOffset: straight.offsetInBytes,
|
bytesOffset: straight.offsetInBytes,
|
||||||
order: img.ChannelOrder.rgba));
|
order: img.ChannelOrder.rgba));
|
||||||
|
// Real sessions own FFI strongly throughout asynchronous cursor decoding.
|
||||||
|
expect(cursor.parent.target, same(ffi));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _checkRegistration(Map<dynamic, dynamic> args, double dpr) {
|
void _checkRegistration(Map<dynamic, dynamic> args, double dpr) {
|
||||||
|
|||||||
Reference in New Issue
Block a user