-- WakeRanger's closed-display helper. -- -- WHAT THIS IS FOR -- Keeping a Mac awake with the lid shut needs one system setting, -- `pmset -a disablesleep`, and that setting needs root. A Mac App Store app -- runs in a sandbox and cannot run it. Apple's sanctioned way out is this -- folder: a script you put in ~/Library/Application Scripts/app.wakeranger/ -- yourself runs outside the sandbox, and WakeRanger may ask it to do things. -- WakeRanger cannot put this file here - only you can. That is the point. -- -- WHAT IT DOES -- Two commands, and nothing else: -- /usr/bin/pmset -a disablesleep 1 -- /usr/bin/pmset -a disablesleep 0 -- It reads nothing, sends nothing anywhere, and touches no other setting. -- -- WakeRanger turns the setting off again when the session ends, when the Mac -- gets too hot, when the battery runs low, when you quit, and at the next -- launch if it crashed while it was on. It never touches the setting if it -- was not the one to turn it on. property kVersion : "2" property kRuleFile : "/etc/sudoers.d/wakeranger_clamshell" on runAction(theAction) if theAction is "version" then return kVersion else if theAction is "enable" then return setDisableSleep("1") else if theAction is "disable" then return setDisableSleep("0") else if theAction is "silent-status" then return silentStatus() else if theAction is "install-silent" then return installSilentRule() else if theAction is "remove-silent" then return removeSilentRule() else if theAction is "display-sleep" then return sleepDisplaysNow() end if return "unknown" end runAction -- Turn the screen off now, without asking for anything. -- -- `pmset displaysleepnow` is an action rather than a setting, and pmset's own -- manual says only settings need root - so this never authenticates. If it -- turns out to need privileges on some Mac, it simply does not happen: a lit -- screen is worth a log line, never a password prompt. -- -- WakeRanger asks for this when the lid shuts on a session that is keeping the -- Mac awake and there is no external display, because the alternative is a -- backlight running at full brightness inside a closed lid. The incumbent -- shipped that behaviour in 5.3, withdrew it in 5.3.1 after it broke the -- "allow display sleep" setting, and its tracker has collected requests for it -- ever since: "It totally messes up battery life (and display longevity)". on sleepDisplaysNow() try do shell script "/usr/bin/pmset displaysleepnow" return "ok" on error return "failed" end try end sleepDisplaysNow -- The one setting, by the shortest route that works. on setDisableSleep(theValue) set theCommand to "/usr/bin/pmset -a disablesleep " & theValue -- Silent, if you asked for that. `-n` never prompts: it fails instead, -- which is what makes this a try and not a hang on an unattended Mac. try do shell script "/usr/bin/sudo -n " & theCommand return "ok" end try try do shell script theCommand with administrator privileges return "ok" on error number errNum if errNum is -128 then return "cancelled" return "failed" end try end setDisableSleep -- Whether the passwordless rule is in place. -- -- Asked with `sudo -n -l`, which lists the permission rather than using it. -- Reading /etc/sudoers.d directly is not possible: it is 0750 root:wheel, so -- checking for the file would report "absent" for every non-root caller. on silentStatus() try do shell script "/usr/bin/sudo -n -l /usr/bin/pmset -a disablesleep 1" return "installed" end try return "absent" end silentStatus on installSilentRule() set theUser to do shell script "/usr/bin/id -un" -- Named user, not %admin. Amphetamine's equivalent grants the rule to the -- admin group, which leaves every standard account unable to use the -- feature - reported against it and unfixed for two years. set theRule to "Cmnd_Alias WAKERANGER_CLAMSHELL = /usr/bin/pmset -a disablesleep 1, /usr/bin/pmset -a disablesleep 0" & linefeed & theUser & " ALL=(ALL) NOPASSWD: WAKERANGER_CLAMSHELL" & linefeed set theTemp to (do shell script "/usr/bin/mktemp /tmp/wakeranger_clamshell.XXXXXX") do shell script "/usr/bin/printf '%s' " & quoted form of theRule & " > " & quoted form of theTemp -- Validate BEFORE installing, never after. A malformed file in -- /etc/sudoers.d breaks `sudo` for the whole machine, and the person it -- breaks it for is the one who would have to use sudo to repair it. try do shell script "/usr/sbin/visudo -cqf " & quoted form of theTemp on error do shell script "/bin/rm -f " & quoted form of theTemp return "invalid" end try try -- 0440 root:wheel, which is what sudo requires. Amphetamine's ships -- 0644 and `visudo -c` reports it as bad permissions. do shell script "/usr/bin/install -o root -g wheel -m 0440 " & quoted form of theTemp & " " & kRuleFile with administrator privileges do shell script "/bin/rm -f " & quoted form of theTemp return "ok" on error number errNum do shell script "/bin/rm -f " & quoted form of theTemp if errNum is -128 then return "cancelled" return "failed" end try end installSilentRule on removeSilentRule() try do shell script "/bin/rm -f " & kRuleFile with administrator privileges return "ok" on error number errNum if errNum is -128 then return "cancelled" return "failed" end try end removeSilentRule