Differentiate clearly how child layers handle scroll events

This allows the scroll handler to know if a child layer didn't handle
an event or the scroll position of the child layer was simply unchanged.
This commit is contained in:
Martin Robinson 2014-09-23 16:38:52 -07:00
parent 80433f7ea0
commit e01c5cd863
2 changed files with 28 additions and 13 deletions

View file

@ -9,6 +9,7 @@ use compositor_task::{SetLayerOrigin, Paint, ScrollFragmentPoint, LoadComplete};
use compositor_task::{ShutdownComplete, ChangeRenderState, RenderMsgDiscarded}; use compositor_task::{ShutdownComplete, ChangeRenderState, RenderMsgDiscarded};
use constellation::SendableFrameTree; use constellation::SendableFrameTree;
use events; use events;
use events::ScrollPositionChanged;
use pipeline::CompositionPipeline; use pipeline::CompositionPipeline;
use platform::{Application, Window}; use platform::{Application, Window};
use windowing; use windowing;
@ -766,7 +767,7 @@ impl IOCompositor {
delta, delta,
cursor.as_f32(), cursor.as_f32(),
window_size, window_size,
scene_scale) || scroll; scene_scale) == ScrollPositionChanged;
} }
None => { } None => { }
} }

View file

@ -39,6 +39,13 @@ impl Clampable for f32 {
} }
} }
#[deriving(PartialEq)]
pub enum ScrollEventResult {
ScrollEventUnhandled,
ScrollPositionChanged,
ScrollPositionUnchanged,
}
/// Move the layer's descendants that don't want scroll events and scroll by a relative /// Move the layer's descendants that don't want scroll events and scroll by a relative
/// specified amount in page coordinates. This also takes in a cursor position to see if the /// specified amount in page coordinates. This also takes in a cursor position to see if the
/// mouse is over child layers first. If a layer successfully scrolled, returns true; otherwise /// mouse is over child layers first. If a layer successfully scrolled, returns true; otherwise
@ -48,11 +55,11 @@ pub fn handle_scroll_event(layer: Rc<Layer<CompositorData>>,
cursor: TypedPoint2D<DevicePixel, f32>, cursor: TypedPoint2D<DevicePixel, f32>,
window_size: TypedSize2D<DevicePixel, f32>, window_size: TypedSize2D<DevicePixel, f32>,
scale: ScaleFactor<PagePx, DevicePixel, f32>) scale: ScaleFactor<PagePx, DevicePixel, f32>)
-> bool { -> ScrollEventResult {
// If this layer doesn't want scroll events, neither it nor its children can handle scroll // If this layer doesn't want scroll events, neither it nor its children can handle scroll
// events. // events.
if layer.extra_data.borrow().wants_scroll_events != WantsScrollEvents { if layer.extra_data.borrow().wants_scroll_events != WantsScrollEvents {
return false return ScrollEventUnhandled;
} }
// Allow children to scroll. // Allow children to scroll.
@ -61,13 +68,15 @@ pub fn handle_scroll_event(layer: Rc<Layer<CompositorData>>,
let new_cursor = cursor - scroll_offset_in_device_pixels; let new_cursor = cursor - scroll_offset_in_device_pixels;
for child in layer.children().iter() { for child in layer.children().iter() {
let child_bounds = child.bounds.borrow(); let child_bounds = child.bounds.borrow();
if child_bounds.contains(&new_cursor) && if child_bounds.contains(&new_cursor) {
handle_scroll_event(child.clone(), let result = handle_scroll_event(child.clone(),
delta, delta,
new_cursor - child_bounds.origin, new_cursor - child_bounds.origin,
child_bounds.size, child_bounds.size,
scale) { scale);
return true if result != ScrollEventUnhandled {
return result;
}
} }
} }
@ -81,7 +90,7 @@ pub fn clamp_scroll_offset_and_scroll_layer(layer: Rc<Layer<CompositorData>>,
new_offset: TypedPoint2D<DevicePixel, f32>, new_offset: TypedPoint2D<DevicePixel, f32>,
window_size: TypedSize2D<DevicePixel, f32>, window_size: TypedSize2D<DevicePixel, f32>,
scale: ScaleFactor<PagePx, DevicePixel, f32>) scale: ScaleFactor<PagePx, DevicePixel, f32>)
-> bool { -> ScrollEventResult {
let layer_size = layer.bounds.borrow().size; let layer_size = layer.bounds.borrow().size;
let min_x = (window_size.width - layer_size.width).get().min(0.0); let min_x = (window_size.width - layer_size.width).get().min(0.0);
let min_y = (window_size.height - layer_size.height).get().min(0.0); let min_y = (window_size.height - layer_size.height).get().min(0.0);
@ -91,7 +100,7 @@ pub fn clamp_scroll_offset_and_scroll_layer(layer: Rc<Layer<CompositorData>>,
let new_offset_in_page_px = new_offset / scale; let new_offset_in_page_px = new_offset / scale;
if layer.extra_data.borrow().scroll_offset == new_offset_in_page_px { if layer.extra_data.borrow().scroll_offset == new_offset_in_page_px {
return false return ScrollPositionUnchanged;
} }
// The scroll offset is just a record of the scroll position of this scrolling root, // The scroll offset is just a record of the scroll position of this scrolling root,
@ -102,7 +111,12 @@ pub fn clamp_scroll_offset_and_scroll_layer(layer: Rc<Layer<CompositorData>>,
for child in layer.children().iter() { for child in layer.children().iter() {
result |= scroll_layer_and_all_child_layers(child.clone(), new_offset_in_page_px); result |= scroll_layer_and_all_child_layers(child.clone(), new_offset_in_page_px);
} }
return result;
if result {
return ScrollPositionChanged;
} else {
return ScrollPositionUnchanged;
}
} }
fn scroll_layer_and_all_child_layers(layer: Rc<Layer<CompositorData>>, fn scroll_layer_and_all_child_layers(layer: Rc<Layer<CompositorData>>,