-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Description
Description
Current issues:
macOS | Windows | Linux |
---|---|---|
No issues |
|
|
Thoughts on the shared Windows and Linux issue about ServiceStartup
timing would be appreciated. I'll look at other services but what is a pattern we like here. Otherwise we need to document the timing issue. It is unlikely to send a notification in main
before calling app.Run()
.
In the effort to add this to v2, we could add a similar InitializeNotifications
to v3 or detail in documentation the need to use the notification service in an ApplicationStarted
event.
Calling ServiceStartup
on the service from main
resolves the issue.
macOS: no need for any coordination/functionality bootstrapped in `ServiceStartup`.
notifications_darwin.go
func (dn *darwinNotifier) Startup(ctx context.Context, options application.ServiceOptions) error {
if !isNotificationAvailable() {
return fmt.Errorf("notifications are not available on this system")
}
if !checkBundleIdentifier() {
return fmt.Errorf("notifications require a valid bundle identifier")
}
if !bool(C.ensureDelegateInitialized()) {
return fmt.Errorf("failed to initialize notification center delegate")
}
return nil
}
Windows: grabs the app icon for use in the toast, ensures Registry entries are populated, and the toast callback handler is hooked up.
notifications_window.go
func (wn *windowsNotifier) Startup(ctx context.Context, options application.ServiceOptions) error {
wn.categoriesLock.Lock()
defer wn.categoriesLock.Unlock()
app := application.Get()
cfg := app.Config()
wn.appName = cfg.Name
guid, err := wn.getGUID()
if err != nil {
return err
}
wn.appGUID = guid
wn.iconPath = filepath.Join(os.TempDir(), wn.appName+wn.appGUID+".png")
exe, err := os.Executable()
if err != nil {
return fmt.Errorf("failed to get executable path: %w", err)
}
wn.exePath = exe
// Create the registry key for the toast activator
key, _, err := registry.CreateKey(registry.CURRENT_USER,
`Software\Classes\CLSID\`+wn.appGUID+`\LocalServer32`, registry.ALL_ACCESS)
if err != nil {
return fmt.Errorf("failed to create CLSID key: %w", err)
}
if err := key.SetStringValue("", fmt.Sprintf("\"%s\" %%1", wn.exePath)); err != nil {
return fmt.Errorf("failed to set CLSID server path: %w", err)
}
key.Close()
toast.SetAppData(toast.AppData{
AppID: wn.appName,
GUID: guid,
IconPath: wn.iconPath,
ActivationExe: wn.exePath,
})
toast.SetActivationCallback(func(args string, data []toast.UserData) {
result := NotificationResult{}
actionIdentifier, options, err := parseNotificationResponse(args)
if err != nil {
result.Error = err
} else {
// Subtitle is retained but was not shown with the notification
response := NotificationResponse{
ID: options.ID,
ActionIdentifier: actionIdentifier,
Title: options.Title,
Subtitle: options.Subtitle,
Body: options.Body,
CategoryID: options.CategoryID,
UserInfo: options.Data,
}
if userText, found := wn.getUserText(data); found {
response.UserText = userText
}
result.Response = response
}
if ns := getNotificationService(); ns != nil {
ns.handleNotificationResult(result)
}
})
// Register the class factory for the toast activator
if err := registerFactoryInternal(wintoast.ClassFactory); err != nil {
return fmt.Errorf("CoRegisterClassObject failed: %w", err)
}
return wn.loadCategoriesFromRegistry()
}
Linux: creates the dbus connection and sets up the dbus signal handlers.
notifications_linux.go
func (ln *linuxNotifier) Startup(ctx context.Context, options application.ServiceOptions) error {
ln.appName = application.Get().Config().Name
conn, err := dbus.ConnectSessionBus()
if err != nil {
return fmt.Errorf("failed to connect to session bus: %w", err)
}
ln.conn = conn
if err := ln.loadCategories(); err != nil {
fmt.Printf("Failed to load notification categories: %v\n", err)
}
var signalCtx context.Context
signalCtx, ln.cancel = context.WithCancel(context.Background())
if err := ln.setupSignalHandling(signalCtx); err != nil {
return fmt.Errorf("failed to set up notification signal handling: %w", err)
}
return nil
}
To Reproduce
On Windows or Linux, in main
:
- Create a notification service
- Call
SendNotification
Windows | Linux |
---|---|
Error saving icon: open : The system cannot find the file specified. |
panic: runtime error: invalid memory address or nil pointer dereference |
On Windows, from Go or JS:
- Call
SendNotification
orSendNotificationWithActions
withoutData
defined
Warning: Failed to decode notification response: failed to decode base64 payload: illegal base64 data at input byte 7
Expected behaviour
Expect the notification service to be usable right after being created.
On Windows, we should be able to send notifications without included arbitrary user data.
Screenshots
No response
Attempted Fixes
No response
System Details
Wails (v3.0.0-dev) Wails Doctor
# System
┌──────────────────────────────────────────────────┐
| Name | MacOS |
| Version | 26.0 |
| ID | 25A5316i |
| Branding | MacOS 26.0 |
| Platform | darwin |
| Architecture | arm64 |
| Apple Silicon | true |
| CPU | Apple M4 Max |
| CPU 1 | Apple M4 Max |
| CPU 2 | Apple M4 Max |
| GPU | 32 cores, Metal Support: Metal 4 |
| Memory | 36 GB |
└──────────────────────────────────────────────────┘
# Build Environment
┌─────────────────────────────────────────────────────────┐
| Wails CLI | v3.0.0-dev |
| Go Version | go1.24.1 |
| Revision | 67058c092378d46b678e5758fa476742ea5ba9aa |
| Modified | true |
| -buildmode | exe |
| -compiler | gc |
| CGO_CFLAGS | |
| CGO_CPPFLAGS | |
| CGO_CXXFLAGS | |
| CGO_ENABLED | 1 |
| CGO_LDFLAGS | |
| GOARCH | arm64 |
| GOARM64 | v8.0 |
| GOOS | darwin |
| vcs | git |
| vcs.modified | true |
| vcs.revision | 67058c092378d46b678e5758fa476742ea5ba9aa |
| vcs.time | 2025-07-25T12:03:26Z |
└─────────────────────────────────────────────────────────┘
# Dependencies
┌────────────────────────────────────────────────────────────────────────┐
| Xcode cli tools | 2410 |
| npm | 10.9.2 |
| *NSIS | Not Installed. Install with `brew install makensis`. |
| |
└─────────────────────── * - Optional Dependency ────────────────────────┘
# Checking for issues
SUCCESS No issues found
# Diagnosis
SUCCESS Your system is ready for Wails development!
Additional context
No response