Feature Request: Smoothly scroll in new lines #1864

Open
opened 2026-01-30 22:40:26 +00:00 by claunia · 19 comments
Owner

Originally created by @ghost on GitHub (Jun 22, 2019).

Summary of the new feature/enhancement

Some hardware terminals allowed smoothly scrolling in new lines. It should be possible to implement this kind of feature in a software terminal emulator as well.

YouTube demonstration (VT525 smooth scrolling):
https://www.youtube.com/watch?v=Iju_pOQM0a0

Originally created by @ghost on GitHub (Jun 22, 2019). # Summary of the new feature/enhancement Some hardware terminals allowed smoothly scrolling in new lines. It should be possible to implement this kind of feature in a software terminal emulator as well. YouTube demonstration (VT525 smooth scrolling): https://www.youtube.com/watch?v=Iju_pOQM0a0
Author
Owner

@zadjii-msft commented on GitHub (Jul 15, 2019):

This seems like it'll be a dupe of #1066. When that one's fixed, this should be too. Thanks!

@zadjii-msft commented on GitHub (Jul 15, 2019): This seems like it'll be a dupe of #1066. When that one's fixed, this should be too. Thanks!
Author
Owner

@zadjii-msft commented on GitHub (Nov 11, 2019):

I may have been premature in closing this. This is definitely not a dupe of #1066, this is something entirely else.

I'm not sure how possible this is. I guess hypothetically we could render a portion of a line at a time, or just render the frame and then apply some sort of transform on it. Getting the velocity by which to scroll these lines might be hard though - how fast should a new line appear on the screen? What happens if multiple lines are output during the course of a frame?

I'm not saying it's impossible, but it will be hard.

@zadjii-msft commented on GitHub (Nov 11, 2019): I may have been premature in closing this. This is definitely _not_ a dupe of #1066, this is something entirely else. I'm not sure how possible this is. I guess hypothetically we could render a portion of a line at a time, or just render the frame and then apply some sort of transform on it. Getting the velocity by which to scroll these lines might be hard though - how fast should a new line appear on the screen? What happens if multiple lines are output during the course of a frame? I'm not saying it's impossible, but it will be hard.
Author
Owner

@mdtauk commented on GitHub (Nov 11, 2019):

If there were an internal buffer, when there is a pause in output, all the lines could then render in. But this should be an option to enable, rather than a new default.

I would say the same for "typing" of lines, instead of an instant "pop-in"

@mdtauk commented on GitHub (Nov 11, 2019): If there were an internal buffer, when there is a pause in output, all the lines could then render in. But this should be an option to enable, rather than a new default. I would say the same for "typing" of lines, instead of an instant "pop-in"
Author
Owner

@egmontkob commented on GitHub (Nov 11, 2019):

FYI: iTerm2 counterpart

