diff options
-rw-r--r-- | components/compositing/compositor.rs | 26 | ||||
-rw-r--r-- | components/compositing/compositor_layer.rs | 2 | ||||
-rw-r--r-- | components/script/dom/document.rs | 21 | ||||
-rw-r--r-- | components/script_traits/lib.rs | 4 |
4 files changed, 41 insertions, 12 deletions
diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index a0cc3059bc6..720ded6ade0 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -35,7 +35,7 @@ use msg::constellation_msg::{NavigationDirection, PipelineId, WindowSizeData}; use pipeline::CompositionPipeline; use profile_traits::mem::{self, ReportKind, Reporter, ReporterRequest}; use profile_traits::time::{self, ProfilerCategory, profile}; -use script_traits::CompositorEvent::TouchEvent; +use script_traits::CompositorEvent::{MouseMoveEvent, TouchEvent}; use script_traits::{ConstellationControlMsg, LayoutControlMsg, MouseButton}; use script_traits::{TouchEventType, TouchId}; use scrolling::ScrollingTimerProxy; @@ -201,6 +201,9 @@ pub struct IOCompositor<Window: WindowMethods> { /// Pipeline IDs of subpages that the compositor has seen in a layer tree but which have not /// yet been painted. pending_subpages: HashSet<PipelineId>, + + /// The id of the pipeline that was last sent a mouse move event, if any. + last_mouse_move_recipient: Option<PipelineId>, } /// The states of the touch input state machine. @@ -370,6 +373,7 @@ impl<Window: WindowMethods> IOCompositor<Window> { ready_to_save_state: ReadyState::Unknown, surface_map: SurfaceMap::new(BUFFER_MAP_SIZE), pending_subpages: HashSet::new(), + last_mouse_move_recipient: None, } } @@ -1205,8 +1209,24 @@ impl<Window: WindowMethods> IOCompositor<Window> { } match self.find_topmost_layer_at_point(cursor / self.scene.scale) { - Some(result) => result.layer.send_mouse_move_event(self, result.point), - None => {}, + Some(result) => { + // In the case that the mouse was previously over a different layer, + // that layer must update its state. + if let Some(last_pipeline_id) = self.last_mouse_move_recipient { + if last_pipeline_id != result.layer.pipeline_id() { + if let Some(pipeline) = self.pipeline(last_pipeline_id) { + let _ = pipeline.script_chan + .send(ConstellationControlMsg::SendEvent( + last_pipeline_id.clone(), + MouseMoveEvent(None))); + } + } + } + + self.last_mouse_move_recipient = Some(result.layer.pipeline_id()); + result.layer.send_mouse_move_event(self, result.point); + } + None => {} } } diff --git a/components/compositing/compositor_layer.rs b/components/compositing/compositor_layer.rs index 8e1330b9344..b47cff1ccca 100644 --- a/components/compositing/compositor_layer.rs +++ b/components/compositing/compositor_layer.rs @@ -385,7 +385,7 @@ impl CompositorLayer for Layer<CompositorData> { compositor: &IOCompositor<Window>, cursor: TypedPoint2D<LayerPixel, f32>) where Window: WindowMethods { - self.send_event(compositor, MouseMoveEvent(cursor.to_untyped())); + self.send_event(compositor, MouseMoveEvent(Some(cursor.to_untyped()))); } fn send_event<Window>(&self, diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 90e5697dd33..b39adbc53fc 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -669,10 +669,12 @@ impl Document { pub fn handle_mouse_move_event(&self, js_runtime: *mut JSRuntime, - point: Point2D<f32>, + point: Option<Point2D<f32>>, prev_mouse_over_targets: &mut RootedVec<JS<Element>>) { // Build a list of elements that are currently under the mouse. - let mouse_over_addresses = self.get_nodes_under_mouse(&point); + let mouse_over_addresses = point.as_ref() + .map(|point| self.get_nodes_under_mouse(point)) + .unwrap_or(vec![]); let mut mouse_over_targets = mouse_over_addresses.iter().map(|node_address| { node::from_untrusted_node_address(js_runtime, *node_address) .inclusive_ancestors() @@ -691,7 +693,11 @@ impl Document { let target = target_ref.upcast(); - self.fire_mouse_event(point, &target, "mouseout".to_owned()); + // FIXME: we should be dispatching this event but we lack an actual + // point to pass to it. + if let Some(point) = point { + self.fire_mouse_event(point, &target, "mouseout".to_owned()); + } } } } @@ -705,8 +711,9 @@ impl Document { let target = target.upcast(); - self.fire_mouse_event(point, target, "mouseover".to_owned()); - + if let Some(point) = point { + self.fire_mouse_event(point, target, "mouseover".to_owned()); + } } } @@ -716,7 +723,9 @@ impl Document { node::from_untrusted_node_address(js_runtime, mouse_over_addresses[0]); let target = top_most_node.upcast(); - self.fire_mouse_event(point, target, "mousemove".to_owned()); + if let Some(point) = point { + self.fire_mouse_event(point, target, "mousemove".to_owned()); + } } // Store the current mouse over targets for next frame diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs index 2db79ff93d3..827a729e236 100644 --- a/components/script_traits/lib.rs +++ b/components/script_traits/lib.rs @@ -187,8 +187,8 @@ pub enum CompositorEvent { MouseDownEvent(MouseButton, Point2D<f32>), /// A mouse button was released on a point. MouseUpEvent(MouseButton, Point2D<f32>), - /// The mouse was moved over a point. - MouseMoveEvent(Point2D<f32>), + /// The mouse was moved over a point (or was moved out of the recognizable region). + MouseMoveEvent(Option<Point2D<f32>>), /// A touch event was generated with a touch ID and location. TouchEvent(TouchEventType, TouchId, Point2D<f32>), /// A key was pressed. |