Switch to using WebRender hit testing

This trades quite a bit of complicated code in Servo for few more
messages and a significant performance improvement. In particular,
WebRender can search the entire display list at once instead of
ping-ponging down the pipeline tree. This allows us to send mouse
events to the correct pipeline immediately.
This commit is contained in:
Martin Robinson 2017-09-30 15:50:47 +02:00
parent 00e2a1c62a
commit b5d51dd263
20 changed files with 381 additions and 555 deletions

View file

@ -1010,7 +1010,7 @@ impl ScriptThread {
}
FromConstellation(ConstellationControlMsg::SendEvent(
_,
MouseMoveEvent(_))) => {
MouseMoveEvent(..))) => {
match mouse_move_event_index {
None => {
mouse_move_event_index = Some(sequential.len());
@ -2187,11 +2187,11 @@ impl ScriptThread {
self.handle_resize_event(pipeline_id, new_size, size_type);
}
MouseButtonEvent(event_type, button, point) => {
self.handle_mouse_event(pipeline_id, event_type, button, point);
MouseButtonEvent(event_type, button, point, node_address) => {
self.handle_mouse_event(pipeline_id, event_type, button, point, node_address);
}
MouseMoveEvent(point) => {
MouseMoveEvent(point, node_address) => {
let document = match { self.documents.borrow().find_document(pipeline_id) } {
Some(document) => document,
None => return warn!("Message sent to closed pipeline {}.", pipeline_id),
@ -2201,7 +2201,8 @@ impl ScriptThread {
let prev_mouse_over_target = self.topmost_mouse_over_target.get();
document.handle_mouse_move_event(self.js_runtime.rt(), point,
&self.topmost_mouse_over_target);
&self.topmost_mouse_over_target,
node_address);
// Short-circuit if nothing changed
if self.topmost_mouse_over_target.get() == prev_mouse_over_target {
@ -2244,8 +2245,14 @@ impl ScriptThread {
}
}
}
TouchEvent(event_type, identifier, point) => {
let touch_result = self.handle_touch_event(pipeline_id, event_type, identifier, point);
TouchEvent(event_type, identifier, point, node_address) => {
let touch_result = self.handle_touch_event(
pipeline_id,
event_type,
identifier,
point,
node_address
);
match (event_type, touch_result) {
(TouchEventType::Down, TouchEventResult::Processed(handled)) => {
let result = if handled {
@ -2263,12 +2270,17 @@ impl ScriptThread {
}
}
TouchpadPressureEvent(point, pressure, phase) => {
TouchpadPressureEvent(_point, pressure, phase, node_address) => {
let doc = match { self.documents.borrow().find_document(pipeline_id) } {
Some(doc) => doc,
None => return warn!("Message sent to closed pipeline {}.", pipeline_id),
};
doc.handle_touchpad_pressure_event(self.js_runtime.rt(), point, pressure, phase);
doc.handle_touchpad_pressure_event(
self.js_runtime.rt(),
pressure,
phase,
node_address
);
}
KeyEvent(ch, key, state, modifiers) => {
@ -2281,24 +2293,35 @@ impl ScriptThread {
}
}
fn handle_mouse_event(&self,
pipeline_id: PipelineId,
mouse_event_type: MouseEventType,
button: MouseButton,
point: Point2D<f32>) {
fn handle_mouse_event(
&self,
pipeline_id: PipelineId,
mouse_event_type: MouseEventType,
button: MouseButton,
point: Point2D<f32>,
node_address: Option<UntrustedNodeAddress>
) {
let document = match { self.documents.borrow().find_document(pipeline_id) } {
Some(document) => document,
None => return warn!("Message sent to closed pipeline {}.", pipeline_id),
};
document.handle_mouse_event(self.js_runtime.rt(), button, point, mouse_event_type);
document.handle_mouse_event(
self.js_runtime.rt(),
button,
point,
mouse_event_type,
node_address
);
}
fn handle_touch_event(&self,
pipeline_id: PipelineId,
event_type: TouchEventType,
identifier: TouchId,
point: Point2D<f32>)
-> TouchEventResult {
fn handle_touch_event(
&self,
pipeline_id: PipelineId,
event_type: TouchEventType,
identifier: TouchId,
point: Point2D<f32>,
node_address: Option<UntrustedNodeAddress>
) -> TouchEventResult {
let document = match { self.documents.borrow().find_document(pipeline_id) } {
Some(document) => document,
None => {
@ -2306,7 +2329,13 @@ impl ScriptThread {
return TouchEventResult::Processed(true);
},
};
document.handle_touch_event(self.js_runtime.rt(), event_type, identifier, point)
document.handle_touch_event(
self.js_runtime.rt(),
event_type,
identifier,
point,
node_address
)
}
/// https://html.spec.whatwg.org/multipage/#navigating-across-documents