Skip to content

Commit 0a706e0

Browse files
committed
smooth scrolling post
1 parent 9179c74 commit 0a706e0

File tree

3 files changed

+67
-0
lines changed

3 files changed

+67
-0
lines changed
134 KB
Loading
294 KB
Loading
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
---
2+
draft: false
3+
date: 2025-02-16
4+
categories:
5+
- DevLog
6+
authors:
7+
- willmcgugan
8+
---
9+
10+
# Smoother scrolling in the terminal — a feature decades in the making
11+
12+
The great philosopher F. Bueller once said “Life moves pretty fast. If you don't stop and look around once in a while, you could miss it.”
13+
14+
Beuller was *not* taking about terminals, which tend not to move very fast at all.
15+
Until they do.
16+
From time to time terminals acquire new abilities after a long plateau.
17+
We are now seeing a kind of punctuated evolution in terminals which makes things possible that just weren't feasible a short time ago.
18+
19+
I want to talk about one such feature, which *I believe* has been decades[^1] in the making.
20+
Take a look at the following screen recording (taken from a TUI running in the terminal):
21+
22+
![A TUI Scrollbar](../images/smooth-scroll/no-smooth-scroll.gif)
23+
24+
<!-- more -->
25+
26+
Note how the mouse pointer moves relatively smoothly, but the scrollbar jumps with a jerky motion.
27+
28+
This happens because the terminal reports the mouse coordinates in cells (a *cell* is the dimensions of a single latin-alphabet character).
29+
In other words, the app knows only which cell is under the pointer.
30+
It isn't granular enough to know where the pointer is *within* a cell.
31+
32+
Until recently terminal apps couldn't do any better.
33+
More granular mouse reporting is possible in the terminal; write the required escape sequence and mouse coordinates are reported in pixels rather than cells.
34+
So why haven't TUIs been using this?
35+
36+
The problem is that we can't translate between pixel coordinates and cell coordinates without first knowing how many pixels are in a cell.
37+
And in order to know that, we need to know the width and height of the terminal in *pixels*.
38+
Unfortunately, that standard way to get the terminal size reports just cells.
39+
40+
At least they didn't before [this extension](https://gist.github.com/rockorager/e695fb2924d36b2bcf1fff4a3704bd83) which reports the size of the terminal in cell *and* pixel coordinates.
41+
Once we have both the mouse coordinates in pixels and the dimensions of the terminal in pixels, we can implement much smoother scrolling.
42+
43+
Let's see how this looks.
44+
45+
On the right we have smooth scrolling enabled, on the left is the default non-smooth scrolling:
46+
47+
48+
| Default scrolling | Smooth scrolling |
49+
| ---------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
50+
| ![A TUI Scrollbar](../images/smooth-scroll/no-smooth-scroll.gif) | ![A TUI Scrollbar with smooth scrolling](../images/smooth-scroll/smooth-scroll.gif) |
51+
52+
Notice how much smoother the motion of the table is, now that it tracks the mouse cursor more accurately.
53+
If you move the scrollbar quickly, you may not notice the difference.
54+
But if you move slowly like you are searching for something, it is a respectable quality of life improvement.
55+
56+
If you have one of the terminals which support this feature[^2], and at least [Textual](https://github.com/textualize/textual/) 2.0.0 you will be able to see this in action.
57+
58+
I think Textual may be the first library to implement this.
59+
Let me know, if you have encountered any non-Textual TUI app which implements this kind of smooth scrolling.
60+
61+
## Join us
62+
63+
Join our [Discord server](https://discord.gg/Enf6Z3qhVr) to discuss anything terminal related with the Textualize devs, or the community!
64+
65+
66+
[^1]: I'm not sure exactly when pixel mouse reporting was added to terminals. I'd be interested if anyone has a precised date.
67+
[^2]: Kitty, Ghostty, and a few others.

0 commit comments

Comments
 (0)