aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/compositing/compositor.rs26
-rw-r--r--components/compositing/compositor_layer.rs2
-rw-r--r--components/script/dom/document.rs21
-rw-r--r--components/script_traits/lib.rs4
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.