From 04754b624536b1a36bf1608f78645a76f7d3ea55 Mon Sep 17 00:00:00 2001 From: Xabi Spacebiker <1733884+xabispacebiker@users.noreply.github.com> Date: Sun, 24 May 2026 00:16:41 +0200 Subject: [PATCH] Fix system color scheme not refreshing live (#37) The window's appearance was being locked to .aqua or .darkAqua on every theme update, which prevented WKWebView's prefers-color-scheme media query from tracking macOS appearance changes. With colorMode = "system" in Bluesky, the title bar and content stayed in the old theme until the user manually refreshed. Pass Bluesky's colorMode through to Swift in the windowColorSchemeChange message, and leave window.appearance unset when it's "system" so the media query follows macOS. Chain updateColorScheme() onto the localStorage write in checkAppearance() so the title-bar round-trip uses the fresh initSystemAppearance. --- Sky/ScriptMessageHandler.swift | 10 ++++------ Sky/Scripts/hook_window_color_scheme.js | 2 ++ Sky/ViewController.swift | 19 +++++++++++-------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/Sky/ScriptMessageHandler.swift b/Sky/ScriptMessageHandler.swift index 3416d02..2e6713f 100644 --- a/Sky/ScriptMessageHandler.swift +++ b/Sky/ScriptMessageHandler.swift @@ -50,12 +50,10 @@ class ScriptMessageHandler: NSObject, WKScriptMessageHandler { let darkMode = messageBody["darkMode"] as? Int, let backgroundColor = messageBody["backgroundColor"] as? String { - // NSLog("colorScheme: \(colorScheme), darkMode: \(darkMode), backgroundColor: \(backgroundColor)") - if darkMode == 1 { - viewController.updateTitleBar(.dark, backgroundColor: backgroundColor) - } else { - viewController.updateTitleBar(.light, backgroundColor: backgroundColor) - } + let colorMode = messageBody["colorMode"] as? String + // NSLog("colorScheme: \(colorScheme), darkMode: \(darkMode), backgroundColor: \(backgroundColor), colorMode: \(colorMode ?? "nil")") + let mode: ViewController.WindowColorScheme = darkMode == 1 ? .dark : .light + viewController.updateTitleBar(mode, backgroundColor: backgroundColor, colorMode: colorMode) } } } diff --git a/Sky/Scripts/hook_window_color_scheme.js b/Sky/Scripts/hook_window_color_scheme.js index ec61736..3a34807 100644 --- a/Sky/Scripts/hook_window_color_scheme.js +++ b/Sky/Scripts/hook_window_color_scheme.js @@ -88,6 +88,7 @@ function updateColorSchemeWithBskyStorage(bskyStorage) { colorScheme: match.name, darkMode: match.darkMode, backgroundColor: match.backgroundColor, + colorMode: colorMode, }); return true; } @@ -106,6 +107,7 @@ function updateColorSchemeAuto() { colorScheme: match.name, darkMode: match.darkMode, backgroundColor: match.backgroundColor, + colorMode: "system", }); return true; } diff --git a/Sky/ViewController.swift b/Sky/ViewController.swift index 3fbe987..f474444 100644 --- a/Sky/ViewController.swift +++ b/Sky/ViewController.swift @@ -46,12 +46,12 @@ class ViewController: NSViewController { NSLog("checkAppearance initSystemAppearanceValue = \(initSystemAppearanceValue)") if self.webView != nil { NSLog("checkAppearance setting local storage") - self.webView.evaluateJavaScript( - Scripts.localStorageSetItem( - key: LocalStorageKeys.initSystemAppearance, - value: initSystemAppearanceValue - ) - ) + // Chain updateColorScheme() so the title bar message sees the fresh localStorage. + let script = Scripts.localStorageSetItem( + key: LocalStorageKeys.initSystemAppearance, + value: initSystemAppearanceValue + ) + "\nif (typeof updateColorScheme === 'function') { updateColorScheme(); }" + self.webView.evaluateJavaScript(script) } } @@ -477,7 +477,7 @@ class ViewController: NSViewController { case light } - func updateTitleBar(_ mode: WindowColorScheme, backgroundColor: String) { + func updateTitleBar(_ mode: WindowColorScheme, backgroundColor: String, colorMode: String? = nil) { if backgroundColor.starts(with:"rgb("), let range = backgroundColor.range(of: #"\((.*?)\)"#, options: .regularExpression) { @@ -496,7 +496,10 @@ class ViewController: NSViewController { ) } } - if mode == .dark { + // Leave appearance unset for "system" so WKWebView's prefers-color-scheme follows macOS. + if colorMode == "system" { + self.webView.window!.appearance = nil + } else if mode == .dark { self.webView.window!.appearance = NSAppearance(named: .darkAqua) } else { self.webView.window!.appearance = NSAppearance(named: .aqua)