Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: scrollbar thumb not visible on long lists #959

Merged
merged 5 commits into from Feb 20, 2024

Conversation

ThomasMiz
Copy link
Contributor

The problem

When displaying somewhat-long lists, the Scrollbar widget might not display a single thumb character, and only the track will be visible. Here are some GIFs showing the issue:
before_vertical
before_horizontal

The code to reproduce this issue was based off the scrollbar example and can be found in this pastebin.

This PR

I fixed this issue by converting the logic in the part_lengths function to use integer calculations instead of floating-point (the only reason for the use of floating point seemed to be the rounding after division, which can be done in integers by replacing (a / b).round() as usize with (a + b/2) / b) and then doing a bit of clamping. The result of the previous test is as shown in these GIFs:
after_vertical
after_horizontal

@ThomasMiz ThomasMiz changed the title Fix scrollbar thumb not visible on long lists fix: scrollbar thumb not visible on long lists Feb 18, 2024
Copy link

codecov bot commented Feb 18, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (b0314c5) 91.9% compared to head (ca183b7) 91.9%.

Additional details and impacted files
@@          Coverage Diff          @@
##            main    #959   +/-   ##
=====================================
  Coverage   91.9%   91.9%           
=====================================
  Files         61      61           
  Lines      15723   15729    +6     
=====================================
+ Hits       14456   14462    +6     
  Misses      1267    1267           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@ThomasMiz
Copy link
Contributor Author

A small thing to note about the pastebin code that should probably be fixed in the examples are lines 55-57:

if key.kind == KeyEventKind::Release {
    continue;
}

Otherwise, on Windows terminals, all events get registered twice

@Valentin271
Copy link
Member

Yep can confirm I reproduce. Though important to note this happens in large lists and somewhat small terminal sizes. My fullscreen terminal at 191x46 works fine but 80x27 does not.

@ThomasMiz
Copy link
Contributor Author

Yep can confirm I reproduce. Though important to note this happens in large lists and somewhat small terminal sizes. My fullscreen terminal at 191x46 works fine but 80x27 does not.

My use case, the reason I found this, is because I have a list of up to 64k log events
image

Copy link
Member

@Valentin271 Valentin271 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me but I'd like another review.

I had a few comments but definitely non-blocking for me.

src/widgets/scrollbar.rs Outdated Show resolved Hide resolved
Copy link
Member

@joshka joshka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also just hit this bug in an app I'm writing.

I'd like to see one or more tests for this that show the problem (make sure they fail on the previous code before the fix is applied)

src/widgets/scrollbar.rs Outdated Show resolved Hide resolved
@ThomasMiz
Copy link
Contributor Author

I'd like to see one or more tests for this that show the problem (make sure they fail on the previous code before the fix is applied)

With commit 8baebda I've added tests to check that the thumb is visible. I've tested the previous code, which fails the tests due do no thumb rendering in some cases, and the new code from this PR, which passes the tests.

Copy link
Member

@joshka joshka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the unit test here - that makes it really easy to confirm that the solution works.

I've provided an alternative approach than keeping things as integers as I think it's genuinely easier to understand.

  • used clamp instead of min / max as it's easy to mistake x.min(2) for being at least 2 instead of at most
  • renamed variables and added a few intermediate variables to help make the calculations more obvious
  • cleaned up the comments
  • arranged the parts of the method so that each section is a bit more self-cohesive

src/widgets/scrollbar.rs Outdated Show resolved Hide resolved
src/widgets/scrollbar.rs Show resolved Hide resolved
Copy link
Member

@joshka joshka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Valentin271 can you take another quick look over this please / @kdheepak ?

Copy link
Member

@Valentin271 Valentin271 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fine by me, I don't mind keeping floats and the code is much easier to understand now 👍

Copy link
Sponsor Member

@orhun orhun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM as well

@Valentin271 Valentin271 merged commit 35e971f into ratatui-org:main Feb 20, 2024
33 checks passed
EdJoPaTo added a commit to EdJoPaTo/ratatui-binary-data-widget that referenced this pull request Feb 22, 2024
Requires ratatui-org/ratatui#959 to be useful with larger binary data like the default in the example
ThomasMiz added a commit to ThomasMiz/dust-devil that referenced this pull request Feb 23, 2024
The thumb not displaying thing is an issue with ratatui's scrollbar widget, which I've also fixed upstream (ratatui-org/ratatui#959) but the positioning is calculated for a different type of scrolling (and I also don't want to wait for the next release).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants