Viewing version 2.0.0. Open the latest package page.
file_picker_linux
2.0.0Linux implementation of the file_picker plugin using GTK3 and XDG Desktop Portals for native file and directory picking.
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:
- Install
dart-dbusglobally via Pub:dart pub global activate dbus - 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 returnsFuture<int?>instead ofFuture<int>. Returnsnullwhen the length could not be determined (e.g. a failed disk read), instead of0, matchinglengthSync(). #2197
1.1.0
- Implemented
PlatformFile.lengthSync(). XDG Desktop Portals only return a file path, not its size, so this returnsnullon Linux, uselength()to actually read it from disk.
1.0.2
- Fixed
LinuxOptions.lockParentWindowandLinuxOptions.acceptLabelbeing silently ignored. Passing a plainLinuxOptionsfell back to a defaultFilePickerLinuxOptions, dropping whatever the caller had set, which is the exact API the deprecation onFilePicker.pickFilespoints to. #2183 FilePickerLinuxOptionsnow acceptsacceptLabel, so it no longer has to be traded away in order to setparentWindow.- Documented the Linux specific options in the README, including that
lockParentWindowneedsparentWindowto have any visible effect. - Expanded the package example to show resolving
parentWindowat runtime, which is what makeslockParentWindowlock anything. - Tightened the
file_picker_platform_interfacelower bound to^3.2.0. This package'spickFile()/pickFiles()signatures referenceDarwinOptions, added in that version, so resolving against an older one would fail to compile.
1.0.1
- Relax
dbusto^0.7.13so dependents can resolvexml7. #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
acceptLabelinLinuxOptionsto customize the confirmation button label in file dialogs. #2120
Installing
export PUB_HOSTED_URL=https://pub.mirror.p-hatan.com
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
| Version | Published | Archive | SHA-256 |
|---|---|---|---|
| 1.0.0 | On demand | Download | 5f8e1de3…797bf1 |
| 1.0.1 | On demand | Download | 93d3f62f…844e3b |
| 1.0.2 | On demand | Download | f0f01ed4…7b04ae |
| 1.1.0 | On demand | Download | bd52ff1e…946cb9 |
| 2.0.0 | Cached · Upstream SHA-256 matched | Download | e7db600f…f08063 |
| 2.0.1 | On demand | Download | 9c870771…3ea5ce |
| 2.0.2 | On demand | Download | c6562fc7…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"