Skip to content

Commit 9a35ab0

Browse files
shivamhwpclaude
andauthored
fix(mobile): iOS terminal font and theme changes no longer replay output (#36115)
Co-authored-by: Claude Haiku 5.5 <[email protected]>
1 parent 8610b31 commit 9a35ab0

1 file changed

Lines changed: 30 additions & 8 deletions

File tree

‎apps/mobile/modules/t3-terminal/ios/T3TerminalView.swift‎

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ public final class T3TerminalView: ExpoView, UITextFieldDelegate, UIEditMenuInte
285285
didSet {
286286
guard oldValue != fontSize else { return }
287287
inputField.font = UIFont.monospacedSystemFont(ofSize: max(fontSize, 13), weight: .regular)
288-
resetSurface()
288+
applyConfigInPlace()
289289
}
290290
}
291291

@@ -321,14 +321,14 @@ public final class T3TerminalView: ExpoView, UITextFieldDelegate, UIEditMenuInte
321321
didSet {
322322
guard oldValue != appearanceScheme else { return }
323323
appearance = TerminalAppearanceScheme(value: appearanceScheme)
324-
resetSurface()
324+
applyConfigInPlace()
325325
}
326326
}
327327

328328
var themeConfig: String = "" {
329329
didSet {
330330
guard oldValue != themeConfig else { return }
331-
resetSurface()
331+
applyConfigInPlace()
332332
}
333333
}
334334

@@ -663,7 +663,8 @@ public final class T3TerminalView: ExpoView, UITextFieldDelegate, UIEditMenuInte
663663
surfaceCreationFailed = true
664664
return
665665
}
666-
loadThemeConfig(into: config)
666+
// Creation proceeds without the file, as before; font_size is also set on the surface config.
667+
_ = loadThemeConfig(into: config)
667668
ghostty_config_finalize(config)
668669
defer { ghostty_config_free(config) }
669670

@@ -710,6 +711,27 @@ public final class T3TerminalView: ExpoView, UITextFieldDelegate, UIEditMenuInte
710711
setNeedsLayout()
711712
}
712713

714+
// Font and theme change in place: a new surface would replay output and re-answer its queries.
715+
private func applyConfigInPlace() {
716+
guard let app, let surface else {
717+
resetSurface()
718+
return
719+
}
720+
guard let config = ghostty_config_new() else { return }
721+
defer { ghostty_config_free(config) }
722+
let loaded = loadThemeConfig(into: config)
723+
ghostty_config_finalize(config)
724+
ghostty_app_set_color_scheme(app, appearance.ghosttyColorScheme)
725+
ghostty_surface_set_color_scheme(surface, appearance.ghosttyColorScheme)
726+
tickApp()
727+
// Without the file, the config lacks font-size and would reset the surface to defaults.
728+
if loaded {
729+
ghostty_surface_update_config(surface, config)
730+
}
731+
resizeSurface()
732+
setNeedsLayout()
733+
}
734+
713735
private func destroySurface() {
714736
// Unblock the io thread before ghostty_surface_free joins it.
715737
tickApp()
@@ -933,16 +955,16 @@ public final class T3TerminalView: ExpoView, UITextFieldDelegate, UIEditMenuInte
933955
terminalViewport.backgroundColor = backgroundColorValue
934956
}
935957

936-
private func loadThemeConfig(into config: ghostty_config_t) {
937-
guard let path = writeThemeConfigFile() else { return }
958+
private func loadThemeConfig(into config: ghostty_config_t) -> Bool {
959+
guard let path = writeThemeConfigFile() else { return false }
938960
path.withCString { cString in
939961
ghostty_config_load_file(config, cString)
940962
}
963+
return true
941964
}
942965

943966
private func writeThemeConfigFile() -> String? {
944-
guard !themeConfig.isEmpty else { return nil }
945-
let configContents = themeConfig
967+
let configContents = "\(themeConfig)\nfont-size = \(String(format: "%g", Double(fontSize)))\n"
946968
let url = URL(fileURLWithPath: NSTemporaryDirectory())
947969
.appendingPathComponent("t3-terminal-theme-\(appearance.rawValue).ghostty")
948970

0 commit comments

Comments
 (0)