Make overlay scrollbar thumbs draggable, with hover/active styling#462
Closed
UMCEKO wants to merge 3 commits into
Closed
Make overlay scrollbar thumbs draggable, with hover/active styling#462UMCEKO wants to merge 3 commits into
UMCEKO wants to merge 3 commits into
Conversation
…ree order Two paint-order fixes in flush_styles_to_layout's paint_children sort: 1. position_to_order put relative/sticky at the in-flow level (0) and absolute/fixed above it (2), so an earlier abspos sibling painted above a later relative sibling. Per CSS 2.1 Appendix E step 8 all positioned descendants with z-index: auto share one paint level and paint in tree order among themselves, above in-flow content. The hero-banner pattern (abspos inset-0 image layer + relative content overlay) rendered only the image. 2. Flex/grid items ignored position entirely (the sort key was just `order`), and z-index was only honored for non-static children — but z-index applies to static flex/grid items too (css-flexbox-1 "painting", css-grid-1 "z-order"). The sort key is now (paint level, order-modified position) and static flex/grid items with z-index are hoisted into the stacking context. Pixel-level tests in packages/blitz-html/tests/paint_order.rs (render via anyrender_vello_cpu, assert center pixel). WPT css-grid + css-flexbox: 0 regressions, new passes: flexbox-items-as-stacking-contexts-002 (its REFERENCE page depends on fix 1; it previously passed because both pages rendered identically wrong), flex-item-z-ordering-001/002, grid-z-axis-ordering-001/002/003, positioned-grid-items-020/021, positioned-grid-items-negative-indices-003.
blitz previously never painted scrollbars: an overflow: auto/scroll container gave no visual indication that it scrolls or where within the content the viewport sits. Draw an overlay thumb (no reserved gutter, so no layout change) per overflowing axis: always for overflow: scroll, only when the content overflows for overflow: auto, never for hidden/clip (programmatic-only scrolling). Geometry derives from Layout::scroll_width/scroll_height and node.scroll_offset; the thumb is drawn unscrolled, above the clipped content, inside the opacity/filter layer. Like other overlay scrollbar UIs (macOS, Firefox on Linux), thumbs only appear while the scroll container is hovered or scrolled away from the origin. Beyond matching platform conventions this keeps thumbs out of static reftest screenshots: an always-visible variant regressed 10 WPT overflow reftests whose reference pages cannot scroll; the hover/scroll rule regresses none. Pixel-level tests in packages/blitz-html/tests/scrollbars.rs. Not yet implemented: thumb hit-testing/dragging, css-scrollbars-1 styling (scrollbar-width/scrollbar-color), and show/hide fade animations.
Thumb geometry moves from blitz-paint into a shared helper on Node (scrollbar_thumb / wants_scrollbar / scrollbar_drag_ratio) so painting and hit testing cannot drift; blitz-paint now consumes it. Pointer handling gains a DragMode::ScrollbarDrag state: on pointerdown the layout ancestor chain of the hit node is walked for a scroll container whose thumb contains the pointer (the hit test returns the content under the overlay thumb; helper shared with hover tracking). While dragging, pointer movement maps thumb px to content px via the track ratio and scrolls through the existing clamped scroll_by path (negated: scroll_by uses wheel-delta semantics). Scrollbar drags are not dispatched to the page, and the existing DragMode handling suppresses the synthetic click on release. The document also tracks which thumb the pointer is over (hovered_scrollbar, repainting on change), and the painter renders three thumb states: normal, hovered, and dragged — a dragged thumb also stays visible if the pointer leaves the container mid-drag. Tests in packages/blitz-html/tests/scrollbar_drag.rs drive the EventDriver with synthetic pointer events: thumb drags scroll proportionally and clamp at the track end; content drags don't scroll; hover and drag visibly restyle the thumb.
Contributor
Author
|
Folded into #461 — painting and dragging are one feature; keeping them as two commits in a single PR instead of a 3-deep stack. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #461 (contains its commit; will rebase once it lands).
Makes the overlay scrollbar thumbs from #461 interactive:
Node(scrollbar_thumb/wants_scrollbar/scrollbar_drag_ratio) so painting and hit testing cannot drift; blitz-paint consumes it.DragMode::ScrollbarDragstate: on pointerdown the layout ancestor chain of the hit node is walked for a scroll container whose thumb contains the pointer (the hit test returns the content under the overlay thumb; the helper is shared with hover tracking). While dragging, pointer movement maps thumb px to content px via the track ratio and scrolls through the existing clampedscroll_bypath. Scrollbar drags are not dispatched to the page, and the existingDragModehandling suppresses the synthetic click on release.hovered_scrollbar, repainting on change), and the painter renders three thumb states: normal, hovered, dragged — a dragged thumb also stays visible if the pointer leaves the container mid-drag.Tests in
packages/blitz-html/tests/scrollbar_drag.rsdrive theEventDriverwith synthetic pointer events: thumb drags scroll proportionally and clamp at the track end; content drags don't scroll; hover and drag visibly restyle the thumb.