diff --git a/packages/desktop_drop/lib/src/channel.dart b/packages/desktop_drop/lib/src/channel.dart index 3e02231f..a7b15996 100644 --- a/packages/desktop_drop/lib/src/channel.dart +++ b/packages/desktop_drop/lib/src/channel.dart @@ -140,7 +140,14 @@ class DesktopDrop { .cast(); final paths = const LineSplitter().convert(text).map((e) { try { - return Uri.tryParse(e)?.toFilePath() ?? ''; + final uri = Uri.tryParse(e); + if (uri == null) { + return ''; + } + if (uri.scheme == 'file') { + return uri.toFilePath(); + } + return e; } catch (error, stacktrace) { debugPrint('failed to parse linux path: $error $stacktrace'); } diff --git a/packages/desktop_drop/test/channel_linux_test.dart b/packages/desktop_drop/test/channel_linux_test.dart new file mode 100644 index 00000000..152fac00 --- /dev/null +++ b/packages/desktop_drop/test/channel_linux_test.dart @@ -0,0 +1,57 @@ +import 'dart:async'; +import 'dart:typed_data'; + +import 'package:desktop_drop/desktop_drop.dart'; +import 'package:desktop_drop/src/events.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; + +Future _invokePlatformMethod(MethodCall call) async { + final codec = const StandardMethodCodec(); + final completer = Completer(); + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .handlePlatformMessage( + 'desktop_drop', + codec.encodeMethodCall(call), + completer.complete, + ); + await completer.future; +} + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + setUp(() { + DesktopDrop.instance.init(); + }); + + test('linux drop keeps non-file uri path', () async { + final events = []; + void listener(DropEvent event) => events.add(event); + DesktopDrop.instance.addRawDropEventListener(listener); + addTearDown(() => DesktopDrop.instance.removeRawDropEventListener(listener)); + + await _invokePlatformMethod(const MethodCall('performOperation_linux', [ + 'smb://server/share/file.txt', + [1.0, 2.0] + ])); + + final event = events.single as DropDoneEvent; + expect(event.files.single.path, 'smb://server/share/file.txt'); + }); + + test('linux drop still converts file uri to local path', () async { + final events = []; + void listener(DropEvent event) => events.add(event); + DesktopDrop.instance.addRawDropEventListener(listener); + addTearDown(() => DesktopDrop.instance.removeRawDropEventListener(listener)); + + await _invokePlatformMethod(const MethodCall('performOperation_linux', [ + 'file:///tmp/file.txt', + [3.0, 4.0] + ])); + + final event = events.single as DropDoneEvent; + expect(event.files.single.path, '/tmp/file.txt'); + }); +}