1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-10 07:25:37 -05:00
Files
DankMaterialShell/backend/internal/server/loginctl/monitor.go
2025-11-12 17:18:45 -05:00

158 lines
3.3 KiB
Go

package loginctl
import (
"time"
"github.com/godbus/dbus/v5"
)
func (m *Manager) handleDBusSignal(sig *dbus.Signal) {
switch sig.Name {
case dbusSessionInterface + ".Lock":
m.stateMutex.Lock()
m.state.Locked = true
m.state.LockedHint = true
m.stateMutex.Unlock()
m.notifySubscribers()
if m.sleepInhibitorEnabled.Load() && m.inSleepCycle.Load() {
id := m.sleepCycleID.Load()
m.lockTimerMu.Lock()
if m.lockTimer != nil {
m.lockTimer.Stop()
}
m.lockTimer = time.AfterFunc(m.fallbackDelay, func() {
m.releaseForCycle(id)
})
m.lockTimerMu.Unlock()
}
case dbusSessionInterface + ".Unlock":
m.stateMutex.Lock()
m.state.Locked = false
m.state.LockedHint = false
m.stateMutex.Unlock()
m.notifySubscribers()
// Cancel the lock timer if it's still running
m.lockTimerMu.Lock()
if m.lockTimer != nil {
m.lockTimer.Stop()
m.lockTimer = nil
}
m.lockTimerMu.Unlock()
// Re-acquire the sleep inhibitor (acquireSleepInhibitor checks the enabled flag)
m.acquireSleepInhibitor()
case dbusManagerInterface + ".PrepareForSleep":
if len(sig.Body) == 0 {
return
}
preparing, _ := sig.Body[0].(bool)
if preparing {
cycleID := m.sleepCycleID.Add(1)
m.inSleepCycle.Store(true)
if m.lockBeforeSuspend.Load() {
m.Lock()
}
readyCh := m.newLockerReadyCh()
go func(id uint64, ch <-chan struct{}) {
<-ch
if m.inSleepCycle.Load() && m.sleepCycleID.Load() == id {
m.releaseSleepInhibitor()
}
}(cycleID, readyCh)
} else {
m.inSleepCycle.Store(false)
m.signalLockerReady()
m.refreshSessionBinding()
m.acquireSleepInhibitor()
}
m.stateMutex.Lock()
m.state.PreparingForSleep = preparing
m.stateMutex.Unlock()
m.notifySubscribers()
case dbusPropsInterface + ".PropertiesChanged":
m.handlePropertiesChanged(sig)
case "org.freedesktop.DBus.NameOwnerChanged":
if len(sig.Body) == 3 {
name, _ := sig.Body[0].(string)
oldOwner, _ := sig.Body[1].(string)
newOwner, _ := sig.Body[2].(string)
if name == dbusDest && oldOwner != "" && newOwner != "" {
m.updateSessionState()
if !m.inSleepCycle.Load() {
m.acquireSleepInhibitor()
}
m.notifySubscribers()
}
}
}
}
func (m *Manager) handlePropertiesChanged(sig *dbus.Signal) {
if len(sig.Body) < 2 {
return
}
iface, ok := sig.Body[0].(string)
if !ok || iface != dbusSessionInterface {
return
}
changes, ok := sig.Body[1].(map[string]dbus.Variant)
if !ok {
return
}
var needsUpdate bool
for key, variant := range changes {
switch key {
case "Active":
if val, ok := variant.Value().(bool); ok {
m.stateMutex.Lock()
m.state.Active = val
m.stateMutex.Unlock()
needsUpdate = true
}
case "IdleHint":
if val, ok := variant.Value().(bool); ok {
m.stateMutex.Lock()
m.state.IdleHint = val
m.stateMutex.Unlock()
needsUpdate = true
}
case "IdleSinceHint":
if val, ok := variant.Value().(uint64); ok {
m.stateMutex.Lock()
m.state.IdleSinceHint = val
m.stateMutex.Unlock()
needsUpdate = true
}
case "LockedHint":
if val, ok := variant.Value().(bool); ok {
m.stateMutex.Lock()
m.state.LockedHint = val
m.state.Locked = val
m.stateMutex.Unlock()
needsUpdate = true
}
}
}
if needsUpdate {
m.notifySubscribers()
}
}