Fix reload config to honor legacy Ghostty config fallback (#202)

This commit is contained in:
Lawrence Chen 2026-02-20 14:30:21 -08:00 committed by GitHub
parent c40ec75616
commit ab84a02152
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 58 additions and 9 deletions

View file

@ -288,9 +288,7 @@ class GhosttyApp {
// Load default config (includes user config). If this fails hard (e.g. due to
// invalid user config), ghostty_app_new may return nil; we fall back below.
ghostty_config_load_default_files(primaryConfig)
loadLegacyGhosttyConfigIfNeeded(primaryConfig)
ghostty_config_finalize(primaryConfig)
loadDefaultConfigFilesWithLegacyFallback(primaryConfig)
updateDefaultBackground(from: primaryConfig)
// Create runtime config with callbacks
@ -458,6 +456,21 @@ class GhosttyApp {
#endif
}
private func loadDefaultConfigFilesWithLegacyFallback(_ config: ghostty_config_t) {
ghostty_config_load_default_files(config)
loadLegacyGhosttyConfigIfNeeded(config)
ghostty_config_finalize(config)
}
static func shouldLoadLegacyGhosttyConfig(
newConfigFileSize: Int?,
legacyConfigFileSize: Int?
) -> Bool {
guard let newConfigFileSize, newConfigFileSize == 0 else { return false }
guard let legacyConfigFileSize, legacyConfigFileSize > 0 else { return false }
return true
}
private func loadLegacyGhosttyConfigIfNeeded(_ config: ghostty_config_t) {
#if os(macOS)
// Ghostty 1.3+ prefers `config.ghostty`, but some users still have their real
@ -475,8 +488,10 @@ class GhosttyApp {
return size.intValue
}
guard let newSize = fileSize(configNew), newSize == 0 else { return }
guard let legacySize = fileSize(configLegacy), legacySize > 0 else { return }
guard Self.shouldLoadLegacyGhosttyConfig(
newConfigFileSize: fileSize(configNew),
legacyConfigFileSize: fileSize(configLegacy)
) else { return }
configLegacy.path.withCString { path in
ghostty_config_load_file(config, path)
@ -512,8 +527,7 @@ class GhosttyApp {
}
guard let newConfig = ghostty_config_new() else { return }
ghostty_config_load_default_files(newConfig)
ghostty_config_finalize(newConfig)
loadDefaultConfigFilesWithLegacyFallback(newConfig)
ghostty_app_update_config(app, newConfig)
updateDefaultBackground(from: newConfig)
DispatchQueue.main.async {
@ -533,8 +547,7 @@ class GhosttyApp {
}
guard let newConfig = ghostty_config_new() else { return }
ghostty_config_load_default_files(newConfig)
ghostty_config_finalize(newConfig)
loadDefaultConfigFilesWithLegacyFallback(newConfig)
ghostty_surface_update_config(surface, newConfig)
ghostty_config_free(newConfig)
}

View file

@ -126,6 +126,42 @@ final class GhosttyConfigTests: XCTestCase {
XCTAssertEqual(rgb255(config.backgroundColor), RGB(red: 253, green: 246, blue: 227))
}
func testLegacyConfigFallbackUsesLegacyFileWhenConfigGhosttyIsEmpty() {
XCTAssertTrue(
GhosttyApp.shouldLoadLegacyGhosttyConfig(
newConfigFileSize: 0,
legacyConfigFileSize: 42
)
)
}
func testLegacyConfigFallbackSkipsWhenNewFileMissingOrLegacyEmpty() {
XCTAssertFalse(
GhosttyApp.shouldLoadLegacyGhosttyConfig(
newConfigFileSize: nil,
legacyConfigFileSize: 42
)
)
XCTAssertFalse(
GhosttyApp.shouldLoadLegacyGhosttyConfig(
newConfigFileSize: 10,
legacyConfigFileSize: 42
)
)
XCTAssertFalse(
GhosttyApp.shouldLoadLegacyGhosttyConfig(
newConfigFileSize: 0,
legacyConfigFileSize: 0
)
)
XCTAssertFalse(
GhosttyApp.shouldLoadLegacyGhosttyConfig(
newConfigFileSize: 0,
legacyConfigFileSize: nil
)
)
}
private func rgb255(_ color: NSColor) -> RGB {
let srgb = color.usingColorSpace(.sRGB)!
var red: CGFloat = 0