GIO file monitor never fires on Flatpak document portal paths

I’m building a Flatpak-sandboxed GTK4/Rust application and trying to monitor dependency files for changes using gio::FileMonitor. The app is a Typst document editor, and the functionality I’m trying to implement is to trigger a recompilation of the main file if/when any imported files referenced from the main file change on disk.

Files accessed through the Flatpak document portal appear under paths like /run/user/1000/doc/ca6abb15/test/lib.typ. I’m creating a file monitor on these paths like so:

let file = gio::File::for_path(&path);
let monitor = file.monitor_file(gio::FileMonitorFlags::NONE, gio::Cancellable::NONE)?;
monitor.connect_changed(move |_, file, _, event| {
    println!("Event: {:?} on {:?}", event, file.path());
});

The monitor is created successfully. However, when I modify a monitored file in another app, the connect_changed callback never fires, not for Changed, ChangesDoneHint, or any other event.

Is GIO file monitoring expected to work on Flatpak document portal FUSE paths (/run/user/1000/doc/...)? If not, is there a supported way to monitor files for changes within the Flatpak sandbox, given that I can’t resolve portal paths to real filesystem paths without breaking the sandbox?

1 Like

FUSE does not support file monitoring events, and that prevents monitoring files exposed by the document portal.

One option would be to have GFileMonitor in GIO detect the case of running on a FUSE file system, and reverting to a timed poll, even though it’s not the greatest solution. It would also need to be an hardcoded check, because Linux file systems do not expose capabilities or feature support.

Actually, now that I think about it: even a timed poll would be of limited use; if something else is modifying the file outside the sandbox, and writing atomically, it could replace the original file. Normally, that would be seen as an event on the parent directory, but since the parent directory is not in the document portal, you would still see the old file.

1 Like

I was wondering if it makes sense to propose a new portal that Gio could use to delegate the actual monitoring to e.g. the Document Portal, outside of the sandbox, and report changes notifications over dbus back to the app.

You don’t need a whole new portal: adding API to the Document portal interface to proxy file system events from outside the sandbox to inside the sandbox is possible; then we’d need a GFileMonitor implementation that uses those notifications when it detects a location inside the document portal, and emits the corresponding changes.

The important part is to avoid leaking information from outside the sandbox into the sandbox, and vice versa, as the portal is a security boundary.

1 Like

Yes that was the idea, “just” a new interface to the existing Document portal.

What would be the reasons against completing the implementation of file monitoring in FUSE, so that we don’t need to maintain yet another GFileMonitor backend (they are complicated)?

Implementing fanotify events in FUSE would definitely be the best option, but:

  • it’s been a request for a decade and the libfuse maintainers have no plans on working on it
  • nobody has showed up to work on it independently
  • it’s entirely unknown whether it’s just a matter of fixing libfuse, or if it needs changes in the Linux kernel itself, which would add additional requirements on its availability
2 Likes