mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-06 16:12:43 +08:00
linux bug fix
This commit is contained in:
parent
94f245f035
commit
e55bf8dffc
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user