New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for non-stacking-context scrolling areas #517
Changes from all commits
File filter...
Jump to…
| @@ -301,65 +301,86 @@ impl Frame { | ||
| None => return false, | ||
| }; | ||
|
|
||
| let layer = self.layers.get_mut(&scroll_layer_id).unwrap(); | ||
| if layer.scrolling.started_bouncing_back && phase == ScrollEventPhase::Move(false) { | ||
| return false | ||
| } | ||
| let scroll_root_id = match scroll_layer_id.info { | ||
| ScrollLayerInfo::Scrollable(_, scroll_root_id) => scroll_root_id, | ||
| ScrollLayerInfo::Fixed => unreachable!("Tried to scroll a fixed position layer."), | ||
glennw
Member
|
||
| }; | ||
|
|
||
| let overscroll_amount = layer.overscroll_amount(); | ||
| let overscrolling = CAN_OVERSCROLL && (overscroll_amount.width != 0.0 || | ||
| overscroll_amount.height != 0.0); | ||
| if overscrolling { | ||
| if overscroll_amount.width != 0.0 { | ||
| delta.x /= overscroll_amount.width.abs() | ||
| let mut scrolled_a_layer = false; | ||
| for (layer_id, layer) in self.layers.iter_mut() { | ||
kvark
Member
|
||
| if layer_id.pipeline_id != scroll_layer_id.pipeline_id { | ||
| continue; | ||
| } | ||
| if overscroll_amount.height != 0.0 { | ||
| delta.y /= overscroll_amount.height.abs() | ||
|
|
||
| match layer_id.info { | ||
| ScrollLayerInfo::Scrollable(_, id) if id != scroll_root_id => continue, | ||
| ScrollLayerInfo::Fixed => continue, | ||
| _ => {} | ||
| } | ||
|
|
||
| if layer.scrolling.started_bouncing_back && phase == ScrollEventPhase::Move(false) { | ||
| continue; | ||
| } | ||
|
|
||
| let overscroll_amount = layer.overscroll_amount(); | ||
| let overscrolling = CAN_OVERSCROLL && (overscroll_amount.width != 0.0 || | ||
| overscroll_amount.height != 0.0); | ||
| if overscrolling { | ||
| if overscroll_amount.width != 0.0 { | ||
| delta.x /= overscroll_amount.width.abs() | ||
| } | ||
| if overscroll_amount.height != 0.0 { | ||
| delta.y /= overscroll_amount.height.abs() | ||
| } | ||
| } | ||
| } | ||
|
|
||
| let is_unscrollable = layer.content_size.width <= layer.local_viewport_rect.size.width && | ||
| layer.content_size.height <= layer.local_viewport_rect.size.height; | ||
| let is_unscrollable = | ||
| layer.content_size.width <= layer.local_viewport_rect.size.width && | ||
| layer.content_size.height <= layer.local_viewport_rect.size.height; | ||
|
|
||
| let original_layer_scroll_offset = layer.scrolling.offset; | ||
| let original_layer_scroll_offset = layer.scrolling.offset; | ||
|
|
||
| if layer.content_size.width > layer.local_viewport_rect.size.width { | ||
| layer.scrolling.offset.x = layer.scrolling.offset.x + delta.x; | ||
| if is_unscrollable || !CAN_OVERSCROLL { | ||
| layer.scrolling.offset.x = layer.scrolling.offset.x.min(0.0); | ||
| layer.scrolling.offset.x = | ||
| layer.scrolling.offset.x.max(-layer.content_size.width + | ||
| layer.local_viewport_rect.size.width); | ||
| if layer.content_size.width > layer.local_viewport_rect.size.width { | ||
| layer.scrolling.offset.x = layer.scrolling.offset.x + delta.x; | ||
| if is_unscrollable || !CAN_OVERSCROLL { | ||
| layer.scrolling.offset.x = layer.scrolling.offset.x.min(0.0); | ||
| layer.scrolling.offset.x = | ||
| layer.scrolling.offset.x.max(-layer.content_size.width + | ||
| layer.local_viewport_rect.size.width); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if layer.content_size.height > layer.local_viewport_rect.size.height { | ||
| layer.scrolling.offset.y = layer.scrolling.offset.y + delta.y; | ||
| if is_unscrollable || !CAN_OVERSCROLL { | ||
| layer.scrolling.offset.y = layer.scrolling.offset.y.min(0.0); | ||
| layer.scrolling.offset.y = | ||
| layer.scrolling.offset.y.max(-layer.content_size.height + | ||
| layer.local_viewport_rect.size.height); | ||
| if layer.content_size.height > layer.local_viewport_rect.size.height { | ||
| layer.scrolling.offset.y = layer.scrolling.offset.y + delta.y; | ||
| if is_unscrollable || !CAN_OVERSCROLL { | ||
| layer.scrolling.offset.y = layer.scrolling.offset.y.min(0.0); | ||
| layer.scrolling.offset.y = | ||
| layer.scrolling.offset.y.max(-layer.content_size.height + | ||
| layer.local_viewport_rect.size.height); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if phase == ScrollEventPhase::Start || phase == ScrollEventPhase::Move(true) { | ||
| layer.scrolling.started_bouncing_back = false | ||
| } else if overscrolling && | ||
| ((delta.x < 1.0 && delta.y < 1.0) || phase == ScrollEventPhase::End) { | ||
| layer.scrolling.started_bouncing_back = true; | ||
| layer.scrolling.bouncing_back = true | ||
| } | ||
| if phase == ScrollEventPhase::Start || phase == ScrollEventPhase::Move(true) { | ||
| layer.scrolling.started_bouncing_back = false | ||
| } else if overscrolling && | ||
| ((delta.x < 1.0 && delta.y < 1.0) || phase == ScrollEventPhase::End) { | ||
| layer.scrolling.started_bouncing_back = true; | ||
| layer.scrolling.bouncing_back = true | ||
| } | ||
|
|
||
| layer.scrolling.offset.x = layer.scrolling.offset.x.round(); | ||
| layer.scrolling.offset.y = layer.scrolling.offset.y.round(); | ||
| layer.scrolling.offset.x = layer.scrolling.offset.x.round(); | ||
| layer.scrolling.offset.y = layer.scrolling.offset.y.round(); | ||
|
|
||
| if CAN_OVERSCROLL { | ||
| layer.stretch_overscroll_spring(); | ||
| if CAN_OVERSCROLL { | ||
| layer.stretch_overscroll_spring(); | ||
| } | ||
|
|
||
| scrolled_a_layer = scrolled_a_layer || | ||
| layer.scrolling.offset != original_layer_scroll_offset || | ||
| layer.scrolling.started_bouncing_back; | ||
| } | ||
|
|
||
| layer.scrolling.offset != original_layer_scroll_offset || layer.scrolling | ||
| .started_bouncing_back | ||
| scrolled_a_layer | ||
| } | ||
|
|
||
| pub fn tick_scrolling_bounce_animations(&mut self) { | ||
| @@ -496,13 +517,26 @@ impl Frame { | ||
| } | ||
| } | ||
|
|
||
| // Build world space transform | ||
| let transform = parent_info.layer_relative_transform.pre_translated(stacking_context.bounds.origin.x, | ||
| stacking_context.bounds.origin.y, | ||
| 0.0) | ||
| .pre_mul(&stacking_context.transform) | ||
| .pre_mul(&stacking_context.perspective); | ||
| // Stacking contexts with scroll roots are currently not "real" stacking contexts, | ||
| // but are currently represented as stacking contexts in the display list until they | ||
| // can get their own display item to represent them. Thus we do not adjust the transform | ||
| // to account for them and we expand the overflow region to include the area above | ||
| // their origin in the parent context. | ||
| let (transform, overflow) = if stacking_context.scroll_layer_id.is_none() { | ||
| (parent_info.layer_relative_transform.pre_translated(stacking_context.bounds.origin.x, | ||
| stacking_context.bounds.origin.y, | ||
|
||
| 0.0) | ||
| .pre_mul(&stacking_context.transform) | ||
| .pre_mul(&stacking_context.perspective), | ||
| stacking_context.overflow) | ||
| } else { | ||
| let mut overflow = stacking_context.overflow; | ||
| overflow.size.width += stacking_context.bounds.origin.x; | ||
| overflow.size.height += stacking_context.bounds.origin.y; | ||
| (parent_info.layer_relative_transform, overflow) | ||
| }; | ||
|
|
||
| // Build world space transform | ||
| let scroll_layer_id = match (stacking_context.scroll_policy, stacking_context.scroll_layer_id) { | ||
| (ScrollPolicy::Fixed, _scroll_layer_id) => { | ||
| debug_assert!(_scroll_layer_id.is_none()); | ||
| @@ -518,8 +552,8 @@ impl Frame { | ||
| }; | ||
|
|
||
| // TODO(gw): Int with overflow etc | ||
| context.builder.push_layer(stacking_context.overflow, | ||
| stacking_context.overflow, | ||
| context.builder.push_layer(overflow, | ||
| overflow, | ||
| transform, | ||
| pipeline_id, | ||
| scroll_layer_id, | ||
should it do
return falseinstead?