Skip to content

Add scrollbar for desktop devices - #4620

Open
xkello wants to merge 4 commits into
masterfrom
feature/add-scrollbar-for-desktop-lists
Open

Add scrollbar for desktop devices#4620
xkello wants to merge 4 commits into
masterfrom
feature/add-scrollbar-for-desktop-lists

Conversation

@xkello

@xkello xkello commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Description

Adds a proper scrollbar for desktop builds. Mobile builds rely on touch/flick scrolling and never had or needed a visible scrollbar, but on desktop there was no scroll indicator at all, and once turned on in ScrollView it was drawn over the left side of content instead of reserving space for itself. ListView based lists had no scrollbar handling at all, so the same content-overlap problem applied there too, across many pages.

Fixes: #4127
Original PR: #4145

Problem

The obvious first approach was to just declare ScrollBar.vertical directly on the shared MMListView component, since ListView/Flickable auto-positions an attached scrollbar correctly on its own. The problem is that a ListView's scrollbar is drawn as an overlay on top of its content - Flickable has no concept of padding the way a Control does, so there's nothing built in to reserve space for it.

In practice, that meant every delegate, header, footer, and section-delegate across the ~17 different lists in the app would need to know a scrollbar might be there and manually subtract its width from their own sizing to avoid being drawn underneath it. That's a lot of duplicated logic to keep in sync, easy to miss in a new or existing list, and it still didn't cover every case cleanly (e.g. footers/section headers don't automatically inherit a delegate's width-adjustment logic, so each one needed the same fix repeated separately). Wrapping each list in MMScrollView instead moves that reservation into one real padding value on a Control, so no list, delegate, or header needs to know a scrollbar exists at all.

What changed

  • Added rightPadding to the shared MMScrollView component so the scrollbar reserves its own space instead of overlapping content, headers, footers, etc.
  • Wrapped every ListView in the app (via the shared MMListView component) in MMScrollView, rather than handling scrollbars per-list. ScrollView is able to reuse a ListView as its own scrollable content directly, so this didn't require a rewrite of any list, just a wrapper, and now every list in the app shares the exact same scrollbar behavior and styling from one place instead of duplicating it.
  • The scrollbar now only appears on desktop builds. Mobile keeps its normal touch/flick scrolling untouched - only the visible scrollbar and its reserved padding are suppressed there.

Behaviour

Desktop - scrollbar visible, correctly positioned on the right edge, content no longer drawn underneath it:

image image

Desktop - scrollbar hides and shows as needed:

Screencast.From.2026-07-22.18-38-09.webm

Mobile — no scrollbar shown, touch scrolling behaves exactly as before:

Screenshot_20260722-183046 Screenshot_20260722-183117

@xkello xkello added this to the 2026.4.0 milestone Jul 22, 2026
@xkello
xkello requested review from Withalion and tomasMizera July 22, 2026 16:49

@Withalion Withalion 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.

Okay, so I'm not against the approach you chose it sounds good. However the idea is that if you are using MMListView component you are not supposed to know/care that it's a ListView wrapped in ScrollView or that you need to wrap it again in ScrollView. The API for MMListView should stay the same and if necessary the component needs to deal with scrollbar internally.

@xkello

xkello commented Aug 25, 2026

Copy link
Copy Markdown
Contributor Author

Okay, so I'm not against the approach you chose it sounds good. However the idea is that if you are using MMListView component you are not supposed to know/care that it's a ListView wrapped in ScrollView or that you need to wrap it again in ScrollView. The API for MMListView should stay the same and if necessary the component needs to deal with scrollbar internally.

Fair point, didn't think of this. Reverted files to their master version and updated MMListView. Had to add some properties as QMLs ScrollView does not support those.

@xkello
xkello requested a review from Withalion August 25, 2026 10:50
@github-actions

Copy link
Copy Markdown

Coverage Report for CI Build 32839190682

Warning

No base build found for commit 9ce25cb on master.
Coverage changes can't be calculated without a base build.
If a base build is processing, this comment will update automatically when it completes.

Coverage: 59.074%

Details

  • Patch coverage: No coverable lines changed in this PR.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

Requires a base build to compare against. How to fix this →


Coverage Stats

Coverage Status
Relevant Lines: 15704
Covered Lines: 9277
Line Coverage: 59.07%
Coverage Strength: 97.67 hits per line

💛 - Coveralls

@github-actions

Copy link
Copy Markdown

📦 Build Artifacts Ready

