diff --git a/Sources/GhosttyTerminalView+Keyboard.swift b/Sources/GhosttyTerminalView+Keyboard.swift index 431f74ef..308afc1b 100644 --- a/Sources/GhosttyTerminalView+Keyboard.swift +++ b/Sources/GhosttyTerminalView+Keyboard.swift @@ -919,7 +919,11 @@ extension GhosttyNSView { #if DEBUG let refreshStart = ProcessInfo.processInfo.systemUptime #endif - terminalSurface?.forceRefresh(reason: "keyDown.textInput") + // PERF (#183): deliberately not forceRefresh. Typing changes grid + // contents, never the surface's geometry or display, so the display-id + // reassert and forceRefreshSurface() that forceRefresh does are pure + // cost here. forceRefresh stays for the topology changes it exists for. + terminalSurface?.requestRedrawAfterInput() #if DEBUG refreshMs = (ProcessInfo.processInfo.systemUptime - refreshStart) * 1000.0 ProgramaDurationSamples.shared.record("keyDown.textInputRefresh", milliseconds: refreshMs) diff --git a/Sources/TerminalSurface.swift b/Sources/TerminalSurface.swift index 810205ac..9f553b0f 100644 --- a/Sources/TerminalSurface.swift +++ b/Sources/TerminalSurface.swift @@ -1426,6 +1426,29 @@ final class TerminalSurface: Identifiable, ObservableObject { return true } + /// Ask Ghostty to redraw after committed text input, without the geometry + /// reconciliation `forceRefresh` does. + /// + /// PERF (#183): this runs after every printable keystroke. `forceRefresh` + /// additionally reasserts the display id and calls `forceRefreshSurface()`, + /// which exist for *topology* changes -- split close/reparent, and the + /// stuck-vsync state after wake-from-sleep -- none of which a character can + /// cause. Typing changes the grid contents, not the surface's size or which + /// display it lives on. + /// + /// The early-out conditions are deliberately identical to `forceRefresh`'s, + /// so *when* a redraw happens is unchanged; only the work done differs. + func requestRedrawAfterInput() { + guard let view = attachedView, + view.window != nil, + view.bounds.width > 0, + view.bounds.height > 0 else { + return + } + guard let surface = self.surface else { return } + ghostty_surface_refresh(surface) + } + /// Force a full size recalculation and surface redraw. func forceRefresh(reason: String = "unspecified") { // PERF (#183): this diagnostic string is consumed only by the DEBUG-only `dlog` below,