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

Move smooth scroll timers to a separate thread, instead of using SetTimer #4722

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

goodtrailer
Copy link

@goodtrailer goodtrailer commented Dec 16, 2024

Potentially addresses #4122

Note. To avoid confusion, I'm going to refer to middle-click scroll as "auto scroll." And I'm going to refer to smoothly animated/interpolated scrolling (enabled by the SmoothScroll=true config) as "interpolated scroll." In the code, "auto scroll" is referred to as SMOOTHSCROLL, while "interpolated scroll" is referred to as smoothScroll. This could be confusing, which is why I call them "auto scroll" and "interpolated scroll."


Discussion #4122 complains that "auto scroll" is too scratchy, and I noticed that this is possibly because it uses SetTimer(). Also, "interpolated scroll" uses SetTimer() as well. An issue is that SetTimer() allows a minimum of 10ms/100fps (according to the docs, but it seems the true minimum is closer to 16ms/60fps in my testing). Many displays run at much higher than 100Hz (e.g. mine runs at 144Hz), so this results in a very scratchy appearance.

A relatively non-intrusive solution is to replace the timer with a thread (see ScrollTimerThread()) which sends WM_TIMER messages to the canvas window. Since we use our own thread instead of SetTimer(), we can run at the monitor's refresh rate, instead of a capped 10ms/100fps. Note that using this method, not very much code needs changing. We still use WM_TIMER messages, which can be handled in the exact same way as before. The only difference is that instead of SetTimer()/KillTimer(), we have to call SetEvent()/ResetEvent() on an Event object which the thread is waiting on. Also, we have to account for the delta time (Δt) so that scrolling isn't faster/slower depending on refresh rate (i.e. for "auto scroll," a 144Hz monitor and a 60Hz monitor should have the same scroll speed).


This is a draft PR because I just wanted to show a proof-of-concept that improves scrolling on high-refresh displays, in case it is helpful at all. It's not perfect, since WM_TIMER messages are low-priority. But it's relatively simple and non-intrusive, which is why I wanted to bring it up.

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.

1 participant