Skip to content

Keep fans when closed on AC power - #12

Open
nsd97 wants to merge 1 commit into
idevtim:mainfrom
nsd97:contrib/keep-fans-closed-on-power
Open

Keep fans when closed on AC power#12
nsd97 wants to merge 1 commit into
idevtim:mainfrom
nsd97:contrib/keep-fans-closed-on-power

Conversation

@nsd97

@nsd97 nsd97 commented Jul 19, 2026

Copy link
Copy Markdown

What does this PR do?

Adds Keep Fans When Closed on Power (default off): on AC, leave fans under app control through display sleep / lock / willSleep so lid-close clamshell does not force fans back to auto.

Closes #11.

Context

  • Issue: Proposal: Keep fans when closed on AC power #11
  • Stack: standalone (no dependency on other open PRs)
  • Out of scope: keeping the Mac awake (pmset / private clamshell SPI), battery lid-close beyond existing Keep Fans on Screen Sleep, Ultra / helper changes

What changed

  • DisplaySleepFanPolicykeepClosedOnPower && onAC → keep; else fall back to keepOnScreenSleep
  • PowerSource.isOnAC via IOPS
  • FanMonitor uses the same policy for screen sleep, screen lock, and willSleep (lid close often posts willSleep after screensDidSleep; resetting there was undoing keep)
  • Settings → Fan Control → Keep Fans When Closed on Power
  • Diagnostics export includes the new setting

Review guide

Start at: ChillMac/Fan/DisplaySleepFanPolicy.swiftChillMac/Fan/FanMonitor.swift (handleSleep / handleScreenSleep / handleScreenLocked) → ChillMac/Views/SettingsView.swift (Fan Control row)

How to test

  1. xcodegen generate && xcodebuild -project ChillMac.xcodeproj -scheme ChillMac build
  2. Plug in AC → enable Performance Mode → Settings → Fan Control → turn Keep Fans When Closed on Power on
  3. Close lid in clamshell (external display / awake) → fans should stay under app control (not snap to auto)
  4. On battery with the new toggle on (and Keep Fans on Screen Sleep off) → lid close should still reset
  5. Both keep toggles off → sleep / lid close still resets (unchanged)

Checklist

  • Builds without errors (xcodegen generate && xcodebuild -scheme ChillMac build)
  • Unit tests pass — N/A on current main (no test target yet; policy is pure and covered on the fork harness)
  • Tested manually in the app

Made with Cursor

Honor Keep Fans When Closed on Power for willSleep so lid close does not force fans back to auto after a keep decision.

Co-authored-by: Cursor <cursoragent@cursor.com>
@idevtim

idevtim commented Jul 31, 2026

Copy link
Copy Markdown
Owner

Thanks for the write-up and the PR. The policy function is clean, the IOPS memory management is right, defaulting off is the correct call, and it merges onto current main and builds (verified with xcodegen generate && xcodebuild).

I want the screen-sleep/lock half of this. I need the willSleep change dropped before I can merge.

The blocker: handleSleep

willSleepNotification fires before genuine system sleep. In clamshell on AC with an external display the Mac stays awake, so it never posts, which means the change does nothing for the case it targets. When it does post, the Mac really is sleeping, and the early return then means:

  • Fans stay forced across every real sleep on AC: Apple menu > Sleep, idle sleep, scheduled sleep.
  • On Apple Silicon Ftst stays engaged, so thermalmonitord stays bypassed through sleep and wake. Only HelperService.cleanupOnExit() clears it today.
  • systemAsleep is never set, so the guard !systemAsleep in applyPerformanceCurve (FanMonitor.swift:594) stops blocking SMC writes during the sleep transition.

Resetting to auto before real sleep is a safety property I want unconditional. The issue notes that Apple menu > Sleep still resets with the toggle off, but with it on it no longer does, and neither the issue nor the settings copy says so.

You don't need it anyway: clamshell-while-awake is already covered by the screensDidSleep and screenIsLocked paths, which is the part I want.

Three smaller items

  1. PowerSource.swift is a third copy of the same AC read. See BatteryInfo.swift:41 and FanMonitor.swift:228-234. Please extract one of those instead.
  2. PowerSource.providingType as a mutable static var test seam doesn't buy anything here. No test target in this repo (see CLAUDE.md), and it's a non-concurrency-safe global.
  3. Settings subtitle: "On AC only, for clamshell while awake" is accurate once willSleep is out, but not as the PR stands.

DisplaySleepFanPolicy then collapses to one function, small enough to live in FanMonitor.swift. Your call whether to keep the file.

That leaves the AppSettings flag, two call-site edits, the settings row, and the diagnostics field. Happy to merge that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Proposal: Keep fans when closed on AC power

2 participants