Skip to content

fix(helper): hand fans to macOS auto on system sleep (#2) - #3

Merged
fexxdev merged 3 commits into
mainfrom
fix/quiet-fans-on-sleep
Jun 10, 2026
Merged

fix(helper): hand fans to macOS auto on system sleep (#2)#3
fexxdev merged 3 commits into
mainfrom
fix/quiet-fans-on-sleep

Conversation

@fexxdev

@fexxdev fexxdev commented Jun 10, 2026

Copy link
Copy Markdown
Owner

What

On system sleep the root helper registers for IOKit system-power notifications and, on kIOMessageSystemWillSleep, hands fan control back to macOS auto mode (setForcedMode(forced: false)). The SMC firmware then idles the fans during sleep instead of holding the last forced RPM. On wake the app re-applies its curve (already handled).

Changes are confined to SMCHelperMode.swift plus a test-only mock extension. Design spec: docs/superpowers/specs/2026-06-08-quiet-fans-on-sleep-design.md.

Tests

4 unit tests cover the routing (handlePowerMessage) and restoreAutoMode against the real IOKit ABI message numbers.

Closes #2.

🤖 Generated with Claude Code

Federico Benedetti and others added 3 commits June 8, 2026 22:26
When the Mac sleeps, the SMC keeps honoring Mystral's last forced fan
mode + RPM (the app's poll loop is suspended), so the fan keeps spinning
and whines. The root helper now registers for IOKit system-power
notifications and, on kIOMessageSystemWillSleep, releases forced mode so
the firmware idles the fans; it always acks via IOAllowPowerChange to
avoid the ~30s sleep stall. Wake re-applies the curve via the app's
existing handleWake.

Routing is factored into a unit-tested handlePowerMessage(); the C
callback is a thin shell. SIGTERM reuses the shared restoreAutoMode().

Closes #2
Copilot AI review requested due to automatic review settings June 10, 2026 12:58

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the root helper to listen for IOKit system-power sleep notifications and, on kIOMessageSystemWillSleep, release forced fan control back to macOS auto mode so the SMC firmware can idle fans during sleep (issue #2). It also adds unit tests validating the message routing and auto-restore behavior using the real IOKit ABI message values, plus supporting documentation and a version bump.

Changes:

  • Register the helper for IOKit sleep notifications and restore auto fan mode pre-sleep (with an ack requirement handled in the callback).
  • Add unit tests for restoreAutoMode and handlePowerMessage, including mock tracking for setForcedMode.
  • Add an approved design spec and bump the app version/build number.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
Mystral/Services/SMCHelperMode.swift Adds IOKit power-notification registration, routes sleep messages to auto-restore, and a C callback to ack sleep transitions.
MystralTests/SMCServiceTests.swift Extends the mock to record forced-mode calls and adds 4 unit tests covering sleep routing/restore behavior.
Mystral/Info.plist Bumps CFBundleShortVersionString and CFBundleVersion.
docs/superpowers/specs/2026-06-08-quiet-fans-on-sleep-design.md Adds the design spec for quiet fans on sleep.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +290 to +297
private func mystralSleepWakeCallback(_ refcon: UnsafeMutableRawPointer?,
_ service: io_service_t,
_ messageType: UInt32,
_ messageArgument: UnsafeMutableRawPointer?) {
if SMCHelperMode.handlePowerMessage(messageType, smc: SMCHelperMode.powerSMC) {
IOAllowPowerChange(SMCHelperMode.rootPowerPort, Int(bitPattern: messageArgument))
}
}
Comment on lines +149 to +151
static func restoreAutoMode(smc: SMCServiceProtocol) {
let count = (try? smc.getAllFans().count) ?? 2
try? smc.setForcedMode(fanCount: count, forced: false)
@fexxdev
fexxdev merged commit 1277cef into main Jun 10, 2026
2 checks passed
@fexxdev
fexxdev deleted the fix/quiet-fans-on-sleep branch June 10, 2026 13:02
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.

There's no need for the fan to spin when it's hibernating

2 participants