OS Status Build Info Workflow run
macOS Build Build failed or not found. #7208
linux Build 📬 Mergin Maps 72341 x86_64 Expires: 23/11/2026 #7234
win64 Build 📬 Mergin Maps 64101 win64 Expires: 23/11/2026 #6410
Android Build 📬 Mergin Maps 851911 APK [armeabi-v7a] Expires: 23/11/2026 #8519
📬 Mergin Maps 851911 APK [armeabi-v7a] Google Play Store #8519
Android Build 📬 Mergin Maps 851951 APK [arm64-v8a] Expires: 23/11/2026 #8519
📬 Mergin Maps 851951 APK [arm64-v8a] Google Play Store #8519
iOS Build 📬 Build number: 26.08.946011 #9460

@Withalion Withalion removed this from the 2026.4.0 milestone Aug 25, 2026

@Withalion Withalion 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.

MMFormPage layout is broken. In MMFormGalleryEditor there should be some spacing between the photos and scrollbar, currently the scrollbar overlays the photos. MMProjectStatusPage not every element inside the MMListView gets it's width updated when scrollbar appears. Scrollbar is doing some weird things in MMChangelogPage, but it might be due to how the content is loaded.

There is a check in code_style.yml called no_stackview, which checks if there is any occurrence of StackView component in our code and throws error if it finds something. Make similar checks for ListView and Scrollview, fix any issues it finds so your PR will be complaint.

The approach looks good!

Comment thread app/qml/components/MMListView.qml

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.

I'm thinking about wrapping the ScrollView in another Item and expose just that, so if used people won't accidentally modify ScrollView property instead of expected Listview property

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm thinking about wrapping the ScrollView in another Item and expose just that, so if used people won't accidentally modify ScrollView property instead of expected Listview property

Yeah, you're right.

ScrollView already carries contentWidth/spacing/padding (inherited from Pane/Control), so exposing it directly on MMListView means someone could set one of those thinking they're touching the real ListView, and get silently routed to the wrapper's own copy instead. Already hit this with spacing - Control.spacing is FINAL so I couldn't even alias around it.

Fix: root MMListView in a plain Item instead of ScrollView. Item is the base class Control/Pane/ScrollView build on top of, so it doesn't carry any of that - only what we explicitly alias gets exposed.

@xkello

xkello commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

MMFormPage layout is broken. In MMFormGalleryEditor there should be some spacing between the photos and scrollbar, currently the scrollbar overlays the photos. MMProjectStatusPage not every element inside the MMListView gets it's width updated when scrollbar appears. Scrollbar is doing some weird things in MMChangelogPage, but it might be due to how the content is loaded.

There is a check in code_style.yml called no_stackview, which checks if there is any occurrence of StackView component in our code and throws error if it finds something. Make similar checks for ListView and Scrollview, fix any issues it finds so your PR will be complaint.

The approach looks good!

Thanks, went through all of these.

MMFormPage/toolbar layout - fixed. Turned out to be MMToolbar leaving a stale button behind when it swaps models on state change (readOnly -> edit); deferred the rebuild with Qt.callLater so old delegates finish clearing first.

MMFormGalleryEditor scrollbar overlay - fixed, photos now reserve space for the scrollbar instead of sitting under it.

MMProjectStatusPage width not updating - fixed. A few items were children of a ColumnLayout using a plain width: binding instead of Layout.fillWidth, which ColumnLayout doesn't reliably honor.

MMChangelogPage - left as is for now. Looks like it's from ListView estimating content height for off-screen items with variable-length descriptions, not something specific to this PR.

Added no_listview/no_scrollview checks to code_style.yml alongside no_stackview, and fixed the four raw ScrollView usages they caught (ListView was already clean).

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown

📦 Build Artifacts Ready

OS Status Build Info Workflow run
macOS Build 📬 Mergin Maps 72551 dmg Expires: 30/11/2026 #7255
linux Build Build failed or not found. #7281
win64 Build 📬 Mergin Maps 64571 win64 Expires: 30/11/2026 #6457
Android Build 📬 Mergin Maps 856551 APK [arm64-v8a] Expires: 30/11/2026 #8565
📬 Mergin Maps 856551 APK [arm64-v8a] Google Play Store #8565
Android Build 📬 Mergin Maps 856511 APK [armeabi-v7a] Expires: 30/11/2026 #8565
📬 Mergin Maps 856511 APK [armeabi-v7a] Google Play Store #8565
iOS Build 📬 Build number: 26.09.950711 #9507

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.

Add scrollbar for desktop builds in lists

2 participants