Viewing version 2.0.0. Open the latest package page.

file_picker_linux

2.0.0

Linux implementation of the file_picker plugin using GTK3 and XDG Desktop Portals for native file and directory picking.

Download archive

Readme

File Picker for Linux

file_picker_linux

The Linux implementation of file_picker.

Usage

This package is endorsed, which means you can simply use file_picker as normal, and the Linux implementation will be automatically included.

Linux specific options

Pass LinuxOptions for the options shared with other desktop platforms, or FilePickerLinuxOptions when you also need parentWindow.

final file = await FilePicker.pickFile(
  linuxOptions: const FilePickerLinuxOptions(
    acceptLabel: 'Choose',
    lockParentWindow: true,
    parentWindow: 'x11:0x1c00007',
  ),
);

acceptLabel

Replaces the text on the dialog's confirmation button. Only applies to file picking (pickFile, pickFiles), the portal does not take it for directory selection or saving.

lockParentWindow

Sent to the portal as modal. On its own it has no visible effect: the portal needs to know which window to be modal against, so it only locks the parent once parentWindow is also set.

Whether you can set parentWindow at all depends on the session type, which makes this option behave very differently on X11 and on Wayland:

Session Handle the portal expects Practical result
X11 the window XID obtainable, so the dialog is parented and genuinely modal
Wayland an xdg_foreign exported handle Flutter does not expose one, so the dialog stays unparented and lockParentWindow has no visible effect

Wayland is the default on current desktops, Ubuntu GNOME and Fedora included, so the second row is the common case rather than the exception. The option is still sent to the portal correctly, there is simply no window for the portal to attach the dialog to.

If you need real modality today, the X11 path works. On a Wayland session the app has to be running on XWayland, which GDK_BACKEND=x11 forces:

GDK_BACKEND=x11 flutter run -d linux

The XID changes on every run, so it has to be read at runtime rather than hardcoded. There is no Flutter API for it, so it takes an external tool such as xdotool:

// Search for an X window belonging to this process. Do not use
// `xdotool getactivewindow`: with XWayland running it returns the focused X
// window, which on a Wayland session belongs to a different application.
final result = await Process.run(
  'xdotool',
  ['search', '--pid', '$pid', '--onlyvisible'],
);
final ids = (result.stdout as String)
    .split('\n')
    .map((line) => line.trim())
    .where((line) => line.isNotEmpty);

final file = await FilePicker.pickFile(
  linuxOptions: FilePickerLinuxOptions(
    lockParentWindow: true,
    parentWindow: ids.isEmpty ? null : ids.last, // e.g. 25165834
  ),
);

On a native Wayland session the search comes back empty, which is the correct answer: the process genuinely has no X window to parent to.

parentWindow takes the decimal value directly and converts it, see the table below. Depending on xdotool at runtime is obviously not great for a shipped app, it is shown here because it is the only way to get the handle today.

parentWindow

The window identifier handed to the portal so it can parent the dialog. Accepted forms:

You pass Sent as
x11:0x1c00007 unchanged
wayland:<handle> unchanged
0x1c00007 x11:0x1c00007
29360135 (decimal) x11:0x1c00007
null or empty no parent window

Flutter does not expose the native window handle, so obtaining it is on you. See the session table under lockParentWindow for what that means in practice.

Development

The DBus bindings in lib/src/xdp_filechooser.dart and lib/src/xdp_request.dart are generated using dart-dbus from the XDG Desktop Portal DBus interface specifications on Linux:

  1. Install dart-dbus globally via Pub:
    dart pub global activate dbus
    
  2. Regenerate bindings against a running DBus daemon or XML interface definition:
    dart-dbus generate-remote-object org.freedesktop.portal.FileChooser
    dart-dbus generate-remote-object org.freedesktop.portal.Request
    
Changelog

2.0.0

  • BREAKING CHANGE: PlatformFile.length() now returns Future<int?> instead of Future<int>. Returns null when the length could not be determined (e.g. a failed disk read), instead of 0, matching lengthSync(). #2197

1.1.0

  • Implemented PlatformFile.lengthSync(). XDG Desktop Portals only return a file path, not its size, so this returns null on Linux, use length() to actually read it from disk.

1.0.2

  • Fixed LinuxOptions.lockParentWindow and LinuxOptions.acceptLabel being silently ignored. Passing a plain LinuxOptions fell back to a default FilePickerLinuxOptions, dropping whatever the caller had set, which is the exact API the deprecation on FilePicker.pickFiles points to. #2183
  • FilePickerLinuxOptions now accepts acceptLabel, so it no longer has to be traded away in order to set parentWindow.
  • Documented the Linux specific options in the README, including that lockParentWindow needs parentWindow to have any visible effect.
  • Expanded the package example to show resolving parentWindow at runtime, which is what makes lockParentWindow lock anything.
  • Tightened the file_picker_platform_interface lower bound to ^3.2.0. This package's pickFile()/pickFiles() signatures reference DarwinOptions, added in that version, so resolving against an older one would fail to compile.

1.0.1

  • Relax dbus to ^0.7.13 so dependents can resolve xml 7. #2130
  • Improved package description, added example, and added missing API documentation.

1.0.0

  • Initial release of Linux implementation package for file_picker.
  • Added support for acceptLabel in LinuxOptions to customize the confirmation button label in file dialogs. #2120

Installing

export PUB_HOSTED_URL=https://pub.mirror.p-hatan.ir
flutter pub add 'file_picker_linux:2.0.0'
pubspec.yaml
name: file_picker_linux
description: Linux implementation of the file_picker plugin using GTK3 and XDG Desktop Portals for native file and directory picking.
version: 2.0.0
homepage: https://github.com/vicajilau/flutter_file_picker/tree/main/packages/file_picker_linux
repository: https://github.com/vicajilau/flutter_file_picker/tree/main/packages/file_picker_linux
topics:
  - file-picker
  - linux

resolution: workspace

environment:
  sdk: ">=3.10.0 <4.0.0"
  flutter: ">=3.38.0"

flutter:
  plugin:
    implements: file_picker
    platforms:
      linux:
        dartPluginClass: FilePickerLinux

dependencies:
  flutter:
    sdk: flutter
  file_picker_platform_interface: ^4.0.0
  cross_file: ^0.3.5+4
  dbus: ^0.7.13
  path: ^1.9.0

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^6.0.0

Version history

VersionPublishedArchiveSHA-256
1.0.0On demandDownload5f8e1de3…797bf1
1.0.1On demandDownload93d3f62f…844e3b
1.0.2On demandDownloadf0f01ed4…7b04ae
1.1.0On demandDownloadbd52ff1e…946cb9
2.0.0Cached · Upstream SHA-256 matchedDownloade7db600f…f08063
2.0.1On demandDownload9c870771…3ea5ce
2.0.2On demandDownloadc6562fc7…9cf4da

Dependencies

cross_file "^0.3.5+4"

dbus "^0.7.13"

file_picker_platform_interface "^4.0.0"

flutter { "sdk": "flutter" }

path "^1.9.0"