Auto merge of #8785 - mbrubeck:fixed-hit-test, r=pcwalton

Add slow path for hit testing of iframe behind positioned content layer

Fixes browser.html blocker #8759. r? @pcwalton

This adds a slow path for cases where the compositor's layer-based hit testing is incorrect.  If the script task discovers that a mouse event should have been dispatched to an iframe, it bounces the event back to the constellation to be forwarded to the correct pipeline.

This isn't terribly slow (on the slow path, it adds one extra round-trip message between script and constellation), but if we want to optimize this better we could instead replace the compositor's layer hit testing with display list hit testing in the paint task.  This would be a more complicated change that I think we should save for a follow-up.

This only fixes mouse input for now.  A basically-identical change will be needed for touch-screen input, whether we stick with this approach or switch to the paint task.

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/8785)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2015-12-04 02:54:22 +05:30
commit bc62b5aadb
15 changed files with 100 additions and 68 deletions

View file

@ -30,13 +30,13 @@ use msg::compositor_msg::{Epoch, EventResult, FrameTreeId, LayerId, LayerKind};
use msg::compositor_msg::{LayerProperties, ScrollPolicy};
use msg::constellation_msg::CompositorMsg as ConstellationMsg;
use msg::constellation_msg::{AnimationState, Image, PixelFormat};
use msg::constellation_msg::{Key, KeyModifiers, KeyState, LoadData};
use msg::constellation_msg::{Key, KeyModifiers, KeyState, LoadData, MouseButton};
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::{MouseMoveEvent, TouchEvent};
use script_traits::{ConstellationControlMsg, LayoutControlMsg, MouseButton};
use script_traits::{ConstellationControlMsg, LayoutControlMsg};
use script_traits::{TouchEventType, TouchId};
use scrolling::ScrollingTimerProxy;
use std::collections::hash_map::Entry::{Occupied, Vacant};

View file

@ -12,9 +12,9 @@ use layers::color::Color;
use layers::geometry::LayerPixel;
use layers::layers::{Layer, LayerBufferSet};
use msg::compositor_msg::{Epoch, LayerId, LayerProperties, ScrollPolicy};
use msg::constellation_msg::PipelineId;
use msg::constellation_msg::{MouseEventType, PipelineId};
use script_traits::CompositorEvent;
use script_traits::CompositorEvent::{ClickEvent, MouseDownEvent, MouseMoveEvent, MouseUpEvent};
use script_traits::CompositorEvent::{MouseButtonEvent, MouseMoveEvent};
use script_traits::ConstellationControlMsg;
use std::rc::Rc;
use windowing::{MouseWindowEvent, WindowMethods};
@ -372,11 +372,11 @@ impl CompositorLayer for Layer<CompositorData> {
let event_point = cursor.to_untyped();
let message = match event {
MouseWindowEvent::Click(button, _) =>
ClickEvent(button, event_point),
MouseButtonEvent(MouseEventType::Click, button, event_point),
MouseWindowEvent::MouseDown(button, _) =>
MouseDownEvent(button, event_point),
MouseButtonEvent(MouseEventType::MouseDown, button, event_point),
MouseWindowEvent::MouseUp(button, _) =>
MouseUpEvent(button, event_point),
MouseButtonEvent(MouseEventType::MouseUp, button, event_point),
};
self.send_event(compositor, message);
}

View file

@ -613,6 +613,19 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
debug!("constellation got focus message");
self.handle_focus_msg(pipeline_id);
}
Request::Script(FromScriptMsg::ForwardMouseButtonEvent(
pipeline_id, event_type, button, point)) => {
if let Some(pipeline) = self.pipelines.get(&pipeline_id) {
pipeline.script_chan.send(ConstellationControlMsg::SendEvent(pipeline_id,
CompositorEvent::MouseButtonEvent(event_type, button, point)));
}
}
Request::Script(FromScriptMsg::ForwardMouseMoveEvent(pipeline_id, point)) => {
if let Some(pipeline) = self.pipelines.get(&pipeline_id) {
pipeline.script_chan.send(ConstellationControlMsg::SendEvent(pipeline_id,
CompositorEvent::MouseMoveEvent(Some(point))));
}
}
Request::Script(FromScriptMsg::GetClipboardContents(sender)) => {
let result = self.clipboard_ctx.as_ref().map_or(
"".to_owned(),

View file

@ -11,9 +11,9 @@ use euclid::size::TypedSize2D;
use euclid::{Point2D, Size2D};
use layers::geometry::DevicePixel;
use layers::platform::surface::NativeDisplay;
use msg::constellation_msg::{Key, KeyModifiers, KeyState};
use msg::constellation_msg::{Key, KeyModifiers, KeyState, MouseButton};
use net_traits::net_error_list::NetError;
use script_traits::{MouseButton, TouchEventType, TouchId};
use script_traits::{TouchEventType, TouchId};
use std::fmt::{Debug, Error, Formatter};
use std::rc::Rc;
use url::Url;
@ -27,7 +27,6 @@ pub enum MouseWindowEvent {
MouseUp(MouseButton, TypedPoint2D<DevicePixel, f32>),
}
#[derive(Clone)]
pub enum WindowNavigateMsg {
Forward,