|
| 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 | + |
| 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 | +|  |  | |
| 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