Repository navigation
Conversation
A file chooser for xdg-desktop-portal (org.freedesktop.impl.portal.FileChooser), so other apps' Open and Save dialogs can be Folio: the same window, with a bar along the bottom for the name to save under, the app's filters and choices, and the answer. folio chooser is started by D-Bus for the first dialog and goes a minute after the last. OpenFile (files or folders, one or several), SaveFile and SaveFiles are answered, with filters, choices, the folder and name to start from, a Replace prompt before a save writes over a file, and the portal closing a request. Opt-in through portals.conf (see the README).
A Save dialog starts with the keyboard in the name, where the keys for the files stand aside. Going to type a path is the one that shouldn't: it's how to get to a server, or anywhere the sidebar doesn't list.
[Medium impact] The PR appears safe to merge; no actionable issues remain from this review. SummaryAdds
|
… five smaller fixes From the review of the pull request: - Picking a folder (or saving files into one), nothing inside is selected on arrival, so Choose is the folder shown rather than its first subfolder. - A filter's patterns match a file's own name in search results too, which are named by their path from the folder searched. - A search counts only what the filter lists toward its limit. - A choice the app leaves unset starts on its first option, a checkbox unticked. - Files saved into a folder never answer with a folder of the same name: the file goes beside it under the next free name. - Only the caller that asked for a dialog can close it.
…aved files never share a name From the second review pass: - Picking a folder, coming back up out of one no longer selects it, and a split's right pane starts with nothing selected too, so Choose is always the folder shown until one is picked. The pane does this itself as each folder arrives, rather than the bar watching one pane. - Files saved into a folder that are moved aside from a folder of their name take a name no other file in the same save has.
From the third review pass: selecting nothing on arrival also dropped what file work had just made in the folder being shown. Only arriving somewhere else clears the selection now, so a new folder is still the one chosen.
|
Please do add some screenshots/screenrecordings! |
|
Here you go. On a real site (squoosh.app in Chromium): its picker opens Folio, a photo is picked from the grid, the site compresses it, and the download saves over the original through Folio's Save dialog, with the Replace prompt. (mp4) The rest of it, from a test page: the sidebar, the grid, the filter menu, picking several, a typed name and Replace, and choosing a folder. (mp4) Open, three picked, with the app's filter in the bar: Save As, with the app's filter and its own choice (Encoding) beside the name: Replace, before a save writes over a file: Choose a Folder: the bar says which folder Choose means, the one picked or else the one shown (nothing is picked on arrival). These are from a headless session, so each window fills the screen; on a desktop the dialog is its own window (app id |
… settled main now hides the window's contents until Hyprland has sized it, and gives the keyboard to the files when they appear. A Save dialog gives it to the name instead, at the same moment.
…ps the space From the review: the name typed is trimmed, which is right for a stray space but saved a file like " report.txt", opened in the window to write over it, under another name. A file that exists exactly as the field has it is that file.
A name is saved as it's typed, for a new file as for one that's there: spaces at the ends are part of a file's name. The path bar still trims what it's given.
…eld up xdg-desktop-portal makes a proxy for every backend portals.conf names as it starts, which D-Bus-activates folio chooser and waits for it to take its name. Omarchy sets QT_QPA_PLATFORMTHEME=qtengine, and that plugin reads org.freedesktop.portal.Settings while QGuiApplication is built, before the name is taken. The portal can't answer until it has finished starting, so both wait until Qt's 25 second timeout lets the chooser go on. Every portal start took 25 seconds instead of 50 ms, holding up every app waiting on any portal, and when Qt's timeout landed after the portal's own, the portal gave up on Folio and left FileChooser out for the whole session. Qt's generic theme reads nothing from the portal. The chooser still looks like Folio, which sets its own font, Material style and colours; what it gives up is the desktop's icon theme for its window icon and any input timings a theme plugin supplies, such as the double-click interval. With it, the portal starts in about 110 ms. Also drops the older of two stacked versions of one comment in ChooserPortal::ask. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Reviewed at 42c13e1, plus one fix pushed on top as dca6263. What was checked. The whole diff, read against On a disposable Omarchy VM (Qt 6.12, xdg-desktop-portal 1.22.1), not on a machine with credentials:
What was found, and fixed in dca6263. With Folio named as the FileChooser, every start of xdg-desktop-portal took 25 seconds, against 50 ms without it. The portal makes a proxy for every backend as it starts, which D-Bus-activates The fix starts the chooser on Qt's Second opinion. Codex (GPT-6, medium effort) and muse-wonder (thinking high) reviewed the diff independently, reading only. Neither found the startup stall; the VM run did. Codex also read the fix: it found no blocking defect, confirmed Qt's generic theme makes no synchronous portal call, and noted that a hand-typed
Other points from the review that hold up but are small: a failed window or a duplicate handle answers with a D-Bus error rather than response 2; the service watcher is armed only after the window opens; Trash is accepted as a place to save into; Two claims didn't hold: that the backend must expose a Open, for the maintainer. 🤖 Generated by Opus 5.5 in Claude Code. Reviewed by Codex Medium and Muse-Wonder High. |
A file whose name says nothing of its type was read again for each type a filter names, and what a search found was filtered a second time. It's read once now, a search's results are left as the search filtered them, and the filtering stops once a newer listing has replaced the one being read.
|
Want your agent to iterate on Greptile's feedback? Try greploops. |






