mirror of
https://github.com/FBukovina/Atoll.git
synced 2026-10-27 15:14:33 +00:00
Fix: Brightness and Volume Control
This commit is contained in:
parent
f4bcb96906
commit
98c826aaae
11 changed files with 340 additions and 97 deletions
|
|
@ -11,82 +11,102 @@ import Foundation
|
|||
import Defaults
|
||||
|
||||
class SystemChangesObserver {
|
||||
private var oldVolume: Float
|
||||
private var oldMuted: Bool
|
||||
private var oldVolume: Float = 0
|
||||
private var oldMuted: Bool = false
|
||||
private var oldBrightness: Float = 0
|
||||
|
||||
private weak var coordinator: DynamicIslandViewCoordinator?
|
||||
private var timer: Timer?
|
||||
|
||||
// Backup timer for edge cases only
|
||||
private var backupTimer: Timer?
|
||||
|
||||
init(coordinator: DynamicIslandViewCoordinator) {
|
||||
self.coordinator = coordinator
|
||||
|
||||
// Initialize baseline values only once
|
||||
oldVolume = SystemVolumeManager.getOutputVolume()
|
||||
oldMuted = SystemVolumeManager.isMuted()
|
||||
|
||||
|
||||
do {
|
||||
oldBrightness = try SystemDisplayManager.getDisplayBrightness()
|
||||
} catch {
|
||||
NSLog("Failed to retrieve display brightness: \(error)")
|
||||
NSLog("Failed to retrieve initial display brightness: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
func startObserving() {
|
||||
guard Defaults[.enableSystemHUD] else { return }
|
||||
|
||||
createObservers()
|
||||
createTimerForContinuousChangesCheck(with: 0.2)
|
||||
}
|
||||
|
||||
private func createTimerForContinuousChangesCheck(with seconds: TimeInterval) {
|
||||
timer = Timer(
|
||||
timeInterval: seconds, target: self, selector: #selector(checkChanges), userInfo: nil,
|
||||
repeats: true)
|
||||
let mainLoop = RunLoop.main
|
||||
mainLoop.add(timer!, forMode: .common)
|
||||
}
|
||||
|
||||
private func createObservers() {
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(showVolumeHUD),
|
||||
name: SystemKeyObserver.volumeChanged,
|
||||
object: nil)
|
||||
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(showBrightnessHUD),
|
||||
name: SystemKeyObserver.brightnessChanged,
|
||||
object: nil)
|
||||
}
|
||||
|
||||
@objc func showVolumeHUD() {
|
||||
guard Defaults[.enableSystemHUD] && Defaults[.enableVolumeHUD] else { return }
|
||||
|
||||
if oldVolume == 0.0 || oldVolume == 1.0 {
|
||||
sendVolumeNotification(value: oldVolume)
|
||||
}
|
||||
print("Showing volume HUD")
|
||||
startMinimalBackupTimer()
|
||||
}
|
||||
|
||||
@objc func showBrightnessHUD() {
|
||||
guard Defaults[.enableSystemHUD] && Defaults[.enableBrightnessHUD] else { return }
|
||||
|
||||
if oldBrightness == 0.0 || oldBrightness == 1.0 {
|
||||
sendBrightnessNotification(value: oldBrightness)
|
||||
private func startMinimalBackupTimer() {
|
||||
// More frequent backup check (every 300ms) for better responsiveness
|
||||
// This is a reasonable compromise between the original 200ms and the previous 5s
|
||||
backupTimer = Timer.scheduledTimer(withTimeInterval: 0.3, repeats: true) { [weak self] _ in
|
||||
guard Defaults[.enableSystemHUD] else { return }
|
||||
self?.performBackupCheck()
|
||||
}
|
||||
print("Showing brightness HUD")
|
||||
}
|
||||
|
||||
@objc func checkChanges() {
|
||||
guard Defaults[.enableSystemHUD] else { return }
|
||||
|
||||
checkBrightnessChanges()
|
||||
|
||||
private func performBackupCheck() {
|
||||
// Only check if we haven't had recent activity
|
||||
checkVolumeChanges()
|
||||
checkBrightnessChanges()
|
||||
}
|
||||
|
||||
private func isAlmost(firstNumber: Float, secondNumber: Float) -> Bool {
|
||||
let marginValue = 5 / 100.0
|
||||
return (firstNumber + Float(marginValue) >= secondNumber && firstNumber - Float(marginValue) <= secondNumber)
|
||||
|
||||
// MARK: - Public Media Key Event Handlers (called from MediaKeyApplication)
|
||||
|
||||
func handleVolumeKeyEvent() {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
|
||||
self.handleVolumeKeyPress()
|
||||
}
|
||||
}
|
||||
|
||||
func handleBrightnessKeyEvent() {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
|
||||
self.handleBrightnessKeyPress()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Key Press Event Handlers
|
||||
|
||||
private func handleVolumeKeyPress() {
|
||||
guard Defaults[.enableVolumeHUD] else { return }
|
||||
|
||||
let newVolume = SystemVolumeManager.getOutputVolume()
|
||||
let newMuted = SystemVolumeManager.isMuted()
|
||||
|
||||
// Always show HUD for key press feedback, even if value doesn't change
|
||||
print("🔊 Volume key pressed - showing HUD: volume=\(newVolume), muted=\(newMuted)")
|
||||
|
||||
if newMuted {
|
||||
sendVolumeNotification(value: 0.0)
|
||||
} else {
|
||||
sendVolumeNotification(value: newVolume)
|
||||
}
|
||||
|
||||
// Update stored values
|
||||
oldVolume = newVolume
|
||||
oldMuted = newMuted
|
||||
}
|
||||
|
||||
private func handleBrightnessKeyPress() {
|
||||
guard Defaults[.enableBrightnessHUD] else { return }
|
||||
guard NSScreen.screens.count > 0 else { return }
|
||||
|
||||
do {
|
||||
let newBrightness = try SystemDisplayManager.getDisplayBrightness()
|
||||
|
||||
// Always show HUD for key press feedback, even if value doesn't change
|
||||
print("☀️ Brightness key pressed - showing HUD: brightness=\(newBrightness)")
|
||||
sendBrightnessNotification(value: newBrightness)
|
||||
|
||||
// Update stored value
|
||||
oldBrightness = newBrightness
|
||||
} catch {
|
||||
// Silently ignore brightness errors to reduce log spam
|
||||
}
|
||||
}
|
||||
|
||||
private func checkVolumeChanges() {
|
||||
|
|
@ -95,7 +115,12 @@ class SystemChangesObserver {
|
|||
let newVolume = SystemVolumeManager.getOutputVolume()
|
||||
let newMuted = SystemVolumeManager.isMuted()
|
||||
|
||||
if !isAlmost(firstNumber: oldVolume, secondNumber: newVolume) || newMuted != oldMuted {
|
||||
let volumeChanged = !isAlmost(firstNumber: oldVolume, secondNumber: newVolume)
|
||||
let muteChanged = newMuted != oldMuted
|
||||
|
||||
if volumeChanged || muteChanged {
|
||||
print("🔊 Volume change detected: \(oldVolume) → \(newVolume), muted: \(oldMuted) → \(newMuted)")
|
||||
|
||||
if newMuted {
|
||||
sendVolumeNotification(value: 0.0)
|
||||
} else {
|
||||
|
|
@ -108,22 +133,30 @@ class SystemChangesObserver {
|
|||
|
||||
private func checkBrightnessChanges() {
|
||||
guard Defaults[.enableBrightnessHUD] else { return }
|
||||
|
||||
if NSScreen.screens.count == 0 {
|
||||
return
|
||||
}
|
||||
guard NSScreen.screens.count > 0 else { return }
|
||||
|
||||
do {
|
||||
let newBrightness = try SystemDisplayManager.getDisplayBrightness()
|
||||
if !isAlmost(firstNumber: oldBrightness, secondNumber: newBrightness) {
|
||||
let brightnessChanged = !isAlmost(firstNumber: oldBrightness, secondNumber: newBrightness)
|
||||
|
||||
if brightnessChanged {
|
||||
print("☀️ Brightness change detected: \(oldBrightness) → \(newBrightness)")
|
||||
sendBrightnessNotification(value: newBrightness)
|
||||
oldBrightness = newBrightness
|
||||
}
|
||||
} catch {
|
||||
NSLog("Failed to retrieve display brightness: \(error)")
|
||||
// Silently ignore brightness errors to reduce log spam
|
||||
}
|
||||
}
|
||||
|
||||
private func isAlmost(firstNumber: Float, secondNumber: Float) -> Bool {
|
||||
// Convert sensitivity setting to a more responsive threshold
|
||||
// Sensitivity 1-10 scale maps to 0.01-0.10 threshold range
|
||||
let marginValue = Float(Defaults[.systemHUDSensitivity]) / 100.0
|
||||
let threshold = max(0.01, marginValue) // Minimum threshold for responsiveness
|
||||
return abs(firstNumber - secondNumber) <= threshold
|
||||
}
|
||||
|
||||
// MARK: - Internal Notification Methods
|
||||
|
||||
private func sendVolumeNotification(value: Float) {
|
||||
|
|
@ -149,8 +182,12 @@ class SystemChangesObserver {
|
|||
}
|
||||
|
||||
func stopObserving() {
|
||||
timer?.invalidate()
|
||||
timer = nil
|
||||
NotificationCenter.default.removeObserver(self)
|
||||
// Clean up backup timer
|
||||
backupTimer?.invalidate()
|
||||
backupTimer = nil
|
||||
|
||||
print("🎹 Media key detection stopped")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue