diff options
Diffstat (limited to 'components')
-rw-r--r-- | components/compositing/compositor.rs | 81 | ||||
-rw-r--r-- | components/compositing/compositor_data.rs | 7 | ||||
-rw-r--r-- | components/compositing/events.rs | 77 |
3 files changed, 77 insertions, 88 deletions
diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index ea8bf447257..f17954245d5 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -22,7 +22,6 @@ use windowing::PinchZoomWindowEvent; use azure::azure_hl::SourceSurfaceMethods; use azure::azure_hl; use std::cmp; -use geom::matrix::identity; use geom::point::{Point2D, TypedPoint2D}; use geom::rect::Rect; use geom::size::TypedSize2D; @@ -159,7 +158,7 @@ impl IOCompositor { context: rendergl::RenderContext::new(CompositorTask::create_graphics_context(), show_debug_borders), root_pipeline: None, - scene: Scene::new(window_size.as_f32().to_untyped(), identity()), + scene: Scene::new(window_size.as_f32().to_untyped()), window_size: window_size, hidpi_factor: hidpi_factor, composite_ready: false, @@ -543,26 +542,41 @@ impl IOCompositor { })); } + + pub fn move_layer(&self, + pipeline_id: PipelineId, + layer_id: LayerId, + origin: TypedPoint2D<DevicePixel, f32>) + -> bool { + match self.find_layer_with_pipeline_and_layer_id(pipeline_id, layer_id) { + Some(ref layer) => { + if layer.extra_data.borrow().wants_scroll_events == WantsScrollEvents { + events::clamp_scroll_offset_and_scroll_layer(layer.clone(), + TypedPoint2D(0f32, 0f32) - origin, + self.window_size.as_f32(), + self.device_pixels_per_page_px()); + } + true + } + None => false, + } + } + fn scroll_layer_to_fragment_point_if_necessary(&mut self, pipeline_id: PipelineId, layer_id: LayerId) { let device_pixels_per_page_px = self.device_pixels_per_page_px(); - let window_size = self.window_size.as_f32(); - let needs_recomposite = match self.scene.root { - Some(ref mut root_layer) => { - self.fragment_point.take().map_or(false, |fragment_point| { - let fragment_point = fragment_point * device_pixels_per_page_px.get(); - events::move(root_layer.clone(), - pipeline_id, - layer_id, - Point2D::from_untyped(&fragment_point), - window_size) - }) + match self.fragment_point.take() { + Some(point) => { + let point = point * device_pixels_per_page_px.get(); + if !self.move_layer(pipeline_id, layer_id, Point2D::from_untyped(&point)) { + fail!("Compositor: Tried to scroll to fragment with unknown layer."); + } + + self.recomposite = true; } - None => fail!("Compositor: Tried to scroll to fragment without root layer."), + None => {} }; - - self.recomposite_if(needs_recomposite); } fn set_layer_origin(&mut self, @@ -610,30 +624,13 @@ impl IOCompositor { pipeline_id: PipelineId, layer_id: LayerId, point: Point2D<f32>) { - let device_pixels_per_page_px = self.device_pixels_per_page_px(); let device_point = point * device_pixels_per_page_px.get(); - let window_size = self.window_size.as_f32(); - - let (ask, move): (bool, bool) = match self.scene.root { - Some(ref layer) if layer.extra_data.borrow().pipeline.id == pipeline_id => { - (true, - events::move(layer.clone(), - pipeline_id, - layer_id, - Point2D::from_untyped(&device_point), - window_size)) - } - Some(_) | None => { - self.fragment_point = Some(point); - - (false, false) - } - }; - - if ask { - self.recomposite_if(move); + if self.move_layer(pipeline_id, layer_id, Point2D::from_untyped(&device_point)) { + self.recomposite = true; self.send_buffer_requests_for_all_layers(); + } else { + self.fragment_point = Some(point); } } @@ -750,12 +747,14 @@ impl IOCompositor { cursor: TypedPoint2D<DevicePixel, i32>) { let mut scroll = false; let window_size = self.window_size.as_f32(); + let scene_scale = self.device_pixels_per_page_px(); match self.scene.root { Some(ref mut layer) => { scroll = events::handle_scroll_event(layer.clone(), delta, cursor.as_f32(), - window_size) || scroll; + window_size, + scene_scale) || scroll; } None => { } } @@ -779,7 +778,7 @@ impl IOCompositor { fn update_zoom_transform(&mut self) { let scale = self.device_pixels_per_page_px(); - self.scene.transform = identity().scale(scale.get(), scale.get(), 1f32); + self.scene.scale = scale.get(); } fn on_zoom_window_event(&mut self, magnification: f32) { @@ -806,12 +805,14 @@ impl IOCompositor { let delta = page_delta * self.device_pixels_per_page_px(); let cursor = TypedPoint2D(-1f32, -1f32); // Make sure this hits the base layer. + let scene_scale = self.device_pixels_per_page_px(); match self.scene.root { Some(ref mut layer) => { events::handle_scroll_event(layer.clone(), delta, cursor, - window_size); + window_size, + scene_scale); } None => { } } diff --git a/components/compositing/compositor_data.rs b/components/compositing/compositor_data.rs index fdfeac7656e..dfd58f5d2b6 100644 --- a/components/compositing/compositor_data.rs +++ b/components/compositing/compositor_data.rs @@ -8,6 +8,7 @@ use pipeline::CompositionPipeline; use azure::azure_hl::Color; use geom::point::TypedPoint2D; +use geom::scale_factor::ScaleFactor; use geom::size::{Size2D, TypedSize2D}; use geom::rect::Rect; use gfx::render_task::UnusedBufferMsg; @@ -74,11 +75,13 @@ impl CompositorData { layer.contents_changed(); // Call scroll for bounds checking if the page shrunk. Use (-1, -1) as the - // cursor position to make sure the scroll isn't propagated downwards. + // cursor position to make sure the scroll isn't propagated downwards. The + // scale doesn't matter here since 0, 0 is 0, 0 no matter the scene scale. events::handle_scroll_event(layer.clone(), TypedPoint2D(0f32, 0f32), TypedPoint2D(-1f32, -1f32), - size); + size, + ScaleFactor(1.0) /* scene_scale */); } pub fn find_layer_with_pipeline_and_layer_id(layer: Rc<Layer<CompositorData>>, diff --git a/components/compositing/events.rs b/components/compositing/events.rs index 25779a417af..c4e86cae26a 100644 --- a/components/compositing/events.rs +++ b/components/compositing/events.rs @@ -7,15 +7,14 @@ use windowing::{MouseWindowEvent, MouseWindowClickEvent, MouseWindowMouseDownEve use windowing::MouseWindowMouseUpEvent; use geom::length::Length; -use geom::point::TypedPoint2D; +use geom::point::{Point2D, TypedPoint2D}; use geom::scale_factor::ScaleFactor; use geom::size::TypedSize2D; use layers::geometry::DevicePixel; use layers::layers::Layer; use script_traits::{ClickEvent, MouseDownEvent, MouseMoveEvent, MouseUpEvent, SendEventMsg}; use script_traits::{ScriptControlChan}; -use servo_msg::compositor_msg::{FixedPosition, LayerId}; -use servo_msg::constellation_msg::PipelineId; +use servo_msg::compositor_msg::FixedPosition; use servo_util::geometry::PagePx; use std::rc::Rc; @@ -47,7 +46,8 @@ impl Clampable for f32 { pub fn handle_scroll_event(layer: Rc<Layer<CompositorData>>, delta: TypedPoint2D<DevicePixel, f32>, cursor: TypedPoint2D<DevicePixel, f32>, - window_size: TypedSize2D<DevicePixel, f32>) + window_size: TypedSize2D<DevicePixel, f32>, + scale: ScaleFactor<PagePx, DevicePixel, f32>) -> bool { // If this layer doesn't want scroll events, neither it nor its children can handle scroll // events. @@ -56,53 +56,60 @@ pub fn handle_scroll_event(layer: Rc<Layer<CompositorData>>, } // Allow children to scroll. - let content_offset = layer.content_offset.borrow().clone(); - let cursor = cursor - content_offset; + let content_offset_in_page_pixels : TypedPoint2D<PagePx, f32> = + Point2D::from_untyped(&*layer.content_offset.borrow()); + let content_offset : TypedPoint2D<DevicePixel, f32> = content_offset_in_page_pixels * scale; + let new_cursor = cursor - content_offset; for child in layer.children().iter() { let child_bounds = child.bounds.borrow(); - if child_bounds.contains(&cursor) && + if child_bounds.contains(&new_cursor) && handle_scroll_event(child.clone(), delta, - cursor - child_bounds.origin, - child_bounds.size) { + new_cursor - child_bounds.origin, + child_bounds.size, + scale) { return true } } - clamp_scroll_offset_and_scroll_layer(layer, content_offset + delta, window_size) + clamp_scroll_offset_and_scroll_layer(layer, content_offset + delta, window_size, scale) } pub fn clamp_scroll_offset_and_scroll_layer(layer: Rc<Layer<CompositorData>>, - mut new_offset: TypedPoint2D<DevicePixel, f32>, - window_size: TypedSize2D<DevicePixel, f32>) + new_offset: TypedPoint2D<DevicePixel, f32>, + window_size: TypedSize2D<DevicePixel, f32>, + scale: ScaleFactor<PagePx, DevicePixel, f32>) -> bool { let layer_size = layer.bounds.borrow().size; let min_x = (window_size.width - layer_size.width).get().min(0.0); - new_offset.x = Length(new_offset.x.get().clamp(&min_x, &0.0)); - let min_y = (window_size.height - layer_size.height).get().min(0.0); - new_offset.y = Length(new_offset.y.get().clamp(&min_y, &0.0)); + let new_offset : TypedPoint2D<DevicePixel, f32> = + Point2D(Length(new_offset.x.get().clamp(&min_x, &0.0)), + Length(new_offset.y.get().clamp(&min_y, &0.0))); - if *layer.content_offset.borrow() == new_offset { + let new_offset_in_page_px = new_offset / scale; + let untyped_new_offset = new_offset_in_page_px.to_untyped(); + if *layer.content_offset.borrow() == untyped_new_offset { return false } // FIXME: This allows the base layer to record the current content offset without // updating its transform. This should be replaced with something less strange. - *layer.content_offset.borrow_mut() = new_offset; - scroll_layer_and_all_child_layers(layer.clone(), new_offset) + *layer.content_offset.borrow_mut() = untyped_new_offset; + scroll_layer_and_all_child_layers(layer.clone(), new_offset_in_page_px) } fn scroll_layer_and_all_child_layers(layer: Rc<Layer<CompositorData>>, - new_offset: TypedPoint2D<DevicePixel, f32>) + new_offset: TypedPoint2D<PagePx, f32>) -> bool { let mut result = false; // Only scroll this layer if it's not fixed-positioned. if layer.extra_data.borrow().scroll_policy != FixedPosition { - *layer.transform.borrow_mut() = identity().translate(new_offset.x.get(), - new_offset.y.get(), + let new_offset = new_offset.to_untyped(); + *layer.transform.borrow_mut() = identity().translate(new_offset.x, + new_offset.y, 0.0); *layer.content_offset.borrow_mut() = new_offset; result = true @@ -122,7 +129,9 @@ pub fn send_mouse_event(layer: Rc<Layer<CompositorData>>, event: MouseWindowEvent, cursor: TypedPoint2D<DevicePixel, f32>, device_pixels_per_page_px: ScaleFactor<PagePx, DevicePixel, f32>) { - let cursor = cursor - *layer.content_offset.borrow(); + let content_offset = *layer.content_offset.borrow() * device_pixels_per_page_px.get(); + let content_offset : TypedPoint2D<DevicePixel, f32> = Point2D::from_untyped(&content_offset); + let cursor = cursor - content_offset; for child in layer.children().iter() { let child_bounds = child.bounds.borrow(); if child_bounds.contains(&cursor) { @@ -152,27 +161,3 @@ pub fn send_mouse_move_event(layer: Rc<Layer<CompositorData>>, let _ = chan.send_opt(SendEventMsg(layer.extra_data.borrow().pipeline.id.clone(), message)); } -pub fn move(layer: Rc<Layer<CompositorData>>, - pipeline_id: PipelineId, - layer_id: LayerId, - origin: TypedPoint2D<DevicePixel, f32>, - window_size: TypedSize2D<DevicePixel, f32>) - -> bool { - // Search children for the right layer to move. - if layer.extra_data.borrow().pipeline.id != pipeline_id || - layer.extra_data.borrow().id != layer_id { - return layer.children().iter().any(|kid| { - move(kid.clone(), - pipeline_id, - layer_id, - origin, - window_size) - }); - } - - if layer.extra_data.borrow().wants_scroll_events != WantsScrollEvents { - return false - } - - clamp_scroll_offset_and_scroll_layer(layer, TypedPoint2D(0f32, 0f32) - origin, window_size) -} |