5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-06 16:30:22 +08:00

linux bug fix

This commit is contained in:
popaprozac 2025-03-20 13:56:47 -07:00
parent 94f245f035
commit e55bf8dffc

View File

@ -91,59 +91,59 @@ func (ls *linuxNotifier) Startup(ctx context.Context) error {
var err error var err error
ls.initOnce.Do(func() { ls.initOnce.Do(func() {
err = ls.internal.init() err = ls.init()
}) })
return err return err
} }
func (n *internalNotifier) shutdown() { func (ls *linuxNotifier) shutdown() {
n.Lock() ls.internal.Lock()
defer n.Unlock() defer ls.internal.Unlock()
// Cancel the listener context if it's running // Cancel the listener context if it's running
if n.listenerCancel != nil { if ls.internal.listenerCancel != nil {
n.listenerCancel() ls.internal.listenerCancel()
n.listenerCancel = nil ls.internal.listenerCancel = nil
} }
// Close the connection // Close the connection
if n.dbusConn != nil { if ls.internal.dbusConn != nil {
n.dbusConn.Close() ls.internal.dbusConn.Close()
n.dbusConn = nil ls.internal.dbusConn = nil
} }
// Clear state // Clear state
n.activeNotifs = make(map[string]uint32) ls.internal.activeNotifs = make(map[string]uint32)
n.contexts = make(map[string]*notificationContext) ls.internal.contexts = make(map[string]*notificationContext)
n.method = "none" ls.internal.method = "none"
n.sendPath = "" ls.internal.sendPath = ""
} }
// Shutdown is called when the service is unloaded // Shutdown is called when the service is unloaded
func (ls *linuxNotifier) Shutdown() error { func (ls *linuxNotifier) Shutdown() error {
if ls.internal != nil { if ls.internal != nil {
ls.internal.shutdown() ls.shutdown()
} }
return ls.saveCategories() return ls.saveCategories()
} }
// Initialize the notifier and choose the best available notification method // Initialize the notifier and choose the best available notification method
func (n *internalNotifier) init() error { func (ls *linuxNotifier) init() error {
var err error var err error
// Cancel any existing listener before starting a new one // Cancel any existing listener before starting a new one
if n.listenerCancel != nil { if ls.internal.listenerCancel != nil {
n.listenerCancel() ls.internal.listenerCancel()
} }
// Create a new context for the listener // Create a new context for the listener
n.listenerCtx, n.listenerCancel = context.WithCancel(context.Background()) ls.internal.listenerCtx, ls.internal.listenerCancel = context.WithCancel(context.Background())
// Reset state // Reset state
n.activeNotifs = make(map[string]uint32) ls.internal.activeNotifs = make(map[string]uint32)
n.contexts = make(map[string]*notificationContext) ls.internal.contexts = make(map[string]*notificationContext)
n.listenerRunning = false ls.internal.listenerRunning = false
checkDbus := func() (*dbus.Conn, error) { checkDbus := func() (*dbus.Conn, error) {
conn, err := dbus.SessionBusPrivate() conn, err := dbus.SessionBusPrivate()
@ -184,52 +184,52 @@ func (n *internalNotifier) init() error {
} }
// Try dbus first // Try dbus first
n.dbusConn, err = checkDbus() ls.internal.dbusConn, err = checkDbus()
if err == nil { if err == nil {
n.method = MethodDbus ls.internal.method = MethodDbus
// Start the dbus signal listener with context // Start the dbus signal listener with context
go n.startDBusListener(n.listenerCtx) go ls.startDBusListener(ls.internal.listenerCtx)
n.listenerRunning = true ls.internal.listenerRunning = true
return nil return nil
} }
if n.dbusConn != nil { if ls.internal.dbusConn != nil {
n.dbusConn.Close() ls.internal.dbusConn.Close()
n.dbusConn = nil ls.internal.dbusConn = nil
} }
// Try notify-send // Try notify-send
send, err := exec.LookPath("notify-send") send, err := exec.LookPath("notify-send")
if err == nil { if err == nil {
n.sendPath = send ls.internal.sendPath = send
n.method = MethodNotifySend ls.internal.method = MethodNotifySend
return nil return nil
} }
// Try sw-notify-send // Try sw-notify-send
send, err = exec.LookPath("sw-notify-send") send, err = exec.LookPath("sw-notify-send")
if err == nil { if err == nil {
n.sendPath = send ls.internal.sendPath = send
n.method = MethodNotifySend ls.internal.method = MethodNotifySend
return nil return nil
} }
// No method available // No method available
n.method = "none" ls.internal.method = "none"
n.sendPath = "" ls.internal.sendPath = ""
return errors.New("no notification method is available") return errors.New("no notification method is available")
} }
// startDBusListener listens for DBus signals for notification actions and closures // startDBusListener listens for DBus signals for notification actions and closures
func (n *internalNotifier) startDBusListener(ctx context.Context) { func (ls *linuxNotifier) startDBusListener(ctx context.Context) {
signal := make(chan *dbus.Signal, notifyChannelBufferSize) signal := make(chan *dbus.Signal, notifyChannelBufferSize)
n.dbusConn.Signal(signal) ls.internal.dbusConn.Signal(signal)
defer func() { defer func() {
n.Lock() ls.internal.Lock()
n.listenerRunning = false ls.internal.listenerRunning = false
n.Unlock() ls.internal.Unlock()
n.dbusConn.RemoveSignal(signal) // Remove signal handler ls.internal.dbusConn.RemoveSignal(signal) // Remove signal handler
close(signal) // Clean up channel close(signal) // Clean up channel
}() }()
@ -253,34 +253,34 @@ func (n *internalNotifier) startDBusListener(ctx context.Context) {
case signalNotificationClosed: case signalNotificationClosed:
systemID := s.Body[0].(uint32) systemID := s.Body[0].(uint32)
reason := closedReason(s.Body[1].(uint32)).string() reason := closedReason(s.Body[1].(uint32)).string()
n.handleNotificationClosed(systemID, reason) ls.handleNotificationClosed(systemID, reason)
case signalActionInvoked: case signalActionInvoked:
systemID := s.Body[0].(uint32) systemID := s.Body[0].(uint32)
actionKey := s.Body[1].(string) actionKey := s.Body[1].(string)
n.handleActionInvoked(systemID, actionKey) ls.handleActionInvoked(systemID, actionKey)
} }
} }
} }
} }
// handleNotificationClosed processes notification closed signals // handleNotificationClosed processes notification closed signals
func (n *internalNotifier) handleNotificationClosed(systemID uint32, reason string) { func (ls *linuxNotifier) handleNotificationClosed(systemID uint32, reason string) {
// Find our notification ID for this system ID // Find our notification ID for this system ID
var notifID string var notifID string
var userData map[string]interface{} var userData map[string]interface{}
n.Lock() ls.internal.Lock()
for id, sysID := range n.activeNotifs { for id, sysID := range ls.internal.activeNotifs {
if sysID == systemID { if sysID == systemID {
notifID = id notifID = id
// Get the user data from context if available // Get the user data from context if available
if ctx, exists := n.contexts[id]; exists { if ctx, exists := ls.internal.contexts[id]; exists {
userData = ctx.UserData userData = ctx.UserData
} }
break break
} }
} }
n.Unlock() ls.internal.Unlock()
if notifID != "" { if notifID != "" {
response := NotificationResponse{ response := NotificationResponse{
@ -305,28 +305,28 @@ func (n *internalNotifier) handleNotificationClosed(systemID uint32, reason stri
} }
// Clean up the context // Clean up the context
n.Lock() ls.internal.Lock()
delete(n.contexts, notifID) delete(ls.internal.contexts, notifID)
delete(n.activeNotifs, notifID) delete(ls.internal.activeNotifs, notifID)
n.Unlock() ls.internal.Unlock()
} }
} }
// handleActionInvoked processes action invoked signals // handleActionInvoked processes action invoked signals
func (n *internalNotifier) handleActionInvoked(systemID uint32, actionKey string) { func (ls *linuxNotifier) handleActionInvoked(systemID uint32, actionKey string) {
// Find our notification ID and context for this system ID // Find our notification ID and context for this system ID
var notifID string var notifID string
var ctx *notificationContext var ctx *notificationContext
n.Lock() ls.internal.Lock()
for id, sysID := range n.activeNotifs { for id, sysID := range ls.internal.activeNotifs {
if sysID == systemID { if sysID == systemID {
notifID = id notifID = id
ctx = n.contexts[id] ctx = ls.internal.contexts[id]
break break
} }
} }
n.Unlock() ls.internal.Unlock()
if notifID != "" { if notifID != "" {
if actionKey == "default" { if actionKey == "default" {
@ -373,10 +373,10 @@ func (n *internalNotifier) handleActionInvoked(systemID uint32, actionKey string
} }
// Clean up the context // Clean up the context
n.Lock() ls.internal.Lock()
delete(n.contexts, notifID) delete(ls.internal.contexts, notifID)
delete(n.activeNotifs, notifID) delete(ls.internal.activeNotifs, notifID)
n.Unlock() ls.internal.Unlock()
} }
} }