fix: quick terminal CPU spikes

Fixes #3998
This commit is contained in:
Damien Mehala
2024-12-30 12:29:03 +01:00
committed by Jonathan Lopez
parent 46a232d209
commit 1697853245

View File

@ -69,7 +69,7 @@ class QuickTerminalController: BaseTerminalController {
window.isRestorable = false window.isRestorable = false
// Setup our configured appearance that we support. // Setup our configured appearance that we support.
syncAppearance(ghostty.config) syncAppearance()
// Setup our initial size based on our configured position // Setup our initial size based on our configured position
position.setLoaded(window) position.setLoaded(window)
@ -214,6 +214,10 @@ class QuickTerminalController: BaseTerminalController {
// If we canceled our animation in we do nothing // If we canceled our animation in we do nothing
guard self.visible else { return } guard self.visible else { return }
// Now that the window is visible, sync our appearance. This function
// requires the window is visible.
self.syncAppearance()
// Once our animation is done, we must grab focus since we can't grab // Once our animation is done, we must grab focus since we can't grab
// focus of a non-visible window. // focus of a non-visible window.
self.makeWindowKey(window) self.makeWindowKey(window)
@ -304,24 +308,18 @@ class QuickTerminalController: BaseTerminalController {
}) })
} }
private func syncAppearance(_ config: Ghostty.Config) { private func syncAppearance() {
guard let window else { return } guard let window else { return }
// If our window is not visible, then delay this. This is possible specifically // If our window is not visible, then no need to sync the appearance yet.
// during state restoration but probably in other scenarios as well. To delay, // Some APIs such as window blur have no effect unless the window is visible.
// we just loop directly on the dispatch queue. We have to delay because some guard window.isVisible else { return }
// APIs such as window blur have no effect unless the window is visible.
guard window.isVisible else {
// Weak window so that if the window changes or is destroyed we aren't holding a ref
DispatchQueue.main.async { [weak self] in self?.syncAppearance(config) }
return
}
// Terminals typically operate in sRGB color space and macOS defaults // Terminals typically operate in sRGB color space and macOS defaults
// to "native" which is typically P3. There is a lot more resources // to "native" which is typically P3. There is a lot more resources
// covered in this GitHub issue: https://github.com/mitchellh/ghostty/pull/376 // covered in this GitHub issue: https://github.com/mitchellh/ghostty/pull/376
// Ghostty defaults to sRGB but this can be overridden. // Ghostty defaults to sRGB but this can be overridden.
switch (config.windowColorspace) { switch (self.derivedConfig.windowColorspace) {
case "display-p3": case "display-p3":
window.colorSpace = .displayP3 window.colorSpace = .displayP3
case "srgb": case "srgb":
@ -331,7 +329,7 @@ class QuickTerminalController: BaseTerminalController {
} }
// If we have window transparency then set it transparent. Otherwise set it opaque. // If we have window transparency then set it transparent. Otherwise set it opaque.
if (config.backgroundOpacity < 1) { if (self.derivedConfig.backgroundOpacity < 1) {
window.isOpaque = false window.isOpaque = false
// This is weird, but we don't use ".clear" because this creates a look that // This is weird, but we don't use ".clear" because this creates a look that
@ -391,24 +389,30 @@ class QuickTerminalController: BaseTerminalController {
// Update our derived config // Update our derived config
self.derivedConfig = DerivedConfig(config) self.derivedConfig = DerivedConfig(config)
syncAppearance(config) syncAppearance()
} }
private struct DerivedConfig { private struct DerivedConfig {
let quickTerminalScreen: QuickTerminalScreen let quickTerminalScreen: QuickTerminalScreen
let quickTerminalAnimationDuration: Double let quickTerminalAnimationDuration: Double
let quickTerminalAutoHide: Bool let quickTerminalAutoHide: Bool
let windowColorspace: String
let backgroundOpacity: Double
init() { init() {
self.quickTerminalScreen = .main self.quickTerminalScreen = .main
self.quickTerminalAnimationDuration = 0.2 self.quickTerminalAnimationDuration = 0.2
self.quickTerminalAutoHide = true self.quickTerminalAutoHide = true
self.windowColorspace = ""
self.backgroundOpacity = 1.0
} }
init(_ config: Ghostty.Config) { init(_ config: Ghostty.Config) {
self.quickTerminalScreen = config.quickTerminalScreen self.quickTerminalScreen = config.quickTerminalScreen
self.quickTerminalAnimationDuration = config.quickTerminalAnimationDuration self.quickTerminalAnimationDuration = config.quickTerminalAnimationDuration
self.quickTerminalAutoHide = config.quickTerminalAutoHide self.quickTerminalAutoHide = config.quickTerminalAutoHide
self.windowColorspace = config.windowColorspace
self.backgroundOpacity = config.backgroundOpacity
} }
} }
} }