1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-04-16 10:42:06 -04:00

fix: gate startup tray scan on prior suspend history (#2225)

The unconditional startup scan introduced duplicate tray icons on normal boot because apps were still registering their own SNI items when the scan ran.

Use CLOCK_BOOTTIME − CLOCK_MONOTONIC to detect whether the system has ever been suspended. The startup scan now only runs when the difference exceeds 5 s, meaning at least one suspend/resume cycle has occurred.
On a fresh boot the difference is ≈ 0 and the scan is skipped entirely.
This commit is contained in:
Dimariqe
2026-04-15 19:52:06 +07:00
committed by GitHub
parent 0ab9b1e4e9
commit fe1fd92953

View File

@@ -8,6 +8,7 @@ import (
"github.com/AvengeMedia/DankMaterialShell/core/internal/log" "github.com/AvengeMedia/DankMaterialShell/core/internal/log"
"github.com/AvengeMedia/DankMaterialShell/core/internal/server/loginctl" "github.com/AvengeMedia/DankMaterialShell/core/internal/server/loginctl"
"github.com/godbus/dbus/v5" "github.com/godbus/dbus/v5"
"golang.org/x/sys/unix"
) )
const resumeDelay = 3 * time.Second const resumeDelay = 3 * time.Second
@@ -29,11 +30,14 @@ func NewManager() (*Manager, error) {
stopChan: make(chan struct{}), stopChan: make(chan struct{}),
} }
// Run a startup scan after a delay — covers the case where the process // Only run a startup scan when the system has been suspended at least once.
// was killed during suspend and restarted by systemd (Type=dbus). // On a fresh boot CLOCK_BOOTTIME ≈ CLOCK_MONOTONIC (difference ~0).
// The fresh process never sees the PrepareForSleep true→false transition, // After any suspend/resume cycle the difference grows by the time spent
// so the loginctl watcher alone is not enough. // sleeping. This avoids duplicate registrations on normal boot where apps
go m.scheduleRecovery() // are still starting up and will register their own tray icons shortly.
if timeSuspended() > 5*time.Second {
go m.scheduleRecovery()
}
return m, nil return m, nil
} }
@@ -91,3 +95,21 @@ func (m *Manager) Close() {
} }
log.Info("TrayRecovery manager closed") log.Info("TrayRecovery manager closed")
} }
// timeSuspended returns how long the system has spent in suspend since boot.
// It is the difference between CLOCK_BOOTTIME (includes suspend) and
// CLOCK_MONOTONIC (excludes suspend).
func timeSuspended() time.Duration {
var bt, mt unix.Timespec
if err := unix.ClockGettime(unix.CLOCK_BOOTTIME, &bt); err != nil {
return 0
}
if err := unix.ClockGettime(unix.CLOCK_MONOTONIC, &mt); err != nil {
return 0
}
diff := (bt.Sec-mt.Sec)*int64(time.Second) + (bt.Nsec - mt.Nsec)
if diff < 0 {
return 0
}
return time.Duration(diff)
}