fix(settings): detect TERM_PROGRAM=ghostty and apply low-motion cap (#1445)
Ghostty's GPU compositor flash-renders each full-screen repaint at 120 FPS, producing visible flicker identical to the VS Code issue fixed in #1356. Extend apply_env_overrides() to also force low_motion=true + fancy_animations=false when TERM_PROGRAM=ghostty, capping redraws to 30 FPS. Add ghostty_term_program_forces_low_motion_on test mirroring the existing vscode test, serialised through the process-wide lock_test_env() guard. Fixes #1445 Signed-off-by: CrepuscularIRIS <serenitygp@qq.com>
This commit is contained in:
committed by
Hunter Bown
parent
4bc5375fa6
commit
97a77d82f0
@@ -316,12 +316,16 @@ impl Settings {
|
||||
self.low_motion = true;
|
||||
self.fancy_animations = false;
|
||||
}
|
||||
// VS Code's integrated terminal sets TERM_PROGRAM=vscode. Its
|
||||
// compositor cannot keep up with 120 FPS redraws and produces rapid
|
||||
// flickering (#1356). Drop to the 30 FPS low-motion cap automatically.
|
||||
// VS Code (TERM_PROGRAM=vscode, #1356) and Ghostty (TERM_PROGRAM=ghostty,
|
||||
// #1445) both produce visible flicker at 120 FPS: VS Code's compositor
|
||||
// cannot keep pace; Ghostty's GPU compositor flash-renders each full-screen
|
||||
// repaint. Drop to the 30 FPS low-motion cap for both automatically.
|
||||
// Like NO_ANIMATIONS above, this unconditionally overrides any
|
||||
// disk-loaded value — consistent precedence: env signals always win.
|
||||
if std::env::var("TERM_PROGRAM").as_deref() == Ok("vscode") {
|
||||
if matches!(
|
||||
std::env::var("TERM_PROGRAM").as_deref(),
|
||||
Ok("vscode") | Ok("ghostty")
|
||||
) {
|
||||
self.low_motion = true;
|
||||
self.fancy_animations = false;
|
||||
}
|
||||
@@ -946,6 +950,34 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ghostty_term_program_forces_low_motion_on() {
|
||||
let _g = term_program_test_guard();
|
||||
let prev = std::env::var_os("TERM_PROGRAM");
|
||||
// SAFETY: serialised by the guard.
|
||||
unsafe {
|
||||
std::env::set_var("TERM_PROGRAM", "ghostty");
|
||||
}
|
||||
let mut settings = Settings::default();
|
||||
assert!(!settings.low_motion, "default is animated");
|
||||
settings.apply_env_overrides();
|
||||
assert!(
|
||||
settings.low_motion,
|
||||
"TERM_PROGRAM=ghostty must enable low_motion to prevent flickering (#1445)"
|
||||
);
|
||||
assert!(
|
||||
!settings.fancy_animations,
|
||||
"TERM_PROGRAM=ghostty must disable fancy_animations"
|
||||
);
|
||||
// SAFETY: cleanup under the guard.
|
||||
unsafe {
|
||||
match prev {
|
||||
Some(v) => std::env::set_var("TERM_PROGRAM", v),
|
||||
None => std::env::remove_var("TERM_PROGRAM"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn non_vscode_term_program_does_not_force_low_motion() {
|
||||
let _g = term_program_test_guard();
|
||||
|
||||
Reference in New Issue
Block a user