Dialogs API
Overview
Section titled “Overview”The Dialogs API provides methods to show native file dialogs and message dialogs. Access dialogs through the app.Dialog manager.
Dialog Types:
- File Dialogs - Open and Save dialogs
- Message Dialogs - Info, Error, Warning, and Question dialogs
All dialogs are native OS dialogs that match the platform’s look and feel.
Accessing Dialogs
Section titled “Accessing Dialogs”Dialogs are accessed through the app.Dialog manager:
app.Dialog.OpenFile()app.Dialog.SaveFile()app.Dialog.Info()app.Dialog.Question()app.Dialog.Warning()app.Dialog.Error()File Dialogs
Section titled “File Dialogs”OpenFile()
Section titled “OpenFile()”Creates a file open dialog.
func (dm *DialogManager) OpenFile() *OpenFileDialogStructExample:
dialog := app.Dialog.OpenFile()OpenFileDialogStruct Methods
Section titled “OpenFileDialogStruct Methods”SetTitle()
Section titled “SetTitle()”Sets the dialog title.
func (d *OpenFileDialogStruct) SetTitle(title string) *OpenFileDialogStructExample:
dialog.SetTitle("Select Image")AddFilter()
Section titled “AddFilter()”Adds a file type filter.
func (d *OpenFileDialogStruct) AddFilter(displayName, pattern string) *OpenFileDialogStructParameters:
displayName- Filter description shown to user (e.g., “Images”, “Documents”)pattern- Semicolon-separated list of extensions (e.g., “.png;.jpg”)
Example:
dialog.AddFilter("Images", "*.png;*.jpg;*.gif"). AddFilter("Documents", "*.pdf;*.docx"). AddFilter("All Files", "*.*")SetDirectory()
Section titled “SetDirectory()”Sets the initial directory.
func (d *OpenFileDialogStruct) SetDirectory(directory string) *OpenFileDialogStructExample:
homeDir, _ := os.UserHomeDir()dialog.SetDirectory(homeDir)CanChooseDirectories()
Section titled “CanChooseDirectories()”Enables or disables directory selection.
func (d *OpenFileDialogStruct) CanChooseDirectories(canChooseDirectories bool) *OpenFileDialogStructExample (folder selection):
// Select folders instead of filespath, err := app.Dialog.OpenFile(). SetTitle("Select Folder"). CanChooseDirectories(true). CanChooseFiles(false). PromptForSingleSelection()CanChooseFiles()
Section titled “CanChooseFiles()”Enables or disables file selection.
func (d *OpenFileDialogStruct) CanChooseFiles(canChooseFiles bool) *OpenFileDialogStructCanCreateDirectories()
Section titled “CanCreateDirectories()”Enables or disables creating new directories.
func (d *OpenFileDialogStruct) CanCreateDirectories(canCreateDirectories bool) *OpenFileDialogStructShowHiddenFiles()
Section titled “ShowHiddenFiles()”Shows or hides hidden files.
func (d *OpenFileDialogStruct) ShowHiddenFiles(showHiddenFiles bool) *OpenFileDialogStructAttachToWindow()
Section titled “AttachToWindow()”Attaches the dialog to a specific window.
func (d *OpenFileDialogStruct) AttachToWindow(window Window) *OpenFileDialogStructPromptForSingleSelection()
Section titled “PromptForSingleSelection()”Shows the dialog and returns the selected file.
func (d *OpenFileDialogStruct) PromptForSingleSelection() (string, error)Returns:
string- Selected file path (empty if cancelled)error- Error if dialog failed
Example:
path, err := app.Dialog.OpenFile(). SetTitle("Select Image"). AddFilter("Images", "*.png;*.jpg;*.gif"). PromptForSingleSelection()
if err != nil { // User cancelled or error occurred return}
// Use the selected fileprocessFile(path)PromptForMultipleSelection()
Section titled “PromptForMultipleSelection()”Shows the dialog and returns multiple selected files.
func (d *OpenFileDialogStruct) PromptForMultipleSelection() ([]string, error)Returns:
[]string- Array of selected file pathserror- Error if dialog failed
Example:
paths, err := app.Dialog.OpenFile(). SetTitle("Select Images"). AddFilter("Images", "*.png;*.jpg"). PromptForMultipleSelection()
if err != nil { return}
for _, path := range paths { processFile(path)}SaveFile()
Section titled “SaveFile()”Creates a file save dialog.
func (dm *DialogManager) SaveFile() *SaveFileDialogStructExample:
dialog := app.Dialog.SaveFile()SaveFileDialogStruct Methods
Section titled “SaveFileDialogStruct Methods”SetTitle()
Section titled “SetTitle()”Sets the dialog title.
func (d *SaveFileDialogStruct) SetTitle(title string) *SaveFileDialogStructSetFilename()
Section titled “SetFilename()”Sets the default filename.
func (d *SaveFileDialogStruct) SetFilename(filename string) *SaveFileDialogStructExample:
dialog.SetFilename("document.pdf")AddFilter()
Section titled “AddFilter()”Adds a file type filter.
func (d *SaveFileDialogStruct) AddFilter(displayName, pattern string) *SaveFileDialogStructExample:
dialog.AddFilter("PDF Document", "*.pdf"). AddFilter("Text Document", "*.txt")SetDirectory()
Section titled “SetDirectory()”Sets the initial directory.
func (d *SaveFileDialogStruct) SetDirectory(directory string) *SaveFileDialogStructAttachToWindow()
Section titled “AttachToWindow()”Attaches the dialog to a specific window.
func (d *SaveFileDialogStruct) AttachToWindow(window Window) *SaveFileDialogStructPromptForSingleSelection()
Section titled “PromptForSingleSelection()”Shows the dialog and returns the save path.
func (d *SaveFileDialogStruct) PromptForSingleSelection() (string, error)Example:
path, err := app.Dialog.SaveFile(). SetTitle("Save Document"). SetFilename("untitled.pdf"). AddFilter("PDF Document", "*.pdf"). PromptForSingleSelection()
if err != nil { // User cancelled return}
// Save to the selected pathsaveDocument(path)Folder Selection
Section titled “Folder Selection”There is no separate SelectFolderDialog. Use OpenFile() with directory options:
path, err := app.Dialog.OpenFile(). SetTitle("Select Output Folder"). CanChooseDirectories(true). CanChooseFiles(false). PromptForSingleSelection()
if err != nil { // User cancelled return}
// Use the selected folderoutputDir = pathMessage Dialogs
Section titled “Message Dialogs”All message dialogs return *MessageDialog and share the same methods.
Info()
Section titled “Info()”Creates an information dialog.
func (dm *DialogManager) Info() *MessageDialogExample:
app.Dialog.Info(). SetTitle("Success"). SetMessage("File saved successfully!"). Show()Error()
Section titled “Error()”Creates an error dialog.
func (dm *DialogManager) Error() *MessageDialogExample:
app.Dialog.Error(). SetTitle("Error"). SetMessage("Failed to save file: " + err.Error()). Show()Warning()
Section titled “Warning()”Creates a warning dialog.
func (dm *DialogManager) Warning() *MessageDialogExample:
app.Dialog.Warning(). SetTitle("Warning"). SetMessage("This action cannot be undone."). Show()Question()
Section titled “Question()”Creates a question dialog with custom buttons.
func (dm *DialogManager) Question() *MessageDialogExample:
dialog := app.Dialog.Question(). SetTitle("Confirm"). SetMessage("Do you want to save changes?")
save := dialog.AddButton("Save")save.OnClick(func() { saveDocument()})
dontSave := dialog.AddButton("Don't Save")dontSave.OnClick(func() { // Continue without saving})
cancel := dialog.AddButton("Cancel")cancel.OnClick(func() { // Do nothing})
dialog.SetDefaultButton(save)dialog.SetCancelButton(cancel)dialog.Show()MessageDialog Methods
Section titled “MessageDialog Methods”SetTitle()
Section titled “SetTitle()”Sets the dialog title.
func (d *MessageDialog) SetTitle(title string) *MessageDialogSetMessage()
Section titled “SetMessage()”Sets the dialog message.
func (d *MessageDialog) SetMessage(message string) *MessageDialogSetIcon()
Section titled “SetIcon()”Sets a custom icon for the dialog.
func (d *MessageDialog) SetIcon(icon []byte) *MessageDialogAddButton()
Section titled “AddButton()”Adds a button to the dialog and returns the button for configuration.
func (d *MessageDialog) AddButton(label string) *ButtonReturns: *Button - The button instance for further configuration
Example:
button := dialog.AddButton("OK")button.OnClick(func() { // Handle click})SetDefaultButton()
Section titled “SetDefaultButton()”Sets which button is the default (activated by pressing Enter).
func (d *MessageDialog) SetDefaultButton(button *Button) *MessageDialogExample:
yes := dialog.AddButton("Yes")no := dialog.AddButton("No")dialog.SetDefaultButton(yes)SetCancelButton()
Section titled “SetCancelButton()”Sets which button is the cancel button (activated by pressing Escape).
func (d *MessageDialog) SetCancelButton(button *Button) *MessageDialogExample:
ok := dialog.AddButton("OK")cancel := dialog.AddButton("Cancel")dialog.SetCancelButton(cancel)AttachToWindow()
Section titled “AttachToWindow()”Attaches the dialog to a specific window.
func (d *MessageDialog) AttachToWindow(window Window) *MessageDialogShow()
Section titled “Show()”Shows the dialog. Button callbacks handle user responses.
func (d *MessageDialog) Show()Note: Show() does not return a value. Use button callbacks to handle user responses.
Button Methods
Section titled “Button Methods”OnClick()
Section titled “OnClick()”Sets the callback function for when the button is clicked.
func (b *Button) OnClick(callback func()) *ButtonSetAsDefault()
Section titled “SetAsDefault()”Marks this button as the default button.
func (b *Button) SetAsDefault() *ButtonSetAsCancel()
Section titled “SetAsCancel()”Marks this button as the cancel button.
func (b *Button) SetAsCancel() *ButtonComplete Examples
Section titled “Complete Examples”File Selection Example
Section titled “File Selection Example”type FileService struct { app *application.App}
func (s *FileService) OpenImage() (string, error) { path, err := s.app.Dialog.OpenFile(). SetTitle("Select Image"). AddFilter("Images", "*.png;*.jpg;*.jpeg;*.gif"). AddFilter("All Files", "*.*"). PromptForSingleSelection()
if err != nil { return "", err }
return path, nil}
func (s *FileService) SaveDocument(defaultName string) (string, error) { path, err := s.app.Dialog.SaveFile(). SetTitle("Save Document"). SetFilename(defaultName). AddFilter("PDF Document", "*.pdf"). AddFilter("Text Document", "*.txt"). PromptForSingleSelection()
if err != nil { return "", err }
return path, nil}
func (s *FileService) SelectOutputFolder() (string, error) { path, err := s.app.Dialog.OpenFile(). SetTitle("Select Output Folder"). CanChooseDirectories(true). CanChooseFiles(false). PromptForSingleSelection()
if err != nil { return "", err }
return path, nil}Confirmation Dialog Example
Section titled “Confirmation Dialog Example”func (s *Service) DeleteItem(app *application.App, id string) { dialog := app.Dialog.Question(). SetTitle("Confirm Delete"). SetMessage("Are you sure you want to delete this item?")
deleteBtn := dialog.AddButton("Delete") deleteBtn.OnClick(func() { deleteFromDatabase(id) })
cancelBtn := dialog.AddButton("Cancel") // Cancel does nothing
dialog.SetDefaultButton(cancelBtn) // Default to Cancel for safety dialog.SetCancelButton(cancelBtn) dialog.Show()}Save Changes Dialog
Section titled “Save Changes Dialog”func (s *Editor) PromptSaveChanges(app *application.App) { dialog := app.Dialog.Question(). SetTitle("Unsaved Changes"). SetMessage("Do you want to save your changes before closing?")
save := dialog.AddButton("Save") save.OnClick(func() { s.Save() s.Close() })
dontSave := dialog.AddButton("Don't Save") dontSave.OnClick(func() { s.Close() })
cancel := dialog.AddButton("Cancel") // Cancel does nothing, dialog closes
dialog.SetDefaultButton(save) dialog.SetCancelButton(cancel) dialog.Show()}Multi-File Processing
Section titled “Multi-File Processing”func (s *Service) ProcessMultipleFiles(app *application.App) error { // Select multiple files paths, err := app.Dialog.OpenFile(). SetTitle("Select Files to Process"). AddFilter("Images", "*.png;*.jpg"). PromptForMultipleSelection()
if err != nil { return err }
if len(paths) == 0 { app.Dialog.Info(). SetTitle("No Files Selected"). SetMessage("Please select at least one file."). Show() return nil }
// Process files for _, path := range paths { err := processFile(path) if err != nil { app.Dialog.Error(). SetTitle("Processing Error"). SetMessage(fmt.Sprintf("Failed to process %s: %v", path, err)). Show() continue } }
// Show completion app.Dialog.Info(). SetTitle("Complete"). SetMessage(fmt.Sprintf("Successfully processed %d files", len(paths))). Show()
return nil}Error Handling with Dialogs
Section titled “Error Handling with Dialogs”func (s *Service) SaveFile(app *application.App, data []byte) error { // Select save location path, err := app.Dialog.SaveFile(). SetTitle("Save File"). SetFilename("data.json"). AddFilter("JSON File", "*.json"). PromptForSingleSelection()
if err != nil { // User cancelled - not an error return nil }
// Attempt to save err = os.WriteFile(path, data, 0644) if err != nil { // Show error dialog app.Dialog.Error(). SetTitle("Save Failed"). SetMessage(fmt.Sprintf("Could not save file: %v", err)). Show() return err }
// Show success app.Dialog.Info(). SetTitle("Success"). SetMessage("File saved successfully!"). Show()
return nil}Platform-Specific Defaults
Section titled “Platform-Specific Defaults”import ( "os" "path/filepath" "runtime")
func (s *Service) GetDefaultDirectory() string { homeDir, _ := os.UserHomeDir()
switch runtime.GOOS { case "windows": return filepath.Join(homeDir, "Documents") case "darwin": return filepath.Join(homeDir, "Documents") case "linux": return filepath.Join(homeDir, "Documents") default: return homeDir }}
func (s *Service) OpenWithDefaults(app *application.App) (string, error) { return app.Dialog.OpenFile(). SetTitle("Open File"). SetDirectory(s.GetDefaultDirectory()). AddFilter("All Files", "*.*"). PromptForSingleSelection()}Best Practices
Section titled “Best Practices”- Use native dialogs - They match the platform’s look and feel
- Provide clear titles - Help users understand the purpose
- Set appropriate filters - Guide users to correct file types
- Handle cancellation - Check for errors (user may cancel)
- Show confirmation for destructive actions - Use Question dialogs
- Provide feedback - Use Info dialogs for success messages
- Set sensible defaults - Default directory, filename, etc.
- Use callbacks for button actions - Handle user responses properly
- Don’t ignore errors - User cancellation returns an error
- Don’t use ambiguous button labels - Be specific: “Save”/“Cancel”
- Don’t overuse dialogs - They interrupt workflow
- Don’t show errors for cancellation - It’s a normal action
- Don’t forget file filters - Help users find the right files
- Don’t hardcode paths - Use os.UserHomeDir() or similar
Dialog Types by Platform
Section titled “Dialog Types by Platform”- Dialogs slide down from title bar
- “Sheet” style attached to parent window
- Native macOS appearance
Windows
Section titled “Windows”- Standard Windows dialogs
- Follows Windows design guidelines
- Modern Windows 10/11 appearance
- GTK dialogs on GTK-based systems
- Qt dialogs on Qt-based systems
- Matches desktop environment
Linux GTK4 Limitations
Section titled “Linux GTK4 Limitations”On Linux with GTK4 (the default for modern distributions), file dialogs use the xdg-desktop-portal for native integration. This provides better desktop integration but means some options have no effect:
| Option | GTK3 | GTK4 | Notes |
|---|---|---|---|
ShowHiddenFiles() | ✅ Works | ❌ No effect | User controls via dialog’s UI toggle (Ctrl+H or menu) |
CanCreateDirectories() | ✅ Works | ❌ No effect | Always enabled in the portal |
ResolvesAliases() | ✅ Works | ❌ No effect | Portal handles symlink resolution |
SetButtonText() | ✅ Works | ✅ Works | Custom accept button text works |
Why these limitations exist: GTK4’s portal-based dialogs delegate UI control to the desktop environment (GNOME, KDE, etc.). This is by design - the portal provides consistent UX across applications and respects user preferences.
Common Patterns
Section titled “Common Patterns””Save As” Pattern
Section titled “”Save As” Pattern”func (s *Service) SaveAs(app *application.App, currentPath string) (string, error) { // Extract filename from current path filename := filepath.Base(currentPath)
// Show save dialog path, err := app.Dialog.SaveFile(). SetTitle("Save As"). SetFilename(filename). PromptForSingleSelection()
if err != nil { return "", err }
return path, nil}”Open Recent” Pattern
Section titled “”Open Recent” Pattern”func (s *Service) OpenRecent(app *application.App, recentPath string) error { // Check if file still exists if _, err := os.Stat(recentPath); os.IsNotExist(err) { dialog := app.Dialog.Question(). SetTitle("File Not Found"). SetMessage("The file no longer exists. Remove from recent files?")
remove := dialog.AddButton("Remove") remove.OnClick(func() { s.removeFromRecent(recentPath) })
cancel := dialog.AddButton("Cancel") dialog.SetCancelButton(cancel) dialog.Show()
return err }
return s.openFile(recentPath)}