summaryrefslogtreecommitdiffstats
path: root/zellij-server/src/pty.rs
diff options
context:
space:
mode:
authorAlexandre Courbot <gnurou@gmail.com>2021-10-25 23:51:30 +0900
committerGitHub <noreply@github.com>2021-10-25 16:51:30 +0200
commit21380c278e6dcd26dd883461224d2291fa0aa522 (patch)
tree3700dd11af98c5fb5cbce381e8e8774ed0b3cd2a /zellij-server/src/pty.rs
parent0c9634708325445aa1109a22027f21a2814f8f3a (diff)
fix(performance): immediately render after a period of inactivity (#798)
The current code waits for 30ms after reading new data to refresh the screen in order to batch input together. This reduces the number of refreshes, but also adds perceptible latency as keystrokes will only get visual feedback after a 30 ms delay. Improve this by immediately refreshing if more than 30ms have already passed since the last refresh. That way punctual events like keystrokes get immediate feedback, while heavier input still gets batched together.
Diffstat (limited to 'zellij-server/src/pty.rs')
-rw-r--r--zellij-server/src/pty.rs12
1 files changed, 8 insertions, 4 deletions
diff --git a/zellij-server/src/pty.rs b/zellij-server/src/pty.rs
index 76ff7978b..277f572c8 100644
--- a/zellij-server/src/pty.rs
+++ b/zellij-server/src/pty.rs
@@ -216,10 +216,13 @@ fn stream_terminal_bytes(
err_ctx.add_call(ContextType::AsyncTask);
// After a successful read, we keep on reading additional data up to a duration of
- // `render_pause`. This is in order to batch up PtyBytes before rendering them.
+ // `RENDER_PAUSE`. This is in order to batch up PtyBytes before rendering them.
// Once `render_deadline` has elapsed, we send Render.
- let render_pause = Duration::from_millis(30);
+ const RENDER_PAUSE: Duration = Duration::from_millis(30);
let mut render_deadline = None;
+ // Keep track of the last render time so we can render immediately if something shows
+ // up after a period of inactivity. This reduces input latency perception.
+ let mut last_render = Instant::now();
let mut buf = [0u8; 65536];
let mut async_reader = os_input.async_file_reader(pid);
@@ -230,6 +233,7 @@ fn stream_terminal_bytes(
async_send_to_screen(senders.clone(), ScreenInstruction::Render).await;
// next read does not need a deadline as we just rendered everything
render_deadline = None;
+ last_render = Instant::now();
}
ReadResult::Ok(n_bytes) => {
let bytes = &buf[..n_bytes];
@@ -242,8 +246,8 @@ fn stream_terminal_bytes(
)
.await;
// if we already have a render_deadline we keep it, otherwise we set it
- // to the duration of `render_pause`.
- render_deadline.get_or_insert(Instant::now() + render_pause);
+ // to RENDER_PAUSE since the last time we rendered.
+ render_deadline.get_or_insert(last_render + RENDER_PAUSE);
}
}
}