Guides
Native APIs
Dialogs, notifications, the clipboard, the shell, displays, dark mode, power and global shortcuts.
MyGo wraps the parts of the operating system desktop apps use most. Like the rest of MyGo, each can be called from any goroutine.
Dialogs
mygo.Dialog shows the system's file and message dialogs. Its methods
block until the user answers: call them from bound methods, which run on
goroutines of their own, or start a goroutine for them in event listeners
and menu items, which should return quickly. Parent attaches a dialog to a
window, as a sheet on macOS.
// Pick files.
paths, err := mygo.Dialog.Open(mygo.OpenDialogOptions{
Parent: win,
Title: "Import",
Filters: []mygo.FileFilter{{Name: "Images", Extensions: []string{"png", "jpg"}}},
Multiple: true,
}) // nil when canceled
// Choose where to save.
path, err := mygo.Dialog.Save(mygo.SaveDialogOptions{
Parent: win,
DefaultPath: "notes.json",
}) // "" when canceled
// Ask a question.
res, err := mygo.Dialog.Message(mygo.MessageOptions{
Parent: win,
Type: mygo.MessageWarning,
Message: "Delete 3 notes?",
Detail: "You cannot undo this.",
Buttons: []string{"Delete", "Cancel"},
CheckboxLabel: "Don't ask again",
})
if res.Button == 0 { /* Delete */ }
// Report an error.
mygo.Dialog.Error("Import failed", err.Error())OpenDialogOptions also pick directories (Directory), show hidden files
and, on macOS, a message and a New Folder button. In message dialogs Enter
activates DefaultButton and Escape CancelButton, by default the first
button labeled Cancel or No.
Notifications
n := mygo.NewNotification(mygo.NotificationOptions{
Title: "Export finished",
Body: "notes.json was saved to Documents.",
})
n.OnClick(func() { mainWindow().Focus() })
if err := n.Show(); err != nil {
log.Println(err)
}Close removes a notification. macOS shows notifications of packaged apps
only, which mygo dev and mygo build make; mygo.NotificationsSupported()
reports whether the app can show them. Linux shows them through the
desktop's notification service, Windows as notification-area balloons.
Clipboard
mygo.Clipboard.WriteText("hello")
text := mygo.Clipboard.ReadText()
mygo.Clipboard.WriteHTML("<b>hello</b>")
mygo.Clipboard.WriteImage(png) // a PNG
img := mygo.Clipboard.ReadImage()
formats := mygo.Clipboard.AvailableFormats()
mygo.Clipboard.Clear()Pages can use the web's navigator.clipboard too.
The shell
mygo.Shell.OpenExternal("https://example.com") // the default browser
mygo.Shell.OpenPath("/Users/ada/report.pdf") // the default app for the file
mygo.Shell.ShowItemInFolder(path) // Finder, Explorer, the file manager
mygo.Shell.TrashItem(path) // to the trash
mygo.Shell.Beep()Displays
mygo.Screen describes the connected displays, in device-independent
pixels with the origin at the top-left corner of the primary display:
primary := mygo.Screen.PrimaryDisplay()
fmt.Println(primary.Bounds, primary.WorkArea, primary.ScaleFactor)
for _, d := range mygo.Screen.Displays() { /* ... */ }
cursor := mygo.Screen.CursorScreenPoint()
d := mygo.Screen.DisplayNearestPoint(cursor)
mygo.Screen.OnDisplaysChanged(func() { /* rearrange windows */ })WorkArea leaves out the menu bar, the Dock and taskbars.
DisplayMatching(rect) returns the display a rectangle overlaps most, the
one a window is on.
Dark mode
mygo.Theme is the light or dark appearance, which pages follow through
the prefers-color-scheme media query:
dark := mygo.Theme.IsDark()
mygo.Theme.OnUpdated(func() { log.Println("dark:", mygo.Theme.IsDark()) })
mygo.Theme.SetSource(mygo.ThemeDark) // or ThemeLight, or ThemeSystem to follow the systemSetSource may be called before App.Run, for example with an appearance
the user saved in the app's preferences: the app then starts in it.
Power
// Keep the computer awake during a long task, and the display on with true.
release := mygo.Power.KeepAwake("Exporting the video", false)
defer release()
mygo.Power.OnSuspend(func() { pauseSync() })
mygo.Power.OnResume(func() { resumeSync() })
mygo.Power.OnLockScreen(func() { hideSecrets() })
mygo.Power.OnUnlockScreen(func() { /* ... */ })
onBattery := mygo.Power.IsOnBattery()
idle := mygo.Power.IdleTime() // since the last keyboard or mouse inputThe reason given to KeepAwake shows where the system lists what keeps it
awake. On Linux, OnLockScreen is called when the screen saver starts,
which usually locks the screen, and IdleTime is 0 on desktops that do not
report it.
Global shortcuts
Global shortcuts work while the app is in the background, for example to bring it to the front:
err := mygo.GlobalShortcut.Register("CmdOrCtrl+Shift+Space", func() {
win.Show()
win.Focus()
})The function runs on the main thread. Shortcuts use the syntax of
accelerators; Unregister, UnregisterAll and
IsRegistered manage them. Register fails when the shortcut is taken,
by the app or, where the system tells, by another app.
On Linux under X11 the app grabs the keys itself. Under Wayland, where apps
cannot, the desktop binds shortcuts for the app through the XDG desktop
portal, which KDE Plasma 6 and GNOME 48 and later provide: the desktop may
ask the user to confirm new shortcuts and lets them pick other keys, and it
needs the app installed, since it identifies apps by their desktop entry.
The shortcut works shortly after Register returns. Windows the function
shows or focuses take the focus with the key press's activation token where
the desktop provides one, as GNOME does.