move chan creation on macos and handle linux shutdown

This commit is contained in:
popaprozac 2025-03-22 23:07:44 -07:00
commit 5ddb27fd3f
2 changed files with 45 additions and 29 deletions

View file

@ -112,8 +112,6 @@ func (dn *darwinNotifier) SendNotification(options NotificationOptions) error {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
id, resultCh := dn.registerChannel()
cIdentifier := C.CString(options.ID)
cTitle := C.CString(options.Title)
cSubtitle := C.CString(options.Subtitle)
@ -133,6 +131,7 @@ func (dn *darwinNotifier) SendNotification(options NotificationOptions) error {
defer C.free(unsafe.Pointer(cDataJSON))
}
id, resultCh := dn.registerChannel()
C.sendNotification(C.int(id), cIdentifier, cTitle, cSubtitle, cBody, cDataJSON)
select {
@ -157,8 +156,6 @@ func (dn *darwinNotifier) SendNotificationWithActions(options NotificationOption
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
id, resultCh := dn.registerChannel()
cIdentifier := C.CString(options.ID)
cTitle := C.CString(options.Title)
cSubtitle := C.CString(options.Subtitle)
@ -180,7 +177,9 @@ func (dn *darwinNotifier) SendNotificationWithActions(options NotificationOption
defer C.free(unsafe.Pointer(cDataJSON))
}
id, resultCh := dn.registerChannel()
C.sendNotificationWithActions(C.int(id), cIdentifier, cTitle, cSubtitle, cBody, cCategoryID, cDataJSON)
select {
case result := <-resultCh:
if !result.Success {
@ -202,8 +201,6 @@ func (dn *darwinNotifier) RegisterNotificationCategory(category NotificationCate
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
id, resultCh := dn.registerChannel()
cCategoryID := C.CString(category.ID)
defer C.free(unsafe.Pointer(cCategoryID))
@ -222,6 +219,7 @@ func (dn *darwinNotifier) RegisterNotificationCategory(category NotificationCate
defer C.free(unsafe.Pointer(cReplyButtonTitle))
}
id, resultCh := dn.registerChannel()
C.registerNotificationCategory(C.int(id), cCategoryID, cActionsJSON, C.bool(category.HasReplyField),
cReplyPlaceholder, cReplyButtonTitle)
@ -245,11 +243,10 @@ func (dn *darwinNotifier) RemoveNotificationCategory(categoryId string) error {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
id, resultCh := dn.registerChannel()
cCategoryID := C.CString(categoryId)
defer C.free(unsafe.Pointer(cCategoryID))
id, resultCh := dn.registerChannel()
C.removeNotificationCategory(C.int(id), cCategoryID)
select {

View file

@ -22,6 +22,7 @@ type linuxNotifier struct {
notificationMeta map[uint32]map[string]interface{}
activeNotifsLock sync.RWMutex
appName string
cancel context.CancelFunc
}
const (
@ -63,7 +64,11 @@ func (ln *linuxNotifier) Startup(ctx context.Context, options application.Servic
fmt.Printf("Failed to load notification categories: %v\n", err)
}
if err := ln.setupSignalHandling(); err != nil {
var signalCtx context.Context
signalCtx, ln.cancel = context.WithCancel(context.Background())
// Set up signal handling for notification actions
if err := ln.setupSignalHandling(signalCtx); err != nil {
return fmt.Errorf("failed to set up notification signal handling: %w", err)
}
@ -72,15 +77,13 @@ func (ln *linuxNotifier) Startup(ctx context.Context, options application.Servic
// Shutdown will save categories and close the D-Bus connection when the service unloads
func (ln *linuxNotifier) Shutdown() error {
ln.cancel()
if err := ln.saveCategories(); err != nil {
fmt.Printf("Failed to save notification categories: %v\n", err)
}
if ln.conn != nil {
return ln.conn.Close()
}
return nil
return ln.conn.Close()
}
// RequestNotificationAuthorization is a Linux stub that always returns true, nil.
@ -126,7 +129,7 @@ func (ln *linuxNotifier) SendNotification(options NotificationOptions) error {
hints["x-wails-metadata"] = dbus.MakeVariant(string(metadataJSON))
actions := []string{}
timeout := int32(0) // Timeout in milliseconds (5 seconds)
timeout := int32(0)
// Call the Notify method on the D-Bus interface
obj := ln.conn.Object(dbusNotificationInterface, dbusNotificationPath)
@ -153,15 +156,18 @@ func (ln *linuxNotifier) SendNotification(options NotificationOptions) error {
}
ln.activeNotifsLock.Lock()
ln.activeNotifs[notifID] = options.ID
ln.notificationMeta[notifID] = map[string]interface{}{
metadata := map[string]interface{}{
"id": options.ID,
"title": options.Title,
"subtitle": options.Subtitle,
"body": options.Body,
"data": options.Data,
}
ln.notificationMeta[notifID] = metadata
ln.activeNotifsLock.Unlock()
return nil
@ -267,7 +273,9 @@ func (ln *linuxNotifier) RegisterNotificationCategory(category NotificationCateg
ln.categories[category.ID] = category
go ln.saveCategories()
if err := ln.saveCategories(); err != nil {
fmt.Printf("Failed to save notification categories: %v\n", err)
}
return nil
}
@ -279,7 +287,9 @@ func (ln *linuxNotifier) RemoveNotificationCategory(categoryId string) error {
delete(ln.categories, categoryId)
go ln.saveCategories()
if err := ln.saveCategories(); err != nil {
fmt.Printf("Failed to save notification categories: %v\n", err)
}
return nil
}
@ -425,7 +435,7 @@ func (ln *linuxNotifier) loadCategories() error {
}
// Setup signal handling for notification actions.
func (ln *linuxNotifier) setupSignalHandling() error {
func (ln *linuxNotifier) setupSignalHandling(ctx context.Context) error {
if err := ln.conn.AddMatchSignal(
dbus.WithMatchInterface(dbusNotificationInterface),
dbus.WithMatchMember("ActionInvoked"),
@ -440,22 +450,31 @@ func (ln *linuxNotifier) setupSignalHandling() error {
return err
}
go ln.handleSignals()
c := make(chan *dbus.Signal, 10)
ln.conn.Signal(c)
go ln.handleSignals(ctx, c)
return nil
}
// Handle incoming D-Bus signals.
func (ln *linuxNotifier) handleSignals() {
c := make(chan *dbus.Signal, 10)
ln.conn.Signal(c)
func (ln *linuxNotifier) handleSignals(ctx context.Context, c chan *dbus.Signal) {
for {
select {
case <-ctx.Done():
return
case signal, ok := <-c:
if !ok {
return
}
for signal := range c {
switch signal.Name {
case dbusNotificationInterface + ".ActionInvoked":
ln.handleActionInvoked(signal)
case dbusNotificationInterface + ".NotificationClosed":
ln.handleNotificationClosed(signal)
switch signal.Name {
case dbusNotificationInterface + ".ActionInvoked":
ln.handleActionInvoked(signal)
case dbusNotificationInterface + ".NotificationClosed":
ln.handleNotificationClosed(signal)
}
}
}
}