BluetoothAudioManager
- Replace Timer.scheduledTimer polling with DispatchSourceTimer on a
utility queue so main-thread back-pressure no longer stalls the 3s
connect-detection cadence.
- Distinguish "host controller unavailable" from "powered off" via a
new bluetoothIsPoweredOn() helper, so transient IOBluetooth registry
blips at launch no longer clear connectedDevices.
- Re-read device metadata (name, type, battery) at +500ms and +2s after
IOBluetoothDeviceConnectedNotification to catch IORegistry's
late-population window; the existing HUD wait-task then updates the
shown battery in place.
- Declare BluetoothAudioDeviceType: Equatable to support the
change-detection diff in the re-read pass.
LockSoundPlayer
- Add a 1.2s cross-type cooldown so a rapid lid close->open no longer
plays lock-then-unlock chimes as a doubled sound (the per-type
throttle never covered this case).
- Bump per-type throttle 0.25s -> 0.6s.
- Reset throttle state when enableLockSounds is toggled back on, so the
first chime after re-enable is never suppressed by a stale timestamp.
StatsManager
- Shorten notchCloseStopDelay 3.0s -> 1.0s so the monitoring timer is
invalidated sooner after the user closes the notch, freeing the
main-thread tick budget for animation work.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The brightness HUD broke on Tahoe because Apple deprecated/changed the
DisplayServices private framework and stopped posting the BezelEngine
distributed notifications that Atoll relied on for change detection.
This commit:
- Adds CoreBrightnessDisplayClient using Apple's CoreBrightness framework
(mirrors the existing KeyboardBrightnessClient pattern) as the primary
brightness read/write path
- Falls back gracefully to DisplayServices then IODisplay if CoreBrightness
is unavailable
- Adds a lightweight polling fallback (150ms) so the HUD fires even when
no distributed notifications are posted (Control Center, Touch Bar, auto-
brightness changes)
- Registers the new com.apple.CoreBrightness.DisplayBrightnessChanged
notification
- Fixes deprecated kIOMasterPortDefault → kIOMainPortDefault in
SystemDisplayManager.swift
Fixes#452
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add session-active and CGSession poll fallbacks for unlock detection
- Force weather panel alpha to 0 before orderOut for instant hide
Signed-off-by: Jis G Jacob <studiokeys@blissroms.org>
- Push content below notch cutout, tighten album art halo
- Resize play/pause and side buttons to fit inside notch bounds
- Scope progress bar clipping so album art glow renders fully
Signed-off-by: Jis G Jacob <studiokeys@blissroms.org>
Subscribe DynamicIslandArtworkLoopController to MusicManager.isPlaying
so the looping AVQueuePlayer pauses and resumes with playback state.
Signed-off-by: Jis G Jacob <jackeagle102@gmail.com>
Google's "secure browsers" policy refuses OAuth inside any WKWebView
regardless of UA, so signing into Spotify with a Google-linked account
in the in-app sheet dead-ended on Google's "browser may be insecure"
page. Intercept navigations to accounts.google.com / accounts.youtube.com
in both decidePolicyFor and the createWebViewWith popup path, redirect
back to Spotify's login screen, and surface a status message pointing
users at email/password/Apple/Facebook sign-in or the existing
"Open in Browser" escape hatch for Google accounts. Update the sheet's
initial banner so the limitation is visible before the user tries it.
Signed-off-by: Jis G Jacob <studiokeys@blissroms.org>
SIGSTOP WallpaperAgent and the aerial extensions while MusicManager
reports paused so the lockscreen Canvas holds its current frame, and
SIGCONT on resume, hide(), and willTerminate so the agent is never
left suspended.
Signed-off-by: Jis G Jacob <studiokeys@blissroms.org>
Wraps accounts.spotify.com login in a WKWebView so users can sign in
without opening the browser inspector to copy the sp_dc cookie. The
sheet uses a non-persistent data store, observes the cookie store, and
hands the captured value to the existing SpotifyAuthManager.validate
flow on a match.
Spotify's anti-bot blocks the WebView path for some accounts, so this
sits alongside (not replaces) the manual paste field, with an "Open in
Browser" escape hatch in the sheet toolbar.
Signed-off-by: Jis G Jacob <studiokeys@blissroms.org>
OSDUIHelper jetsam-exits when idle and launchd spawns a fresh PID on
the next media-key press, so the one-shot SIGSTOP only suppressed the
first incarnation. SystemOSDManager now polls for the PID after
kickstart and runs a background watcher that re-SIGSTOPs every new
incarnation, with state guarded by OSAllocatedUnfairLock. Watcher is
torn down on enableSystemHUD().
Fixes the legacy OSDUIHelper duplicate-HUD path in #419.
The macOS 26 Liquid Glass HUD (loginwindow -> BezelServices ->
ControlCenter SystemBannerService) is a separate render path gated by
the com.apple.private.system-banner-client entitlement and is not
suppressible from a regular user-space app; it needs a privileged
SMAppService helper and is out of scope here.
Signed-off-by: Jis G Jacob <studiokeys@blissroms.org>
Replace the transparent canvas-fallback panel background with a soft
ultra-thin dark scrim plus a gentle vertical gradient and hairline
stroke, and add a subtle drop shadow on the foreground so titles, time
labels, and controls stay readable on bright or busy canvas videos.
Restore consistent horizontal and vertical padding in canvas-fallback
mode so the marquee title and inline elapsed/remaining timers no longer
hug the panel edges.
Signed-off-by: Jis G Jacob <studiokeys@blissroms.org>
The lockscreen battery widget treated any plugged-in-but-not-charging
state as 'Fully charged'. macOS pauses charging for battery health
(e.g., optimized battery charging at 80%), so this misreported the
actual battery state.
Now 'Fully charged' shows only at 100% + plugged in; otherwise the
detail label reads '<level>% • On hold' (with a matching accessibility
string). Charging-in-progress and fully-charged states are unchanged.
The 1 GiB resident-size threshold is reasonable for a release build,
but Swift/SwiftUI debug builds plus the AVPlayer-backed Canvas video
pipeline and SkyLight overlay windows can easily exceed it during
normal Xcode-attached development. The restart-alert dialog firing
mid-development is disruptive and not actionable.
Keep the 1 GiB safety net on release, raise to 4 GiB in DEBUG so
developers running under Xcode aren't interrupted by spurious
restart prompts. The poll interval, cooldown, and alert text all
stay the same.
Signed-off-by: Jis G Jacob <studiokeys@blissroms.org>
Two fixes for the right-click-artwork-to-wallpaper flow on Spotify
tracks that have a Canvas video.
1. Force AllSpacesAndDisplays.Type and SystemDefault.Type to
"individual" while the artwork is active (was: keep existing
value via nil-coalescing). On macOS Tahoe the user-level
wallpaper rotation honors the parent Type field, so leaving it
as "folder" caused WallpaperAgent to advance to the next image
in a rotating wallpaper pack instead of honoring the patched
single-image / aerial choice. The original Type is preserved in
the plist backup at temp/atoll_wallpaper_backup.plist and is
restored byte-for-byte on dismiss, so rotation resumes normally
after the artwork is dismissed. The forced override is also
applied to nested Displays / Spaces blocks but only when Type
was already present, to avoid mutating block shapes that
intentionally omit it.
2. When the Canvas is expected at right-click time
(effectiveVideoURL != nil), defer applyArtworkToPlist and
restartWallpaperAgent entirely. Previously the flow applied raw
album art as the static wallpaper, restarted the agent, then
prepared and applied the aerial in a second restart, causing a
visible flash of the raw album cover. The deferred path stores
the blurred fallback URL in pendingFallbackStaticURL and only
touches the plist once: with the aerial on success, or with the
blurred album cover via applyDeferredStaticFallback if the
aerial asset prep or aerial-plist patch fails. The in-app
videoWindow continues to mask the desktop wallpaper during prep
on the unlocked screen; the lock screen simply transitions from
the existing wallpaper straight to the Canvas video.
The earlier ?? nil-coalescing in patchWallpaperEntries also covered
per-Display, per-Space.Default, and per-Space.Displays Type fields,
so those are forced too where present.
Signed-off-by: Jis G Jacob <studiokeys@blissroms.org>
The Spotify Canvas fallback layout previously centered the panel+artwork
group on screenFrame.midY, so the enlarged artwork tile could push up
into the row of circular widgets (battery, audio, AQI, weather).
Clamp maxCenterY against the bottom edge of both
LockScreenWeatherPanelManager.latestFrame and
LockScreenTimerWidgetPanelManager.latestFrame, with a 20pt clearance,
and guard against the clamp inverting via max(maxCenterY, minCenterY).
The panel reflows through the existing
.atollLockScreenPanelFrameDidChange notification, so the artwork
overlay window follows the new panel position automatically.
Signed-off-by: Jis G Jacob <studiokeys@blissroms.org>
The widget is too small to display both the title and countdown
comfortably. Replaced the title section with a spacer so the
controls and countdown spread out cleanly.
Signed-off-by: Jis G Jacob <studiokeys@blissroms.org>
Uses MusicKit MusicCatalogSearchRequest to find the current track, then
fetches editorialVideo.motionTallVideo3x4 HLS URL via MusicDataRequest.
The animated artwork URL is pre-fetched on track change and cached per
song for instant availability.
Adds NSAppleMusicUsageDescription to Info.plist for MusicKit
authorization.
Signed-off-by: Jis G Jacob <studiokeys@blissroms.org>
Right-click on the album art in the lock screen music panel to set it
as the desktop wallpaper. Right-click again or click anywhere on the
background to restore the original wallpaper. Wallpaper also restores
automatically on track change or screen unlock.
Uses direct plist manipulation of the wallpaper config to avoid leaving
traces in the wallpaper picker. Album art PNG is pre-cached in the
background on track change for instant application.
Adds video artwork URL fetching from iTunes catalog for Apple Music
tracks (musicVideo entity search).
Signed-off-by: Jis G Jacob <studiokeys@blissroms.org>