mirror of
https://github.com/wez/wezterm.git
synced 2024-11-27 12:23:46 +03:00
Add separate animation_fps config for easing
and adjust animation scheduling to avoid excessive scheduling if the time we compute is later than an already scheduled time
This commit is contained in:
parent
39babc1f1e
commit
0826fb060c
@ -433,6 +433,9 @@ pub struct Config {
|
||||
#[serde(default = "linear_ease")]
|
||||
pub cursor_blink_ease_out: EasingFunction,
|
||||
|
||||
#[serde(default = "default_anim_fps")]
|
||||
pub animation_fps: u8,
|
||||
|
||||
#[serde(default)]
|
||||
pub force_reverse_video_cursor: bool,
|
||||
|
||||
@ -1164,6 +1167,10 @@ fn default_mux_env_remove() -> Vec<String> {
|
||||
]
|
||||
}
|
||||
|
||||
fn default_anim_fps() -> u8 {
|
||||
10
|
||||
}
|
||||
|
||||
fn default_max_fps() -> u8 {
|
||||
60
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ pub struct ColorEase {
|
||||
out_duration: f32,
|
||||
out_function: EasingFunction,
|
||||
start: Option<Instant>,
|
||||
last_render: Instant,
|
||||
}
|
||||
|
||||
impl ColorEase {
|
||||
@ -24,6 +25,7 @@ impl ColorEase {
|
||||
out_duration: Duration::from_millis(out_duration_ms).as_secs_f32(),
|
||||
out_function,
|
||||
start,
|
||||
last_render: Instant::now(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,7 +37,7 @@ impl ColorEase {
|
||||
self.start.replace(start);
|
||||
}
|
||||
|
||||
pub fn intensity_continuous(&mut self) -> f32 {
|
||||
pub fn intensity_continuous(&mut self) -> (f32, Instant) {
|
||||
match self.intensity_one_shot() {
|
||||
Some(intensity) => intensity,
|
||||
None => {
|
||||
@ -46,7 +48,7 @@ impl ColorEase {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn intensity_one_shot(&mut self) -> Option<f32> {
|
||||
pub fn intensity_one_shot(&mut self) -> Option<(f32, Instant)> {
|
||||
let start = self.start?;
|
||||
let elapsed = start.elapsed().as_secs_f32();
|
||||
|
||||
@ -64,9 +66,37 @@ impl ColorEase {
|
||||
}
|
||||
};
|
||||
|
||||
if intensity.is_none() {
|
||||
self.start.take();
|
||||
match intensity {
|
||||
Some(i) => {
|
||||
let now = Instant::now();
|
||||
let fps = config::configuration().animation_fps as u64;
|
||||
let next = match fps {
|
||||
1 if elapsed < self.in_duration => {
|
||||
start + Duration::from_secs_f32(self.in_duration)
|
||||
}
|
||||
1 => {
|
||||
start
|
||||
+ Duration::from_secs_f32(self.in_duration)
|
||||
+ Duration::from_secs_f32(self.out_duration)
|
||||
}
|
||||
_ => {
|
||||
let frame_interval = 1000 / fps as u64;
|
||||
let elapsed = (elapsed * 1000.).ceil() as u64;
|
||||
let remain = elapsed % frame_interval;
|
||||
if remain != 0 {
|
||||
now + Duration::from_millis(remain)
|
||||
} else {
|
||||
now + Duration::from_millis(frame_interval)
|
||||
}
|
||||
}
|
||||
};
|
||||
self.last_render = now;
|
||||
Some((i, next))
|
||||
}
|
||||
None => {
|
||||
self.start.take();
|
||||
None
|
||||
}
|
||||
}
|
||||
intensity
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ use mux::tab::{PositionedPane, PositionedSplit, SplitDirection};
|
||||
use smol::Timer;
|
||||
use std::ops::Range;
|
||||
use std::rc::Rc;
|
||||
use std::time::{Duration, Instant};
|
||||
use std::time::Instant;
|
||||
use termwiz::cell::{unicode_column_width, Blink};
|
||||
use termwiz::cellcluster::CellCluster;
|
||||
use termwiz::surface::{CursorShape, CursorVisibility};
|
||||
@ -302,18 +302,24 @@ impl super::TermWindow {
|
||||
// invalidate the viewport when the next frame is due
|
||||
if self.focused.is_some() {
|
||||
if let Some(next_due) = *self.has_animation.borrow() {
|
||||
if Some(next_due) != *self.scheduled_animation.borrow() {
|
||||
self.scheduled_animation.borrow_mut().replace(next_due);
|
||||
let window = self.window.clone().take().unwrap();
|
||||
promise::spawn::spawn(async move {
|
||||
Timer::at(next_due).await;
|
||||
let win = window.clone();
|
||||
window.notify(TermWindowNotif::Apply(Box::new(move |tw| {
|
||||
tw.scheduled_animation.borrow_mut().take();
|
||||
win.invalidate();
|
||||
})));
|
||||
})
|
||||
.detach();
|
||||
let prior = self.scheduled_animation.borrow_mut().take();
|
||||
match prior {
|
||||
Some(prior) if prior <= next_due => {
|
||||
// Already due before that time
|
||||
}
|
||||
_ => {
|
||||
self.scheduled_animation.borrow_mut().replace(next_due);
|
||||
let window = self.window.clone().take().unwrap();
|
||||
promise::spawn::spawn(async move {
|
||||
Timer::at(next_due).await;
|
||||
let win = window.clone();
|
||||
window.notify(TermWindowNotif::Apply(Box::new(move |tw| {
|
||||
tw.scheduled_animation.borrow_mut().take();
|
||||
win.invalidate();
|
||||
})));
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -357,10 +363,8 @@ impl super::TermWindow {
|
||||
None => {
|
||||
per_pane.bell_start.take();
|
||||
}
|
||||
Some(intensity) => {
|
||||
self.update_next_frame_time(Some(
|
||||
Instant::now() + Duration::from_millis(1000 / config.max_fps as u64),
|
||||
));
|
||||
Some((intensity, next)) => {
|
||||
self.update_next_frame_time(Some(next));
|
||||
return Some(intensity);
|
||||
}
|
||||
}
|
||||
@ -1608,7 +1612,7 @@ impl super::TermWindow {
|
||||
};
|
||||
if let Some((blink_rate, mut colorease)) = blink_rate {
|
||||
if blink_rate != 0 {
|
||||
let intensity = colorease.intensity_continuous();
|
||||
let (intensity, next) = colorease.intensity_continuous();
|
||||
|
||||
let (r1, g1, b1, a) = bg.tuple();
|
||||
let (r, g, b, _a) = fg.tuple();
|
||||
@ -1619,10 +1623,7 @@ impl super::TermWindow {
|
||||
a,
|
||||
);
|
||||
|
||||
self.update_next_frame_time(Some(
|
||||
Instant::now()
|
||||
+ Duration::from_millis(1000 / self.config.max_fps as u64),
|
||||
));
|
||||
self.update_next_frame_time(Some(next));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2518,7 +2519,7 @@ impl super::TermWindow {
|
||||
if blinking {
|
||||
let mut color_ease = self.cursor_blink_state.borrow_mut();
|
||||
color_ease.update_start(self.prev_cursor.last_cursor_movement());
|
||||
let intensity = color_ease.intensity_continuous();
|
||||
let (intensity, next) = color_ease.intensity_continuous();
|
||||
|
||||
// Invert the intensity: we want to start with a visible
|
||||
// cursor whenever the cursor moves, then fade out, then back.
|
||||
@ -2547,9 +2548,7 @@ impl super::TermWindow {
|
||||
);
|
||||
}
|
||||
|
||||
self.update_next_frame_time(Some(
|
||||
Instant::now() + Duration::from_millis(1000 / self.config.max_fps as u64),
|
||||
));
|
||||
self.update_next_frame_time(Some(next));
|
||||
}
|
||||
|
||||
ComputeCellFgBgResult {
|
||||
|
Loading…
Reference in New Issue
Block a user