linebender / linebender/druid

Scroll refinements

Open
#73 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

discussion write-up
Dominant language
Rust
Stars
9.7k
Forks
565
PR merge metrics
No merged PRs in 30d

Description

This issue is a continuation of the review discussion for #69, which was a very basic scroll container, and describes some refinements that would be nice.

The easiest is probably scroll bars. Right now, there's no visual indication of scroll position. It would be pretty straightforward to draw those on top of the content, and not all that hard to wire up the click-drag gesture. I'd consider this "help wanted."

Of course, the scroll bars need to be subject to styling. This is a much deeper question, which we might get back to in a while. In the meantime, I think it makes sense to start to develop a default theme (at first hardcoded), and focus on making that not-so-terrible.

There's a cluster of issues around dynamics, listed in the review as "momentum and bounce." These require animation frames, which is currently not wired. I'd like to do something similar the "request_anim_frame" mechanism in old druid, but in any case that needs to happen before we can add things to this widget.

I think momentum is handled by the system on macOS. It seems to deliver a series of events to the app. We can get more metadata, including the [momentum phase](https://developer.apple.com/documentation/appkit/nsevent/1525439-momentumphase) (this would allow us to turn off momentum by suppressing events), but I'm not sure how important this is. I believe on Windows momentum is not considered idiomatic. (For reference, see [Handling Trackpad Events](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/EventOverview/HandlingTouchEvents/HandlingTouchEvents.html) in the Cocoa docs, as the full range of trackpad gestures is extremely rich)

Bounce is legit, though, and I think can just be configured at widget creation time. It requires animation frames.

I'd *also* like to do smoothing, but this is something of a deeper question. This breaks down into two sub-issues. First, sometimes you get a discrete scrolling bump (for example from the scroll wheel, but also potentially from the content) and want to animate that out. Second, even more or less continuous sources of scroll deltas (trackpads) are noisy, with quantization both in time and value. For the latter, I think doing smoothing can improve the overall feel of the app. I'd like to do something very similar to the [midi smoothing](https://github.com/raphlinus/synthesizer-io/blob/master/synthesizer-io-core/src/modules/smooth_ctrl.rs) in synthesizer.io, but no doubt this will require some fine-tuning of parameters to make sure it feels good. (As a sub-issue, I'd also like druid-shell to have a more precise, jitter suppressed timebase for animation events, right now it just measures wall clock at event processing time - this should probably also be tracked by an issue because I'm not sure when I'm going to get to it).

Related to the above, the content window should also be able to request scrolling, for example in a text editor. I think an appropriate mechanism for this is to have an `Action` that's propagated up in the event flow. Similarly, the scroll offset can be propagated down as part of the environment. (Digression - in the design I'm currently contemplating, this will cause a flurry of `update` calls for all the descendants of the scroll container whenever the content is scrolled. I'm thinking maybe we have a way for widgets to indicate their interest in particular data sources)

I need a little convincing that we need "principal axis scrolling." In my experimentation, many of the problems with this on xi-mac come from poor scroll dynamics, where (for example) on a momentum flick the scrolling continues without being clamped by the app. Setting principal axis scrolling fixes this, by effectively quantizing the angle of the scroll, but I'm not sure it's the absolute best solution. That said, I just checked VS Code and Sublime Text on Windows, and it is the default scroll behavior there. I think I'd be happiest with it as an option but not the default (like bounce).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the basic scroll container from issue #69 and the review discussion referenced here. The issue lists scroll bars, animation frames, momentum, bounce, smoothing, content-requested scrolling, and principal-axis scrolling, but names no files, tests, or single implementation target. A contributor would first need maintainers to choose one refinement and define its completion criteria.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
frontend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.