Skip to content

Instantly share code, notes, and snippets.

@dprado75
Last active December 4, 2022 21:33
Show Gist options
  • Save dprado75/eb317ebca12d5fea1663645039c0b6d9 to your computer and use it in GitHub Desktop.
Save dprado75/eb317ebca12d5fea1663645039c0b6d9 to your computer and use it in GitHub Desktop.
Fixes sleep problem for laptops using Windows 10 - the PC will hibernate whenever this script is running on battery power and you close the lid
/*
Daniel DP - https://gist.github.com/dprado75/eb317ebca12d5fea1663645039c0b6d9
Code created based in the following links:
Lid Library By Linear Spoon - https://www.autohotkey.com/board/topic/92888-lidwatcher-monitor-the-state-of-your-laptop-lid/
Battery status by AntonyB - https://www.autohotkey.com/board/topic/7022-acbattery-status/
*/
Start_LidWatcher()
{
VarSetCapacity(guid, 16)
;GUID_LIDSWITCH_STATE_CHANGE
Numput(0xBA3E0F4D, guid, 0, "uint"), Numput(0x4094B817, guid, 4, "uint")
Numput(0x63D5D1A2, guid, 8, "uint"), Numput(0xF3A0E679, guid, 12, "uint")
r := DllCall("RegisterPowerSettingNotification", "ptr", A_ScriptHwnd, "ptr", &guid, "uint", 0)
if (!r || ErrorLevel)
{
;MSDN says check GetLastError if the return value was NULL.
Msgbox % "RegisterPowerSettingNotification failed with error: " (ErrorLevel ? ErrorLevel : A_LastError)
return 0
}
OnMessage(0x218, "WM_POWERBROADCAST")
return r
}
Stop_LidWatcher(r)
{
DllCall("UnregisterPowerSettingNotification", "ptr", r)
OnMessage(0x218, "")
}
WM_POWERBROADCAST(wparam, lparam)
{
static fx := "LidStateChange"
if (wparam = 0x8013)
{
;data = 0 = closed
;data = 1 = opened
if isFunc(fx)
%fx%(Numget(lparam+20, 0, "uchar") ? "opened" : "closed")
}
return 1
}
r := Start_LidWatcher() ;Start waiting for the lid to be opened or closed
OnExit, cleanup
return
cleanup:
Stop_LidWatcher(r) ;Stop watching the lid state changes
ExitApp
return
/*
power change monitor
*/
PowerDetectAction()
{
VarSetCapacity(powerstatus, 1+1+1+1+4+4)
success := DllCall("kernel32.dll\GetSystemPowerStatus", "uint", &powerstatus)
acLineStatus:=ReadInteger(&powerstatus,0,1,false)
if (acLineStatus = 0)
{
DllCall("PowrProf\SetSuspendState", "Int", 0, "Int", 0, "Int", 0)
}
;uncomment for visual status
;output=AC Status: %acLineStatus%`n
;MsgBox, %output%
}
/*
converts byte position to integer
*/
ReadInteger( p_address, p_offset, p_size, p_hex=true )
{
value = 0
old_FormatInteger := a_FormatInteger
if ( p_hex )
SetFormat, integer, hex
else
SetFormat, integer, dec
loop, %p_size%
value := value+( *( ( p_address+p_offset )+( a_Index-1 ) ) << ( 8* ( a_Index-1 ) ) )
SetFormat, integer, %old_FormatInteger%
return, value
}
/*
This function will be called whenever the lid changes states.
*/
LidStateChange(newstate)
{
if (newstate = "closed")
{
PowerDetectAction()
}
;uncomment this block if you want to save the lid log into file
;FormatTime, TimeString,, h:mm:ss tt
;FileAppend, The lid was %newstate% at %TimeString%`n, lid_hibernate.log
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment