# 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.




## Installing
```
export PUB_HOSTED_URL=https://pub.mirror.p-hatan.ir
flutter pub add 'file_picker_linux:2.0.0'
```
Published: 2026-09-14T07:34:58.047744Z
Expected archive SHA-256: e7db600f50672ce5ebbe422ac0906e0f3d2a476188cc93e7126afee12bf08063

Available in cache; verification: upstream_checksum
## Direct dependencies
- cross_file: ^0.3.5+4
- dbus: ^0.7.13
- file_picker_platform_interface: ^4.0.0
- flutter: map[sdk:flutter]
- path: ^1.9.0

## Package README (untrusted upstream documentation)
![File Picker for Linux](https://raw.githubusercontent.com/vicajilau/flutter_file_picker/main/.github/assets/readme_banner_linux.svg)

# 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`.

```dart
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`](https://wayland.app/protocols/xdg-foreign-unstable-v2) 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:

```bash
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`:

```dart
// 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:
   ```bash
   dart pub global activate dbus
   ```
2. Regenerate bindings against a running DBus daemon or XML interface definition:
   ```bash
   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](https://github.com/vicajilau/flutter_file_picker/issues/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](https://github.com/vicajilau/flutter_file_picker/issues/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](https://github.com/vicajilau/flutter_file_picker/issues/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](https://github.com/vicajilau/flutter_file_picker/pull/2120)








 
