diff --git a/Sources/AppDelegate.swift b/Sources/AppDelegate.swift index e0cabdaa..155ecfc9 100644 --- a/Sources/AppDelegate.swift +++ b/Sources/AppDelegate.swift @@ -3372,6 +3372,39 @@ final class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCent return nil } + func refreshTerminalSurfacesAfterGhosttyConfigReload(source: String) { + var refreshedCount = 0 + forEachTerminalPanel { terminalPanel in + terminalPanel.hostedView.reconcileGeometryNow() + terminalPanel.surface.forceRefresh() + refreshedCount += 1 + } +#if DEBUG + dlog("reload.config.surfaceRefresh source=\(source) count=\(refreshedCount)") +#endif + } + + private func forEachTerminalPanel(_ body: (TerminalPanel) -> Void) { + var seenManagers: Set = [] + + func visitManager(_ manager: TabManager?) { + guard let manager else { return } + let managerId = ObjectIdentifier(manager) + guard seenManagers.insert(managerId).inserted else { return } + for workspace in manager.tabs { + for panel in workspace.panels.values { + guard let terminalPanel = panel as? TerminalPanel else { continue } + body(terminalPanel) + } + } + } + + visitManager(tabManager) + for context in mainWindowContexts.values { + visitManager(context.tabManager) + } + } + func focusMainWindow(windowId: UUID) -> Bool { guard let window = windowForMainWindowId(windowId) else { return false } if TerminalController.shouldSuppressSocketCommandActivation() { diff --git a/Sources/GhosttyTerminalView.swift b/Sources/GhosttyTerminalView.swift index bc7329cc..0a6b2489 100644 --- a/Sources/GhosttyTerminalView.swift +++ b/Sources/GhosttyTerminalView.swift @@ -660,6 +660,7 @@ class GhosttyApp { private func loadDefaultConfigFilesWithLegacyFallback(_ config: ghostty_config_t) { ghostty_config_load_default_files(config) loadLegacyGhosttyConfigIfNeeded(config) + ghostty_config_load_recursive_files(config) ghostty_config_finalize(config) } @@ -767,6 +768,7 @@ class GhosttyApp { ghostty_app_update_config(app, config) lastAppearanceColorScheme = GhosttyConfig.currentColorSchemePreference() NotificationCenter.default.post(name: .ghosttyConfigDidReload, object: nil) + scheduleSurfaceRefreshAfterConfigurationReload(source: source) logThemeAction("reload end source=\(source) soft=\(soft) mode=soft") return } @@ -791,9 +793,16 @@ class GhosttyApp { config = newConfig lastAppearanceColorScheme = GhosttyConfig.currentColorSchemePreference() NotificationCenter.default.post(name: .ghosttyConfigDidReload, object: nil) + scheduleSurfaceRefreshAfterConfigurationReload(source: source) logThemeAction("reload end source=\(source) soft=\(soft) mode=full") } + private func scheduleSurfaceRefreshAfterConfigurationReload(source: String) { + DispatchQueue.main.async { + AppDelegate.shared?.refreshTerminalSurfacesAfterGhosttyConfigReload(source: source) + } + } + func synchronizeThemeWithAppearance(_ appearance: NSAppearance?, source: String) { let currentColorScheme = GhosttyConfig.currentColorSchemePreference( appAppearance: appearance ?? NSApp?.effectiveAppearance