@egmontkob commented on GitHub (Nov 11, 2019): FYI: [iTerm2 counterpart](https://gitlab.com/gnachman/iterm2/issues/8389)
Author
Owner

@j4james commented on GitHub (Nov 12, 2019):

Note that in addition to the VT100 DECSCLM mode for switching between smooth and jump scrolling, later terminals also had the DECSSCLS command, which gave you more control over the speed of smooth scrolling.

I don't think the exact speeds matter that much, since the smooth scrolling on a VT100 was originally 6 lines per second (STD 070 gives that value too), while on later terminals the default speed was 9 lines per second. I believe the original value was simply the result of the monitor refresh rate (60Hz) and the number of scan lines in a row (10).

@j4james commented on GitHub (Nov 12, 2019): Note that in addition to the VT100 [`DECSCLM`](https://vt100.net/docs/vt510-rm/DECSCLM.html) mode for switching between smooth and jump scrolling, later terminals also had the [`DECSSCLS`](https://vt100.net/docs/vt510-rm/DECSSCLS.html) command, which gave you more control over the speed of smooth scrolling. I don't think the exact speeds matter that much, since the smooth scrolling on a VT100 was originally 6 lines per second (STD 070 gives that value too), while on later terminals the default speed was 9 lines per second. I believe the original value was simply the result of the monitor refresh rate (60Hz) and the number of scan lines in a row (10).
Author
Owner

@Livven commented on GitHub (Mar 22, 2020):

I think this issue actually includes three related but different things:

  • Scrolling in new lines smoothly, as per the original issue description.
  • Handling precision touchpad scrolling, which is at the (sub-)pixel instead of line level, as per #1980 which was closed as a duplicate of this.
  • Animating mouse wheel or PgUp/PgDn etc. scrolling, as per this comment 😉
@Livven commented on GitHub (Mar 22, 2020): I think this issue actually includes three related but different things: - Scrolling in new lines smoothly, as per the original issue description. - Handling precision touchpad scrolling, which is at the (sub-)pixel instead of line level, as per #1980 which was closed as a duplicate of this. - Animating mouse wheel or PgUp/PgDn etc. scrolling, as per this comment 😉
Author
Owner

@DHowett commented on GitHub (Dec 11, 2020):

Description of the new feature/enhancement

I would absolutely die and go to heaven if smooth and precise (i.e. animated and pixel-by-pixel) scrolling were implemented. One of the top reasons I started using Edge Chromium over Chrome was due to the slightly better smooth scrolling implementation.

Being able to easily read text while scrolling smoothly and precisely is a game... changer...! Especially, if you have a free scroll wheel like the MX Master 3 and/or a 120Hz+ monitor.

Proposed technical implementation details (optional)

Implementing something like this is outside of my wheelhouse, but I found some great information on the topic here: pavelfatin.com/scrolling-with-pleasure

I understand that the pure intent of a terminal emulator is to display single lines as quickly and efficiently as possible. But from a UX perspective, smooth/precise scrolling feels sooo good with the right peripherals.

Let me know your thoughts please! 😁

From #8548

@DHowett commented on GitHub (Dec 11, 2020): > # Description of the new feature/enhancement > I would absolutely die and go to heaven if smooth _and_ precise (i.e. animated and pixel-by-pixel) scrolling were implemented. One of the top reasons I started using Edge Chromium over Chrome was due to the slightly better smooth scrolling implementation. > > Being able to easily read text while scrolling smoothly and precisely is a game... changer...! Especially, if you have a free scroll wheel like the MX Master 3 and/or a 120Hz+ monitor. > > # Proposed technical implementation details (optional) > Implementing something like this is outside of my wheelhouse, but I found some great information on the topic here: [pavelfatin.com/scrolling-with-pleasure](https://pavelfatin.com/scrolling-with-pleasure/) > > I understand that the pure intent of a terminal emulator is to display single lines as quickly and efficiently as possible. But from a UX perspective, smooth/precise scrolling feels sooo good with the right peripherals. > > Let me know your thoughts please! 😁 From #8548
Author
Owner

@perennialmind commented on GitHub (Jan 28, 2021):

Obligatory reference to Pavel Fatin's Scrolling with Pleasure. Scroll smoothing compensates for low precision using animation. #8548 was about alleviating low precision by utilizing high precision input. Same problem, two different solutions. With the summary as it stands, this issue addresses animation specifically: there is no overlap with #8548. A good way to tie them together is with a UX tasklist-style issue.

@perennialmind commented on GitHub (Jan 28, 2021): Obligatory reference to Pavel Fatin's [Scrolling with Pleasure](https://pavelfatin.com/scrolling-with-pleasure/). Scroll _smoothing_ compensates for low precision using animation. #8548 was about alleviating low precision by utilizing high precision input. Same problem, two different solutions. With the summary as it stands, this issue addresses animation specifically: there is no overlap with #8548. A good way to tie them together is with a UX tasklist-style issue.
Author
Owner

@mechite commented on GitHub (Feb 4, 2021):

https://gyazo.com/75806dcc6eceeb640c733769556b1d2a
Sublime Text + Terminus

The best implementation of scrolling in any text editing program, let alone just the terminal plugin.
Implement it like this and you've just boosted your UX super far, scrolling here is beautiful.

@mechite commented on GitHub (Feb 4, 2021): https://gyazo.com/75806dcc6eceeb640c733769556b1d2a Sublime Text + Terminus The best implementation of scrolling in **any** text editing program, let alone just the terminal plugin. Implement it like this and you've just boosted your UX super far, scrolling here is **beautiful**.
Author
Owner

@BartekPog commented on GitHub (Sep 4, 2021):

Hi, was there any update on the issue?

@BartekPog commented on GitHub (Sep 4, 2021): Hi, was there any update on the issue?
Author
Owner

@zadjii-msft commented on GitHub (Sep 7, 2021):

Nope. We'll make sure to update this thread when there is. In the meantime, might I recommend the Subscribe button?
image
That way you'll be notified of any updates to this thread, without needlessly pinging everyone on this thread ☺️

@zadjii-msft commented on GitHub (Sep 7, 2021): Nope. We'll make sure to update this thread when there is. In the meantime, might I recommend the Subscribe button? ![image](https://user-images.githubusercontent.com/18356694/91237459-5cbb0c80-e700-11ea-9347-b9b1ec2813b1.png) That way you'll be notified of any updates to this thread, without needlessly pinging everyone on this thread ☺️
Author
Owner

@zadjii-msft commented on GitHub (Apr 13, 2022):

Notes from around the web:

That PR implements it as a timer that continually scrolls a single line at a time even when the accumulated scroll delta is bigger than that, so the scrolling doesn't happen all at once.

I was more picturing this as a viewport that accepted a floating-point offset, so that we could have a fractional amount of lines at a time. Like, for precision trackpads where you might not always have 100% of a row scrolled.

@zadjii-msft commented on GitHub (Apr 13, 2022): Notes from around the web: * https://github.com/xtermjs/xterm.js/issues/1140 * https://github.com/xtermjs/xterm.js/pull/3616 That PR implements it as a timer that continually scrolls a single line at a time even when the accumulated scroll delta is bigger than that, so the scrolling doesn't happen all at once. I was more picturing this as a viewport that accepted a floating-point offset, so that we could have a fractional amount of lines at a time. Like, for precision trackpads where you might not always have 100% of a row scrolled.
Author
Owner

@j4james commented on GitHub (Apr 14, 2022):

@zadjii-msft As I understand it, the xtermjs issues you linked are regarding mouse-wheel scrolling of the scrollback buffer. This feature request was for smooth scrolling of the terminal output. The simplest case being when you output a line feed at the bottom of the screen, it should smoothly scroll the new line into view.

The complication is that you generally need to be able to render more lines than you actually have in the buffer. For example, if you have a 30 line screen, and you're going to scroll up a line, you'd typically just erase the top line, move everything up by one, and then insert your new content on the bottom line. With smooth scrolling, though, the top line is sliding out of view at the same time as the new bottom line is sliding into view, so you actually need to be rendering 31 lines at the same time.

This is probably not a big deal if you're doing a full screen scroll and you have a scrollback buffer. But it ideally needs to work with margin-based scrolling too, and that becomes trickier. If it's not practical, though, we could probably get away with just letting the top line disappear in those cases. It should still a produce a reasonably nice effect I think.

@j4james commented on GitHub (Apr 14, 2022): @zadjii-msft As I understand it, the xtermjs issues you linked are regarding mouse-wheel scrolling of the scrollback buffer. This feature request was for smooth scrolling of the terminal output. The simplest case being when you output a line feed at the bottom of the screen, it should smoothly scroll the new line into view. The complication is that you generally need to be able to render more lines than you actually have in the buffer. For example, if you have a 30 line screen, and you're going to scroll up a line, you'd typically just erase the top line, move everything up by one, and then insert your new content on the bottom line. With smooth scrolling, though, the top line is sliding out of view at the same time as the new bottom line is sliding into view, so you actually need to be rendering 31 lines at the same time. This is probably not a big deal if you're doing a full screen scroll and you have a scrollback buffer. But it ideally needs to work with margin-based scrolling too, and that becomes trickier. If it's not practical, though, we could probably get away with just letting the top line disappear in those cases. It should still a produce a reasonably nice effect I think.
Author
Owner

@lhecker commented on GitHub (Apr 14, 2022):

That's an excellent point! I think letting partially visible lines simply disappear would look a bit weird. Another pragmatic solution would be to just disable smooth scrolling when margins are set.
Since most of the time you're not using them it should satisfy most use cases.

With AtlasEngine drawing smoothly scrolling content that covers the entire viewport is sufficiently easy thankfully. We could just add another float parameter to the constant buffer between 0 and 1 that is the floating point scroll position modulo 1.0 and shift the entire content up and down by that much.

@lhecker commented on GitHub (Apr 14, 2022): That's an excellent point! I think letting partially visible lines simply disappear would look a bit weird. Another pragmatic solution would be to just disable smooth scrolling when margins are set. Since most of the time you're not using them it should satisfy most use cases. With `AtlasEngine` drawing smoothly scrolling content that covers the entire viewport is sufficiently easy thankfully. We could just add another float parameter to the constant buffer between 0 and 1 that is the floating point scroll position modulo 1.0 and shift the entire content up and down by that much.
Author
Owner

@j4james commented on GitHub (Apr 14, 2022):

Another pragmatic solution would be to just disable smooth scrolling when margins are set.
Since most of the time you're not using them it should satisfy most use cases.

Funnily enough, the only times I've actually seen smooth scrolling deliberately enabled have been with margins also set. The one case was in vttest, which naturally enough has a test of smooth scrolling within margins. The other case was with a set of ASCII Christmas animations, some of which relied on smooth scrolling for effect.

Not that these are critical use cases, but if we are going to the effort of implementing smooth scrolling, it would be nice if it could handle as many of these situations as possible.

And I've just been looking through my terminal collection to see how others are implementing this, and the one example I found was Reflection Desktop, which looks to me like it's letting the top line smoothly scroll out of view, before rendering the new line at the bottom. That seems to work reasonably well.

I also wondered if we could do something similar to the way the original hardware probably worked, where we rely on the fact that the area being scrolled is already in the memory bitmap, so you can scroll most of the bitmap content directly, and just render the new line coming into view. In that case you don't care that the top line is already gone from the buffer. I think we already do something like this for full screen scrolling in the GDI renderer - it would just need to be extended to support arbitrary margin regions. I'm not sure if that approach would be applicable to the DX and Atlas renderers though.

Anyway, none of this is essential for me - I'm just brainstorming ideas.

@j4james commented on GitHub (Apr 14, 2022): > Another pragmatic solution would be to just disable smooth scrolling when margins are set. Since most of the time you're not using them it should satisfy most use cases. Funnily enough, the only times I've actually seen smooth scrolling deliberately enabled have been with margins also set. The one case was in vttest, which naturally enough has a test of smooth scrolling within margins. The other case was with a set of ASCII Christmas animations, some of which relied on smooth scrolling for effect. Not that these are critical use cases, but if we are going to the effort of implementing smooth scrolling, it would be nice if it could handle as many of these situations as possible. And I've just been looking through my terminal collection to see how others are implementing this, and the one example I found was Reflection Desktop, which looks to me like it's letting the top line smoothly scroll out of view, before rendering the new line at the bottom. That seems to work reasonably well. I also wondered if we could do something similar to the way the original hardware probably worked, where we rely on the fact that the area being scrolled is already in the memory bitmap, so you can scroll most of the bitmap content directly, and just render the new line coming into view. In that case you don't care that the top line is already gone from the buffer. I think we already do something like this for full screen scrolling in the GDI renderer - it would just need to be extended to support arbitrary margin regions. I'm not sure if that approach would be applicable to the DX and Atlas renderers though. Anyway, none of this is essential for me - I'm just brainstorming ideas.
Author
Owner

@rbanffy commented on GitHub (Sep 26, 2022):

One thing any smooth scrolling feature needs to account for is the rendering backlog. Physical terminals signalled the computer via the RS-232 signals to stop sending characters when its buffer was full. Windowed terminals don't (or can't) do that. A usability improvement over the behavior of these older machines would be increasing the speed proportionally to the backlog - so that it never takes more than "x" seconds to reach the end of the buffer.

The approach Reflection uses is the same a couple physical terminals I have used rely on - the last line only scrolls into the screen if there is a rendering backlog and other lines to be rendered after it. If there is no backlog, the line shows on the screen (because, usually, it means the user is typing and they'd like to see what is being written.

@rbanffy commented on GitHub (Sep 26, 2022): One thing any smooth scrolling feature needs to account for is the rendering backlog. Physical terminals signalled the computer via the RS-232 signals to stop sending characters when its buffer was full. Windowed terminals don't (or can't) do that. A usability improvement over the behavior of these older machines would be increasing the speed proportionally to the backlog - so that it never takes more than "x" seconds to reach the end of the buffer. The approach Reflection uses is the same a couple physical terminals I have used rely on - the last line only scrolls into the screen if there is a rendering backlog and other lines to be rendered after it. If there is no backlog, the line shows on the screen (because, usually, it means the user is typing and they'd like to see what is being written.
Author
Owner
@zadjii-msft commented on GitHub (Jan 4, 2024): adding notes: https://github.com/microsoft/terminal/assets/18356694/b5eaba75-2580-4dc3-9434-f4ae0a6d37f1 which I got from https://news.ycombinator.com/item?id=38851642, which is about https://flak.tedunangst.com/post/terminal-smooth-scrolling
Author
Owner

@Welding-Torch commented on GitHub (Jan 4, 2024):

@zadjii-msft Lmao, I read the same article on Hacker News and came here to say the exact same thing.

@Welding-Torch commented on GitHub (Jan 4, 2024): @zadjii-msft Lmao, I read the same article on Hacker News and came here to say the exact same thing.
Author
Owner

@knowbits commented on GitHub (Jan 5, 2024):

Yes, please find inspiration in the recent posting by Ted Unangst (OpenBSD).
https://flak.tedunangst.com/post/terminal-smooth-scrolling

@knowbits commented on GitHub (Jan 5, 2024): Yes, please find inspiration in the recent posting by Ted Unangst (OpenBSD). https://flak.tedunangst.com/post/terminal-smooth-scrolling
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#1864