Split mode and file choosers

Hello,

I’m wondering how to handle file choosers in split mode (both in dialogs and configuration).
For example com.intellij.openapi.fileChooser.FileChooser works with VirtualFile which would suggest backend but it’s also UI related.
There is a similar situation with preferences UI that uses com.intellij.openapi.ui.TextFieldWithBrowseButton#addBrowseFolderListener(com.intellij.openapi.ui.TextBrowseFolderListener).

So the question is where should the code live that needs to open a FileChooser.

For backend operations, I set isForcedToUseIdeaFileChooser = true on the operation’s FileChooserDescriptor. This shows the IDE’s own file chooser on the client, but the dialog runs against the backend and browses the backend’s VFS (the native OS chooser can’t be remoted, only the IDEA one).

The governing rule I’ve landed on: the chooser has to run on the side that owns the filesystem being browsed, as it can only list the filesystem of the process it runs in, and in split mode the backend is where the project’s filesystem actually lives.

If the trigger and the read/write are on the same side, handling is identical to the old monolithic flow (aside from setting isForcedToUseIdeaFileChooser on the backend). If they’re on different sides, the chooser runs on one side but the bytes originate on the other, so you’ll need a custom @Rpc remote API to transport the content across the wire to the appropriate process.

A couple of cross-process examples:

  • Browsing the client’s local filesystem, handled on the backend → open the chooser on the frontend, read the bytes there, and ship them to the backend.
  • Browsing the backend’s project filesystem, with content coming from the client → open the chooser on the backend (isForcedToUseIdeaFileChooser = true) and ship the content to the backend. This is what I ended up doing for a flow where my plugin generates a diagram on the client side and saves it to the backend when the user saves it.

Another UX to consider is when you want to enable opening/saving on either filesystem. I use an OptionAction in my plugin’s diagram export flow to allow the user to choose either saving to the client filesystem (FileChooser invoked on client using the OS chooser) or to the backend (@Rpc ships the file content to the backend and triggers a backend save dialog using the IDE’s chooser).

If anyone from JetBrains wants to chime in with more official guidance or corrections, feel free. This just where I’ve landed from my own plugin’s split mode migration after a bunch of trial and error.

Thanks, David! This is a good explanation of how things work at the moment.

In general, dialogs are advised to be registered in the frontend module since it is a UI component. But the file chooser specifically is a platform api that has to be used on backend now. Note that indeed only the platform-provided chooser will be shown in split mode, a native OS chooser opened on the backend side will be ignored.