Skip to content

feat: Autoscroll with the middle mouse button on desktop - #1169

Merged
PartyDonut merged 3 commits into
DonutWare:developfrom
MrRussLuther:feat/middle-mouse-autoscroll
Oct 18, 2026
Merged

PartyDonut merged 3 commits into
DonutWare:developfrom
MrRussLuther:feat/middle-mouse-autoscroll

Conversation

@MrRussLuther

@MrRussLuther MrRussLuther commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Pull Request Description

Browser-style autoscroll for the middle mouse button on desktop, as described in #1156. Hold the middle button and a small marker appears where you pressed. Move the mouse away from it and the view scrolls that way, faster the further you move. Let go and it stops. It works on both axes at once, so on the series page the episode row scrolls sideways while the page scrolls down in one motion.

How it fits together:

  • FladderScrollBehavior replaces the stock MaterialScrollBehavior in main.dart and wraps every scrollable in a MiddleMouseAutoscroll listener, so nothing changes in individual widgets. On web it returns the stock scrollbar untouched, since the browser already does this.
  • Pointer events reach listeners innermost first, so the first scrollable that can scroll on a given axis claims it for that press. That is how the nearest horizontal and the nearest vertical scrollable under the cursor end up moving together.
  • One shared session per press holds the origin, the claimed axes, a Ticker and the marker OverlayEntry. Each tick scrolls every claimed axis by speed * dt through ScrollPosition.pointerScroll, so the existing physics clamp it at the extents. Speed is 6 px/s per pixel the pointer sits past an 8 px dead zone, capped at 3000 px/s. Reversed axes (RTL rows) are handled, so the content always moves towards the pointer.
  • Releasing the button, or the middle button going up while another is still held, disposes the ticker and removes the marker. A stray middle click just flashes the marker and moves nothing.

It takes over no gestures: left click, taps and "Drag using mouse" behave as before. There is no click-to-toggle mode like browsers have, only hold. If you'd rather have this behind a setting next to "Drag using mouse", I'm happy to add that.

test/middle_mouse_autoscroll_test.dart covers scrolling towards the pointer on both axes, stopping on release, speed growing with distance, the dead zone, the stray click, holding outside the row, clamping, RTL rows, and the primary button being left alone.

Issue Being Fixed

Discussion #1156. With a mouse, long horizontal rows mean the arrow buttons or shift+scroll one direction at a time, and long grids mean a lot of wheel spinning.

Screenshots / Recordings

Holding the middle button over a row on the dashboard and moving the mouse to the right. The row scrolls sideways, the marker sits where the button was pressed, and it stops on release. Moving diagonally scrolls the page at the same time.

Middle mouse autoscroll on a dashboard row

Tested On

  • Android
  • Android TV
  • iOS
  • Linux
  • Windows
  • macOS
  • Web

Checklist

  • If a new package was added, did you ensure it works for all supported platforms? Is the package well maintained (no new packages)
  • Check that any changes are related to the issue at hand.

Holding the middle button marks an origin and scrolls the nearest horizontal and vertical
scrollable under the pointer towards wherever the pointer is relative to it, faster the
further away, until the button is released. A small marker shows the origin and a dead zone
around it stops small hand movements from drifting the view. Hooked in through the app
ScrollBehavior so it covers every scroll view. Primary button drag, taps and the mouse drag
setting are unaffected. Disabled on web, where the browser has its own autoscroll.
MrRussLuther added a commit to MrRussLuther/Fladder that referenced this pull request Oct 13, 2026

@PartyDonut PartyDonut left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM. Good improvement.

I removed the test as we probably don't need it for this.

@PartyDonut
PartyDonut merged commit 715873a into DonutWare:develop Oct 18, 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.

2 participants