Skip to content

Mac overscroll#320

Merged
john-preston merged 2 commits into
desktop-app:masterfrom
teidesu:mac-overscroll
Jul 16, 2026
Merged

Mac overscroll#320
john-preston merged 2 commits into
desktop-app:masterfrom
teidesu:mac-overscroll

Conversation

@teidesu

@teidesu teidesu commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

full disclosure: i wrote exactly zero lines of code myself, but i reviewed and tested the changes thoroughly (i think (maybe))

ok so overscroll behavior currently implemented in ElasticScroll feels very bad and i asked fable to port the chromium(blink) macos overscroll implementation over here.

that alone already improved things a lot, but then we also reworked the pull-action stuff (pull-to-next-channel in history and pull-to-stories in chat list), making them feel a lot nicer and more responsive - instead of the log curve it was using.

currently all changes are gated behind Q_OS_MACOS (because i dont have any win/linux device to test them), but most of them should be portable and work on other platforms with little to no changes. (however kinetic scrolling on both linux and windows needs extra care i believe)

note: the changes in the lib_ui are just the "core" and require some slight changes in the actual consumers of the main app - see telegramdesktop/tdesktop#30990

before/after (videos dont really do justice, it should be compared side-by-side with an actual trackpad, but i tried my best):

chatlist-overflow-before.mov
chatlist-overflow-after.mov
history-overflow-before.mov
history-overflow-after.mov
pull-to-channel-before.mov
pull-to-channel-after.mov

teidesu added 2 commits July 15, 2026 20:37
Match the WebKit / Chromium rubber-band behavior
(blink::ElasticOverscrollControllerExponential), which replicates
the native macOS feel, on Real overscroll sides:

- Linear stretch (accumulated overscroll / 20) while dragging,
instead of the log curve whose initial slope exceeded 1 and then
saturated abruptly.
- A minimum of 10px of accumulated overscroll before the stretch
starts, so stray motions at the edge don't jiggle the content.
- Scroll velocity tracking from wheel event timestamps (processing
times inflate the velocity when queued momentum events arrive
back-to-back after a main thread stall), clamped to a plausible
trackpad maximum.
- A critically damped spring return
x(t) = (x0 + v0 * amplitude * t) * e^(-stiffness * t / period)
seeded with the release velocity, replacing the fixed-duration
sineInOut tween: flings into an edge now bounce proportionally to
their speed.
- Once the spring owns the stretch the rest of the momentum stream
is ignored instead of feeding the overscroll accumulator, removing
the plateau-and-hang at the edge.
- Scrolling away from the stretch consumes it 1:1 (Chromium's
ReconcileStretchAndScroll) instead of unwinding through the force
mapping, which would glue the view to the edge for
(stiffness * stretch) of input travel after a canceled bounce.

Virtual overscroll sides keep the legacy behavior. Everything is
gated under Q_OS_MAC.
Pull sides (the stories strip in the chat list, the pull to the next
channel in the chat history) follow the finger with a soft linear
stiffness over a configurable pull distance and continue with the
plain bounce stiffness beyond it. The stretch mapping is one curve
anchored at zero, so collapsing from an expanded overscroll default
re-traverses the soft range, and momentum flings keep retracting the
pull instead of bouncing back to the default. Virtual overscroll also
squishes the scrollbar thumb the way Real overscroll does.
@CLAassistant

CLAassistant commented Jul 15, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

const auto distance = (side < 0)
? _overscrollPullFrom
: _overscrollPullTill;
return distance ? float64(distance) : 1e9;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

1e9 is good enough to be placed in constexpr as well.

@23rd

23rd commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

The comments are too wordy and verbose.

@gearonixx

Copy link
Copy Markdown

I can reproduce the same overshoot on Linux x86_64 with the QScroller option enabled.

@gearonixx

Copy link
Copy Markdown

PR: telegramdesktop/tdesktop#30991

@john-preston

Copy link
Copy Markdown
Collaborator

Thanks

@john-preston john-preston merged commit a6a39ec into desktop-app:master Jul 16, 2026
1 check passed
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.

5 participants