Mac 上按時段調暗螢幕,以及那個會把螢幕一路調成全黑的陷阱
按時段調暗螢幕聽起來是兩行程式的事:看錶、設亮度。陷阱在「設」這個字上。如果你要設的值是從目前已有的值推算出來的,那麼每複查一次螢幕就更暗一點——到早上它就全黑了。
這個功能,從使用者角度看
一天被分成幾個時段——工作時段、傍晚時段、夜間時段——每一段各自帶白點與亮度。沒有全域開關;改 21:00 的行為不會影響 14:00。
時間以距本地午夜的分鐘數儲存。這帶來一個漂亮的結果:結束時間早於開始時間就自動跨越午夜,所以「夜間 20:00 到 08:00」完全不需要特例——它和別的時段是同一套算術。
陷阱一——會自己越乘越小的「倍數」
下面這種寫法看起來完全合理:
let current = display.brightness
let dimmed = current * 0.6 // 錯的
apply(dimmed)
把它掛在 60 秒一次的心跳上,面板就會被反覆乘以 0.6:0.6、0.36、0.22、0.13……螢幕會自己走向全黑,而使用者的說法是「這個應用程式一夜之間把我螢幕弄壞了」。
解法是把值做成絕對量——按滿量程的比例,而不是即時值的倍數:
let target = 0.6 // 滿量程的比例
apply(target)
現在套用兩次和套用一次的結果相同。用一個詞說:這個排程器是幂等的。反覆求值不等於空操作的排程器,不是幂等的——而它會漂移。
陷阱二——你拖滑桿時,心跳不跳了
第二個陷阱更安靜。掛在預設 run loop 模式上的計時器,在使用者拖動滑桿時不會觸發——因為拖動會把 run loop 按在事件追蹤模式裡。於是那個本該在 21:00 落下的複查,悄無聲息地沒落下。
把心跳註冊在 .common 模式下,它就仍然會落下——而那恰恰是使用者最容易注意到的時刻。
陷阱三——會自我重啟的淡入淡出
值變成絕對量之後,緊接著的問題是:排程器對同一個時段做了兩次決定會怎樣?如果每次決定都重啟淡入淡出,螢幕就會每分鐘可見地脈衝一次。正確答案是:已經生效的時段是空操作,所以心跳不會重啟一段已經在往正確目標走的過渡。
而且必須可逆
關掉排程時,把面板交還給開啟排程之前的狀態——不是交還給某個預設值。使用者原本設的是 80%,就拿回 80%,而不是 100%。
兩個更小、但值得點名的決定
- 淡入淡出的時長調到「長到讀得出是一次過渡,短到不覺得遲鈍」——一個真實的取捨,說出來而不是藏起來。
- 休息(番茄鐘式計時)可以調暗或遮罩螢幕。狀態機帶一鍵跳過,可以提前結束休息回到工作。
誠實的邊界
- 它調暗的是畫面,不是背光。低亮度下黑位不再是真的黑。
- 改白點是軟體色溫,不是硬體校準。要準確的顏色得上色度計。
- 它與 Night Shift、f.lux 屬於同一類機制——我們不聲稱比這更高級。
相關
全部指南 · 外接顯示器亮度怎麼調 · 色彩發灰 · DDC/CI 無回應