Fix browser pane dark-mode leak on light pages (#2346)
* Fix browser pane dark-mode leak * Restore browser theme mode without CSS injection
This commit is contained in:
parent
35cb42fbc8
commit
79bcf1d370
2 changed files with 30 additions and 60 deletions
|
|
@ -210,6 +210,17 @@ enum BrowserThemeSettings {
|
|||
|
||||
return defaultMode
|
||||
}
|
||||
|
||||
static func apply(_ mode: BrowserThemeMode, to webView: WKWebView) {
|
||||
switch mode {
|
||||
case .system:
|
||||
webView.appearance = nil
|
||||
case .light:
|
||||
webView.appearance = NSAppearance(named: .aqua)
|
||||
case .dark:
|
||||
webView.appearance = NSAppearance(named: .darkAqua)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum BrowserImportHintVariant: String, CaseIterable, Identifiable {
|
||||
|
|
@ -2295,6 +2306,10 @@ final class BrowserPanel: Panel, ObservableObject {
|
|||
profileID == BrowserProfileStore.shared.builtInDefaultProfileID
|
||||
}
|
||||
|
||||
var currentBrowserThemeMode: BrowserThemeMode {
|
||||
browserThemeMode
|
||||
}
|
||||
|
||||
private static let portalHostAreaThreshold: CGFloat = 4
|
||||
private static let portalHostReplacementAreaGainRatio: CGFloat = 1.2
|
||||
|
||||
|
|
@ -2468,8 +2483,9 @@ final class BrowserPanel: Panel, ObservableObject {
|
|||
if #available(macOS 13.3, *) {
|
||||
webView.isInspectable = true
|
||||
}
|
||||
// Match the empty-page background to the terminal theme so newly-created browsers
|
||||
// don't flash white before content loads.
|
||||
// Match only the unpainted/loading background so newly-created browsers don't flash
|
||||
// white before content loads. Do not force page appearance or inject color-scheme CSS;
|
||||
// websites must keep control of their own theme.
|
||||
webView.underPageBackgroundColor = GhosttyBackgroundTheme.currentColor()
|
||||
// Always present as Safari.
|
||||
webView.customUserAgent = BrowserUserAgentSettings.safariUserAgent
|
||||
|
|
@ -2544,7 +2560,6 @@ final class BrowserPanel: Panel, ObservableObject {
|
|||
self.realignRestoredSessionHistoryToLiveCurrentIfPossible()
|
||||
boundHistoryStore.recordVisit(url: webView.url, title: webView.title)
|
||||
self.refreshFavicon(from: webView)
|
||||
self.applyBrowserThemeModeIfNeeded()
|
||||
// Keep find-in-page open through load completion and refresh matches for the new DOM.
|
||||
self.restoreFindStateAfterNavigation(replaySearch: true)
|
||||
}
|
||||
|
|
@ -4929,6 +4944,9 @@ extension BrowserPanel {
|
|||
func setBrowserThemeMode(_ mode: BrowserThemeMode) {
|
||||
browserThemeMode = mode
|
||||
applyBrowserThemeModeIfNeeded()
|
||||
for controller in popupControllers {
|
||||
controller.setBrowserThemeMode(mode)
|
||||
}
|
||||
}
|
||||
|
||||
func refreshAppearanceDrivenColors() {
|
||||
|
|
@ -5431,63 +5449,7 @@ extension BrowserPanel {
|
|||
|
||||
private extension BrowserPanel {
|
||||
func applyBrowserThemeModeIfNeeded() {
|
||||
switch browserThemeMode {
|
||||
case .system:
|
||||
webView.appearance = nil
|
||||
case .light:
|
||||
webView.appearance = NSAppearance(named: .aqua)
|
||||
case .dark:
|
||||
webView.appearance = NSAppearance(named: .darkAqua)
|
||||
}
|
||||
|
||||
let script = makeBrowserThemeModeScript(mode: browserThemeMode)
|
||||
webView.evaluateJavaScript(script) { _, error in
|
||||
#if DEBUG
|
||||
if let error {
|
||||
dlog("browser.themeMode error=\(error.localizedDescription)")
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
func makeBrowserThemeModeScript(mode: BrowserThemeMode) -> String {
|
||||
let colorSchemeLiteral: String
|
||||
switch mode {
|
||||
case .system:
|
||||
colorSchemeLiteral = "null"
|
||||
case .light:
|
||||
colorSchemeLiteral = "'light'"
|
||||
case .dark:
|
||||
colorSchemeLiteral = "'dark'"
|
||||
}
|
||||
|
||||
return """
|
||||
(() => {
|
||||
const metaId = 'cmux-browser-theme-mode-meta';
|
||||
const colorScheme = \(colorSchemeLiteral);
|
||||
const root = document.documentElement || document.body;
|
||||
if (!root) return;
|
||||
|
||||
let meta = document.getElementById(metaId);
|
||||
if (colorScheme) {
|
||||
root.style.setProperty('color-scheme', colorScheme, 'important');
|
||||
root.setAttribute('data-cmux-browser-theme', colorScheme);
|
||||
if (!meta) {
|
||||
meta = document.createElement('meta');
|
||||
meta.id = metaId;
|
||||
meta.name = 'color-scheme';
|
||||
(document.head || root).appendChild(meta);
|
||||
}
|
||||
meta.setAttribute('content', colorScheme);
|
||||
} else {
|
||||
root.style.removeProperty('color-scheme');
|
||||
root.removeAttribute('data-cmux-browser-theme');
|
||||
if (meta) {
|
||||
meta.remove();
|
||||
}
|
||||
}
|
||||
})();
|
||||
"""
|
||||
BrowserThemeSettings.apply(browserThemeMode, to: webView)
|
||||
}
|
||||
|
||||
func scheduleDeveloperToolsRestoreRetry() {
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ final class BrowserPopupWindowController: NSObject, NSWindowDelegate {
|
|||
}
|
||||
webView.underPageBackgroundColor = GhosttyBackgroundTheme.currentColor()
|
||||
webView.customUserAgent = BrowserUserAgentSettings.safariUserAgent
|
||||
BrowserThemeSettings.apply(openerPanel?.currentBrowserThemeMode ?? BrowserThemeSettings.mode(), to: webView)
|
||||
self.webView = webView
|
||||
|
||||
// --- Window sizing from WKWindowFeatures ---
|
||||
|
|
@ -251,6 +252,13 @@ final class BrowserPopupWindowController: NSObject, NSWindowDelegate {
|
|||
childPopups.removeAll { $0 === child }
|
||||
}
|
||||
|
||||
func setBrowserThemeMode(_ mode: BrowserThemeMode) {
|
||||
BrowserThemeSettings.apply(mode, to: webView)
|
||||
for child in childPopups {
|
||||
child.setBrowserThemeMode(mode)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Popup lifecycle
|
||||
|
||||
func closePopup() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue