From 6f18ad7f29d665ab1d3b8963f9a9ec230b93957c Mon Sep 17 00:00:00 2001 From: Anton Potekhin Date: Wed, 26 Apr 2023 17:24:02 +0300 Subject: [PATCH] Improved prevention from sleep for Win 11 --- server/cmd/preconfig_win.go | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/server/cmd/preconfig_win.go b/server/cmd/preconfig_win.go index d36c65a..2de0405 100644 --- a/server/cmd/preconfig_win.go +++ b/server/cmd/preconfig_win.go @@ -12,31 +12,44 @@ import ( ) const ( - EsSystemRequired = 0x00000001 - EsContinuous = 0x80000000 + EsSystemRequired = 0x00000001 + EsAwaymodeRequired = 0x00000040 // Added for future improvements + EsContinuous = 0x80000000 ) -var pulseTime = 1 * time.Minute +var pulseTime = 60 * time.Second func Preconfig(kill bool) { go func() { // don't sleep/hibernate windows kernel32 := syscall.NewLazyDLL("kernel32.dll") setThreadExecStateProc := kernel32.NewProc("SetThreadExecutionState") + currentExecState := uintptr(EsContinuous) + normalExecutionState := uintptr(EsContinuous) + systemRequireState := uintptr(EsSystemRequired | EsContinuous) pulse := time.NewTicker(pulseTime) for { select { case <-pulse.C: { - send := false + systemRequired := false for _, torrent := range torr.ListTorrent() { if torrent.Stat != state.TorrentInDB { - send = true + systemRequired = true break } } - if send { - setThreadExecStateProc.Call(uintptr(EsSystemRequired)) + if systemRequired && currentExecState != systemRequireState { + // Looks like sending just EsSystemRequired to clear timer is broken in Win11. + // Enable system required to avoid the system to idle to sleep. + currentExecState = systemRequireState + setThreadExecStateProc.Call(systemRequireState) + } + + if !systemRequired && currentExecState != normalExecutionState { + // Clear EXECUTION_STATE flags to disable away mode and allow the system to idle to sleep normally. + currentExecState = normalExecutionState + setThreadExecStateProc.Call(normalExecutionState) } } }