Package limn.backend

Interface FileDialogs


public interface FileDialogs
Native system file/folder dialogs, obtained via Backend.fileDialogs(). Each call opens the platform's chooser and blocks the UI thread until the user picks or cancels (system-modal, like every native app). UI thread only. Headless/embedded backends return NONE, whose dialogs resolve empty; callers must treat "empty" as "cancelled" and need no headless branch.

The application stops while the panel is up, and the first call is dearer than the rest. On macOS and Linux the chooser is not drawn by this process at all: a command goes to a helper program (osascript on macOS, zenity or kdialog on Linux) and one line of its output is the answer. So while the panel is open, this process runs no frames: its windows keep showing the frame presented just before the call, animations do not advance, and no timer or posted task runs until the user is done. That last frame is drawn immediately before blocking, so what stays on screen reflects whatever the calling handler already changed: a button that renders released, not one frozen mid-press. Starting the helper costs tens of milliseconds on every call, and the first call in a process pays a further one-off setup (on the order of a quarter of a second) before any panel appears. A caller that cannot afford that pause on a click, such as a game loop or a video that must keep playing, should not open a file dialog from one. On Windows the chooser runs inside this process instead, on the calling thread, so its own message loop can still service window repaints there; the thread is unavailable to the toolkit either way.

No asynchronous form, and none would be right. A system-modal panel's whole contract is that the application is unusable while it is up, so a chooser opened from a worker would leave this process drawing frames and taking clicks behind a panel the platform believes is blocking them. What is being waited for is the user, not a disk, so there is no work here to move off the thread, only a pause to keep off a click that cannot afford one.

One at a time. The chooser is not reentrant, and a second one opened before the first returns is undefined. This is reachable only through code that runs while the call is on the stack, which is why the Windows difference above is worth knowing.

These are the platform's own panels, so how they look, where they appear, and which shortcuts and sidebar places they offer are the platform's to decide, not the toolkit theme's, and not this API's.

Title and initial path are bounded on macOS and Linux. There the helper's command line has a fixed size, so a title and an initial path that would not fit it together are shortened before the call: the path is dropped in favour of the panel's own default folder first, and only a title too long on its own is cut. A few hundred bytes between them always fit.