Skip to content

explorer: add native folder pickers - #29

Closed
qianniancn wants to merge 4 commits into
gioui:mainfrom
qianniancn:explorer-dialogs
Closed

explorer: add native folder pickers#29
qianniancn wants to merge 4 commits into
gioui:mainfrom
qianniancn:explorer-dialogs

Conversation

@qianniancn

@qianniancn qianniancn commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Add native folder selection on Linux, macOS, and Windows.

Linux uses the XDG desktop portal directory option and returns the selected path without opening the directory. macOS uses NSOpenPanel as a sheet. Windows uses IFileOpenDialog for folder selection and fixes filter buffers used by the legacy file dialogs.

Use IFileOpenDialog to select a folder and return its filesystem path.

Signed-off-by: qiannian <qianniancn@gmail.com>
Build filters with embedded NUL terminators and handle single-file multi-select results.

Signed-off-by: qiannian <qianniancn@gmail.com>
Use NSOpenPanel to select a single directory and return its path through the existing callback channel.

Signed-off-by: qiannian <qianniancn@gmail.com>
Comment thread explorer/explorer_windows.go Outdated
// application resolves after the dialog closes.
_FlagNoChangeDir = uint32(0x00000008)
_FlagNoChangeDir = uint32(0x00000008)
_FOSNoChangeDir = uint32(0x00000008)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why declare a redundant constant with the same value and semantics as the prior _FlagNoChangeDir?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They correspond to OFN_NOCHANGEDIR and FOS_NOCHANGEDIR from two different
dialog APIs, but they do have the same value and semantics. I’ll replace
them with one shared constant.

Comment thread explorer/explorer_windows.go Outdated
return "", err
}

hr, err := fileDialogCall(dialog, _iModalWindowShow, e.owner.Load())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we not attempt to load the owner at the beginning of the method and fail with an error if the owner is unset? Alternatively, we could call the variant of iModalWindowShow that does not require a HWND

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I've changed this to load the owner at the start and return an error
if it hasn't been set by ListenEvents.

IFileDialog::Show doesn't have a native overload without an HWND; passing 0
would just create an unowned dialog.

@whereswaldon whereswaldon left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Historically, I've been reluctant to add a method for choosing directories because it's unclear how to implement it in a cross-browser way in WASM. However, it is clearly useful for many applications, and having most of the desktop OSes supported in one fell swoop is hard to turn down. Thank you for working on this. I have a couple of small questions, but it mostly looks great.

Use the desktop portal directory option to return a selected folder without opening it as a file.

Signed-off-by: qiannian <qianniancn@gmail.com>
@whereswaldon

Copy link
Copy Markdown
Member

Thank you, merged.

To git.sr.ht:~whereswaldon/gio-x
   a0e809e..961f4a7  main -> main

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants