Skip to content

Commit

Permalink
Bring back the pastStatusPublisher to prevent offset from being chang…
Browse files Browse the repository at this point in the history
…ed on lid close.
  • Loading branch information
OCJvanDijk committed Apr 19, 2020
1 parent 41047ab commit 51329d7
Showing 1 changed file with 39 additions and 16 deletions.
55 changes: 39 additions & 16 deletions Brightness Sync/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,10 @@ class AppDelegate: NSObject, NSApplicationDelegate {
let diagnostics = """
CGDisplayList:
\(CGDisplays.map {
["VendorNumber": CGDisplayVendorNumber($0),
"ModelNumber": CGDisplayModelNumber($0),
"SerialNumber": CGDisplaySerialNumber($0)]
})
["VendorNumber": CGDisplayVendorNumber($0),
"ModelNumber": CGDisplayModelNumber($0),
"SerialNumber": CGDisplaySerialNumber($0)]
})
IODisplayList:
\(IODisplays)
Expand All @@ -118,13 +118,10 @@ class AppDelegate: NSObject, NSApplicationDelegate {
// MARK: - Brightness Sync

enum Status: Equatable {
case deactivated
case noTargets
case lidClosed
case paused
case running(sourceBrightness: Double, targets: [Target])

var isRunning: Bool {
self != .deactivated && self != .paused
}
}

struct Target: Equatable {
Expand All @@ -138,7 +135,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
var cancelBag = Set<AnyCancellable>()

func setup() {
let brightnessPublisher = sourceDisplayPublisher
let statusPublisher = sourceDisplayPublisher
.combineLatest(targetDisplaysPublisher, pausedPublisher)
.map { [monitorOffsets] source, targets, paused -> AnyPublisher<Status, Never> in
// We don't want the timer running unless necessary to save energy
Expand All @@ -162,16 +159,31 @@ class AppDelegate: NSObject, NSApplicationDelegate {
)
}
.eraseToAnyPublisher()
} else {
} else if source == nil {
os_log("Deactivated...")
return Just(.deactivated).eraseToAnyPublisher()
return Just(.lidClosed).eraseToAnyPublisher()
} else {
return Just(.noTargets).eraseToAnyPublisher()
}
}
.switchToLatest()
.removeDuplicates()
.multicast(subject: PassthroughSubject())

brightnessPublisher
// There is a quirk in CoreDisplay, that causes it to read incorrect values just before you close the lid and enter clamshell mode.
// This causes different kinds of problems, so we roll back to two seconds ago.
// This is probably desirable anyway because even without the quirk closing the lid will briefly affect brightness readings.
let pastStatusPublisher = statusPublisher.delay(for: .seconds(2), scheduler: RunLoop.current).prepend(.noTargets)
let rollbackInjector = statusPublisher.withLatestFrom(pastStatusPublisher)
.compactMap { brightnessStatus, brightnessStatusTwoSecondsAgo -> [Target]? in
if brightnessStatus == .lidClosed, case let .running(_, targets) = brightnessStatusTwoSecondsAgo {
return targets
} else {
return nil
}
}

statusPublisher
.scan(nil) { previouslySynced, newStatus -> [Target]? in
guard case let .running(sourceBrightness, targets) = newStatus else { return nil }

Expand All @@ -194,6 +206,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}
}
.compactMap { $0 }
.merge(with: rollbackInjector)
.sink { [monitorOffsets] targets in
for target in targets {
CoreDisplay_Display_SetLinearBrightness(CGDisplayGetDisplayIDFromUUID(target.id), target.brightness)
Expand All @@ -202,10 +215,10 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}
.store(in: &cancelBag)

brightnessPublisher
statusPublisher
.map {
switch $0 {
case .deactivated:
case .lidClosed, .noTargets:
return "Deactivated"
case .paused:
return "Paused"
Expand All @@ -217,7 +230,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
.assign(to: \.title, on: statusIndicator)
.store(in: &cancelBag)

brightnessPublisher.connect().store(in: &cancelBag)
statusPublisher.connect().store(in: &cancelBag)
}

// MARK: - Displays
Expand Down Expand Up @@ -338,3 +351,13 @@ extension Comparable {
return min(max(self, limits.lowerBound), limits.upperBound)
}
}

extension Publisher {
func withLatestFrom<A, P: Publisher>(_ second: P)
-> Publishers.SwitchToLatest<Publishers.Map<Self, (Self.Output, A)>, Publishers.Map<P, Publishers.Map<Self, (Self.Output, A)>>> where P.Output == A, P.Failure == Failure {
second.map { latestValue in
self.map { ownValue in (ownValue, latestValue) }
}
.switchToLatest()
}
}

0 comments on commit 51329d7

Please sign in to comment.