For #40. Folio as the file chooser other apps show: an
xdg-desktop-portalFileChooser backend, so Open and Save dialogs are a Folio window rather than the GTK one.What it is
folio chooserservesorg.freedesktop.impl.portal.FileChooser. D-Bus starts it for the first dialog and it goes a minute after the last one closes, so nothing runs while no one is using it.Main.qml: same views, sidebar, previews, keys) with a bar along the bottom,ChooserBar.qml: the name to save under, the app's filters and choices, Cancel and the answer.portals.confnamesfoliofor the FileChooser (README has the three lines).How it fits
FolderModelgets afilter(name patterns and MIME types). Files that fit none aren't listed; folders always are. An ordinary window has no filter and lists as before.Windows::open()takes an optionalChooser; the window's context carries it aschooser, null everywhere else.Backend::open()on a file hands it to the chooser rather than starting an app.share/gainsfolio.portal, the D-Bus service file and a hiddenfolio-chooser.desktop. Windows have the app idfolio-chooser, for a rule to float them.Checked
bin/test: 201 pass, seven of them new (filter, reading a request, working out an answer, answering once, the bar).xdg-desktop-portalwith Folio started by D-Bus: GTK 4 (GtkFileDialogopen, open several, save, folder), zenity, a Qt QuickFileDialogthrough Qt's portal theme, an upload from a page in Chromium, and an upload and a download's Save As in Firefox.Main.qmlunder ASan/UBSan, by mouse and keyboard, in all three views: double click, shift/alt click and the button, the filter and choice menus, typing a name (Q, S, / and ? are typed, not acted on), Replace, two dialogs at once, a split pane, right to left, 30,000 files..., a handle used twice): each gets an answer or an error and the service stays up.current_name, SaveFiles'files) are taken as bare names; only the user can type a path.Not here
share/folio.portalto/usr/share/xdg-desktop-portal/portals/, the service file to/usr/share/dbus-1/services/andfolio-chooser.desktopto/usr/share/applications/. Happy to send that once this shape is settled.hyprland-portals.conf, and a window rule forfolio-chooser).en.jsononly, for the translation sync.One thing found on the way that isn't this PR's:
FolderColumns.qmlcallsbackend.showItem(path)for a click on a file in an ancestor column, butBackend::showItemisn'tQ_INVOKABLE, so the click logs a TypeError and does nothing. I can send that separately.