Remove the script listener thread (fixes #11345).

We needed a separate thread in the chrome process because communication to the
compositor is done through a trait object, and cross-process virtual calls are
forbidden.

Also, the fact that these messages are ultimately handled by the compositor is
an implementation detail; conceptually, the relevant constellation is supposed
to handle these messages.

So instead, the script thread will now send the messages to the constellation,
which will ask the compositor to handle them.
This commit is contained in:
Ms2ger 2016-05-25 10:33:28 +02:00
parent 586c0702a0
commit 4113eb6f72
8 changed files with 105 additions and 163 deletions

View file

@ -9,13 +9,13 @@ use compositor::{self, CompositingReason};
use euclid::point::Point2D; use euclid::point::Point2D;
use euclid::size::Size2D; use euclid::size::Size2D;
use gfx_traits::{Epoch, FrameTreeId, LayerId, LayerProperties, PaintListener}; use gfx_traits::{Epoch, FrameTreeId, LayerId, LayerProperties, PaintListener};
use ipc_channel::ipc::{IpcReceiver, IpcSender}; use ipc_channel::ipc::IpcSender;
use layers::layers::{BufferRequest, LayerBufferSet}; use layers::layers::{BufferRequest, LayerBufferSet};
use layers::platform::surface::{NativeDisplay, NativeSurface}; use layers::platform::surface::{NativeDisplay, NativeSurface};
use msg::constellation_msg::{Image, Key, KeyModifiers, KeyState, PipelineId}; use msg::constellation_msg::{Image, Key, KeyModifiers, KeyState, PipelineId};
use profile_traits::mem; use profile_traits::mem;
use profile_traits::time; use profile_traits::time;
use script_traits::{AnimationState, ConstellationMsg, EventResult, ScriptToCompositorMsg}; use script_traits::{AnimationState, ConstellationMsg, EventResult};
use std::fmt::{Debug, Error, Formatter}; use std::fmt::{Debug, Error, Formatter};
use std::rc::Rc; use std::rc::Rc;
use std::sync::mpsc::{Receiver, Sender, channel}; use std::sync::mpsc::{Receiver, Sender, channel};
@ -55,54 +55,6 @@ impl CompositorReceiver for Receiver<Msg> {
} }
} }
pub fn run_script_listener_thread(compositor_proxy: Box<CompositorProxy + 'static + Send>,
receiver: IpcReceiver<ScriptToCompositorMsg>) {
while let Ok(msg) = receiver.recv() {
match msg {
ScriptToCompositorMsg::ScrollFragmentPoint(pipeline_id, layer_id, point, smooth) => {
compositor_proxy.send(Msg::ScrollFragmentPoint(pipeline_id,
layer_id,
point,
smooth));
}
ScriptToCompositorMsg::GetClientWindow(send) => {
compositor_proxy.send(Msg::GetClientWindow(send));
}
ScriptToCompositorMsg::MoveTo(point) => {
compositor_proxy.send(Msg::MoveTo(point));
}
ScriptToCompositorMsg::ResizeTo(size) => {
compositor_proxy.send(Msg::ResizeTo(size));
}
ScriptToCompositorMsg::Exit => {
compositor_proxy.send(Msg::Exit);
}
ScriptToCompositorMsg::SetTitle(pipeline_id, title) => {
compositor_proxy.send(Msg::ChangePageTitle(pipeline_id, title))
}
ScriptToCompositorMsg::SendKeyEvent(key, key_state, key_modifiers) => {
compositor_proxy.send(Msg::KeyEvent(key, key_state, key_modifiers))
}
ScriptToCompositorMsg::TouchEventProcessed(result) => {
compositor_proxy.send(Msg::TouchEventProcessed(result))
}
ScriptToCompositorMsg::GetScrollOffset(pid, lid, send) => {
compositor_proxy.send(Msg::GetScrollOffset(pid, lid, send));
}
ScriptToCompositorMsg::Exited => break,
}
}
}
pub trait RenderListener { pub trait RenderListener {
fn recomposite(&mut self, reason: CompositingReason); fn recomposite(&mut self, reason: CompositingReason);
} }

View file

@ -812,6 +812,45 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
self.handle_alert(pipeline_id, message, sender); self.handle_alert(pipeline_id, message, sender);
} }
Request::Script(FromScriptMsg::ScrollFragmentPoint(pipeline_id, layer_id, point, smooth)) => {
self.compositor_proxy.send(ToCompositorMsg::ScrollFragmentPoint(pipeline_id,
layer_id,
point,
smooth));
}
Request::Script(FromScriptMsg::GetClientWindow(send)) => {
self.compositor_proxy.send(ToCompositorMsg::GetClientWindow(send));
}
Request::Script(FromScriptMsg::MoveTo(point)) => {
self.compositor_proxy.send(ToCompositorMsg::MoveTo(point));
}
Request::Script(FromScriptMsg::ResizeTo(size)) => {
self.compositor_proxy.send(ToCompositorMsg::ResizeTo(size));
}
Request::Script(FromScriptMsg::Exit) => {
self.compositor_proxy.send(ToCompositorMsg::Exit);
}
Request::Script(FromScriptMsg::SetTitle(pipeline_id, title)) => {
self.compositor_proxy.send(ToCompositorMsg::ChangePageTitle(pipeline_id, title))
}
Request::Script(FromScriptMsg::SendKeyEvent(key, key_state, key_modifiers)) => {
self.compositor_proxy.send(ToCompositorMsg::KeyEvent(key, key_state, key_modifiers))
}
Request::Script(FromScriptMsg::TouchEventProcessed(result)) => {
self.compositor_proxy.send(ToCompositorMsg::TouchEventProcessed(result))
}
Request::Script(FromScriptMsg::GetScrollOffset(pid, lid, send)) => {
self.compositor_proxy.send(ToCompositorMsg::GetScrollOffset(pid, lid, send));
}
// Messages from layout thread // Messages from layout thread

View file

@ -4,7 +4,6 @@
use compositing::CompositionPipeline; use compositing::CompositionPipeline;
use compositing::CompositorProxy; use compositing::CompositorProxy;
use compositing::compositor_thread;
use compositing::compositor_thread::Msg as CompositorMsg; use compositing::compositor_thread::Msg as CompositorMsg;
use devtools_traits::{DevtoolsControlMsg, ScriptToDevtoolsControlMsg}; use devtools_traits::{DevtoolsControlMsg, ScriptToDevtoolsControlMsg};
use euclid::scale_factor::ScaleFactor; use euclid::scale_factor::ScaleFactor;
@ -24,7 +23,7 @@ use profile_traits::mem as profile_mem;
use profile_traits::time; use profile_traits::time;
use script_traits::{ConstellationControlMsg, InitialScriptState, MozBrowserEvent}; use script_traits::{ConstellationControlMsg, InitialScriptState, MozBrowserEvent};
use script_traits::{LayoutControlMsg, LayoutMsg, NewLayoutInfo, ScriptMsg}; use script_traits::{LayoutControlMsg, LayoutMsg, NewLayoutInfo, ScriptMsg};
use script_traits::{ScriptToCompositorMsg, ScriptThreadFactory, TimerEventRequest}; use script_traits::{ScriptThreadFactory, TimerEventRequest};
use std::collections::HashMap; use std::collections::HashMap;
use std::mem; use std::mem;
use std::sync::mpsc::{Receiver, Sender, channel}; use std::sync::mpsc::{Receiver, Sender, channel};
@ -34,7 +33,6 @@ use util::geometry::{PagePx, ViewportPx};
use util::ipc::OptionalIpcSender; use util::ipc::OptionalIpcSender;
use util::opts::{self, Opts}; use util::opts::{self, Opts};
use util::prefs::{self, Pref}; use util::prefs::{self, Pref};
use util::thread;
use webrender_traits; use webrender_traits;
/// A uniquely-identifiable pipeline of script thread, layout thread, and paint thread. /// A uniquely-identifiable pipeline of script thread, layout thread, and paint thread.
@ -128,8 +126,6 @@ impl Pipeline {
.expect("Pipeline layout shutdown chan"); .expect("Pipeline layout shutdown chan");
let (pipeline_chan, pipeline_port) = ipc::channel() let (pipeline_chan, pipeline_port) = ipc::channel()
.expect("Pipeline main chan");; .expect("Pipeline main chan");;
let (script_to_compositor_chan, script_to_compositor_port) = ipc::channel()
.expect("Pipeline script to compositor chan");
let window_size = state.window_size.map(|size| { let window_size = state.window_size.map(|size| {
WindowSizeData { WindowSizeData {
@ -223,7 +219,6 @@ impl Pipeline {
pipeline_port: pipeline_port, pipeline_port: pipeline_port,
layout_shutdown_chan: layout_shutdown_chan, layout_shutdown_chan: layout_shutdown_chan,
paint_shutdown_chan: paint_shutdown_chan.clone(), paint_shutdown_chan: paint_shutdown_chan.clone(),
script_to_compositor_chan: script_to_compositor_chan,
pipeline_namespace_id: state.pipeline_namespace_id, pipeline_namespace_id: state.pipeline_namespace_id,
layout_content_process_shutdown_chan: layout_content_process_shutdown_chan, layout_content_process_shutdown_chan: layout_content_process_shutdown_chan,
layout_content_process_shutdown_port: layout_content_process_shutdown_port, layout_content_process_shutdown_port: layout_content_process_shutdown_port,
@ -244,7 +239,6 @@ impl Pipeline {
chrome_to_paint_chan: chrome_to_paint_chan, chrome_to_paint_chan: chrome_to_paint_chan,
chrome_to_paint_port: chrome_to_paint_port, chrome_to_paint_port: chrome_to_paint_port,
paint_shutdown_chan: paint_shutdown_chan, paint_shutdown_chan: paint_shutdown_chan,
script_to_compositor_port: script_to_compositor_port,
}; };
(pipeline, unprivileged_pipeline_content, privileged_pipeline_content) (pipeline, unprivileged_pipeline_content, privileged_pipeline_content)
@ -380,7 +374,6 @@ pub struct UnprivilegedPipelineContent {
layout_to_constellation_chan: IpcSender<LayoutMsg>, layout_to_constellation_chan: IpcSender<LayoutMsg>,
scheduler_chan: IpcSender<TimerEventRequest>, scheduler_chan: IpcSender<TimerEventRequest>,
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>, devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
script_to_compositor_chan: IpcSender<ScriptToCompositorMsg>,
bluetooth_thread: IpcSender<BluetoothMethodMsg>, bluetooth_thread: IpcSender<BluetoothMethodMsg>,
image_cache_thread: ImageCacheThread, image_cache_thread: ImageCacheThread,
font_cache_thread: FontCacheThread, font_cache_thread: FontCacheThread,
@ -414,7 +407,6 @@ impl UnprivilegedPipelineContent {
let layout_pair = STF::create(InitialScriptState { let layout_pair = STF::create(InitialScriptState {
id: self.id, id: self.id,
parent_info: self.parent_info, parent_info: self.parent_info,
compositor: self.script_to_compositor_chan,
control_chan: self.script_chan.clone(), control_chan: self.script_chan.clone(),
control_port: mem::replace(&mut self.script_port, None).expect("No script port."), control_port: mem::replace(&mut self.script_port, None).expect("No script port."),
constellation_chan: self.constellation_chan.clone(), constellation_chan: self.constellation_chan.clone(),
@ -467,7 +459,6 @@ impl UnprivilegedPipelineContent {
pub struct PrivilegedPipelineContent { pub struct PrivilegedPipelineContent {
id: PipelineId, id: PipelineId,
compositor_proxy: Box<CompositorProxy + Send + 'static>, compositor_proxy: Box<CompositorProxy + Send + 'static>,
script_to_compositor_port: IpcReceiver<ScriptToCompositorMsg>,
font_cache_thread: FontCacheThread, font_cache_thread: FontCacheThread,
time_profiler_chan: time::ProfilerChan, time_profiler_chan: time::ProfilerChan,
mem_profiler_chan: profile_mem::ProfilerChan, mem_profiler_chan: profile_mem::ProfilerChan,
@ -481,26 +472,7 @@ pub struct PrivilegedPipelineContent {
impl PrivilegedPipelineContent { impl PrivilegedPipelineContent {
pub fn start_all(self) { pub fn start_all(self) {
PaintThread::create(self.id, self.start_paint_thread();
self.load_data.url,
self.chrome_to_paint_chan,
self.layout_to_paint_port,
self.chrome_to_paint_port,
self.compositor_proxy.clone_compositor_proxy(),
self.panic_chan,
self.font_cache_thread,
self.time_profiler_chan,
self.mem_profiler_chan,
self.paint_shutdown_chan);
let compositor_proxy_for_script_listener_thread =
self.compositor_proxy.clone_compositor_proxy();
let script_to_compositor_port = self.script_to_compositor_port;
thread::spawn_named("CompositorScriptListener".to_owned(), move || {
compositor_thread::run_script_listener_thread(
compositor_proxy_for_script_listener_thread,
script_to_compositor_port)
});
} }
pub fn start_paint_thread(self) { pub fn start_paint_thread(self) {

View file

@ -106,8 +106,8 @@ use parse::{ParserRoot, ParserRef, MutNullableParserField};
use script_thread::{MainThreadScriptMsg, Runnable}; use script_thread::{MainThreadScriptMsg, Runnable};
use script_traits::UntrustedNodeAddress; use script_traits::UntrustedNodeAddress;
use script_traits::{AnimationState, MouseButton, MouseEventType, MozBrowserEvent}; use script_traits::{AnimationState, MouseButton, MouseEventType, MozBrowserEvent};
use script_traits::{ScriptMsg as ConstellationMsg, ScriptToCompositorMsg}; use script_traits::{ScriptMsg as ConstellationMsg, TouchpadPressurePhase};
use script_traits::{TouchpadPressurePhase, TouchEventType, TouchId}; use script_traits::{TouchEventType, TouchId};
use std::ascii::AsciiExt; use std::ascii::AsciiExt;
use std::borrow::ToOwned; use std::borrow::ToOwned;
use std::boxed::FnBox; use std::boxed::FnBox;
@ -636,8 +636,8 @@ impl Document {
/// Sends this document's title to the compositor. /// Sends this document's title to the compositor.
pub fn send_title_to_compositor(&self) { pub fn send_title_to_compositor(&self) {
let window = self.window(); let window = self.window();
let compositor = window.compositor(); window.constellation_chan()
compositor.send(ScriptToCompositorMsg::SetTitle(window.pipeline(), .send(ConstellationMsg::SetTitle(window.pipeline(),
Some(String::from(self.Title())))) Some(String::from(self.Title()))))
.unwrap(); .unwrap();
} }
@ -1049,7 +1049,7 @@ impl Document {
key: Key, key: Key,
state: KeyState, state: KeyState,
modifiers: KeyModifiers, modifiers: KeyModifiers,
compositor: &IpcSender<ScriptToCompositorMsg>) { constellation: &IpcSender<ConstellationMsg>) {
let focused = self.get_focused_element(); let focused = self.get_focused_element();
let body = self.GetBody(); let body = self.GetBody();
@ -1124,7 +1124,7 @@ impl Document {
} }
if !prevented { if !prevented {
compositor.send(ScriptToCompositorMsg::SendKeyEvent(key, state, modifiers)).unwrap(); constellation.send(ConstellationMsg::SendKeyEvent(key, state, modifiers)).unwrap();
} }
// This behavior is unspecced // This behavior is unspecced

View file

@ -62,7 +62,7 @@ use script_runtime::{ScriptChan, ScriptPort};
use script_thread::SendableMainThreadScriptChan; use script_thread::SendableMainThreadScriptChan;
use script_thread::{MainThreadScriptChan, MainThreadScriptMsg, RunnableWrapper}; use script_thread::{MainThreadScriptChan, MainThreadScriptMsg, RunnableWrapper};
use script_traits::{ConstellationControlMsg, UntrustedNodeAddress}; use script_traits::{ConstellationControlMsg, UntrustedNodeAddress};
use script_traits::{DocumentState, MsDuration, ScriptToCompositorMsg, TimerEvent, TimerEventId}; use script_traits::{DocumentState, MsDuration, TimerEvent, TimerEventId};
use script_traits::{ScriptMsg as ConstellationMsg, TimerEventRequest, TimerSource}; use script_traits::{ScriptMsg as ConstellationMsg, TimerEventRequest, TimerSource};
use std::ascii::AsciiExt; use std::ascii::AsciiExt;
use std::borrow::ToOwned; use std::borrow::ToOwned;
@ -153,8 +153,6 @@ pub struct Window {
image_cache_chan: ImageCacheChan, image_cache_chan: ImageCacheChan,
#[ignore_heap_size_of = "channels are hard"] #[ignore_heap_size_of = "channels are hard"]
custom_message_chan: IpcSender<CustomResponseSender>, custom_message_chan: IpcSender<CustomResponseSender>,
#[ignore_heap_size_of = "TODO(#6911) newtypes containing unmeasurable types are hard"]
compositor: IpcSender<ScriptToCompositorMsg>,
browsing_context: MutNullableHeap<JS<BrowsingContext>>, browsing_context: MutNullableHeap<JS<BrowsingContext>>,
performance: MutNullableHeap<JS<Performance>>, performance: MutNullableHeap<JS<Performance>>,
navigation_start: u64, navigation_start: u64,
@ -340,10 +338,6 @@ impl Window {
&self.image_cache_thread &self.image_cache_thread
} }
pub fn compositor(&self) -> &IpcSender<ScriptToCompositorMsg> {
&self.compositor
}
pub fn browsing_context(&self) -> Root<BrowsingContext> { pub fn browsing_context(&self) -> Root<BrowsingContext> {
self.browsing_context.get().unwrap() self.browsing_context.get().unwrap()
} }
@ -775,7 +769,7 @@ impl WindowMethods for Window {
// Step 1 // Step 1
//TODO determine if this operation is allowed //TODO determine if this operation is allowed
let size = Size2D::new(x.to_u32().unwrap_or(1), y.to_u32().unwrap_or(1)); let size = Size2D::new(x.to_u32().unwrap_or(1), y.to_u32().unwrap_or(1));
self.compositor.send(ScriptToCompositorMsg::ResizeTo(size)).unwrap() self.constellation_chan.send(ConstellationMsg::ResizeTo(size)).unwrap()
} }
// https://drafts.csswg.org/cssom-view/#dom-window-resizeby // https://drafts.csswg.org/cssom-view/#dom-window-resizeby
@ -790,7 +784,7 @@ impl WindowMethods for Window {
// Step 1 // Step 1
//TODO determine if this operation is allowed //TODO determine if this operation is allowed
let point = Point2D::new(x, y); let point = Point2D::new(x, y);
self.compositor.send(ScriptToCompositorMsg::MoveTo(point)).unwrap() self.constellation_chan.send(ConstellationMsg::MoveTo(point)).unwrap()
} }
// https://drafts.csswg.org/cssom-view/#dom-window-moveby // https://drafts.csswg.org/cssom-view/#dom-window-moveby
@ -976,13 +970,13 @@ impl Window {
let size = self.current_viewport.get().size; let size = self.current_viewport.get().size;
self.current_viewport.set(Rect::new(Point2D::new(Au::from_f32_px(x), Au::from_f32_px(y)), size)); self.current_viewport.set(Rect::new(Point2D::new(Au::from_f32_px(x), Au::from_f32_px(y)), size));
self.compositor.send(ScriptToCompositorMsg::ScrollFragmentPoint( let message = ConstellationMsg::ScrollFragmentPoint(self.pipeline(), layer_id, point, smooth);
self.pipeline(), layer_id, point, smooth)).unwrap() self.constellation_chan.send(message).unwrap();
} }
pub fn client_window(&self) -> (Size2D<u32>, Point2D<i32>) { pub fn client_window(&self) -> (Size2D<u32>, Point2D<i32>) {
let (send, recv) = ipc::channel::<(Size2D<u32>, Point2D<i32>)>().unwrap(); let (send, recv) = ipc::channel::<(Size2D<u32>, Point2D<i32>)>().unwrap();
self.compositor.send(ScriptToCompositorMsg::GetClientWindow(send)).unwrap(); self.constellation_chan.send(ConstellationMsg::GetClientWindow(send)).unwrap();
recv.recv().unwrap_or((Size2D::zero(), Point2D::zero())) recv.recv().unwrap_or((Size2D::zero(), Point2D::zero()))
} }
@ -1180,7 +1174,7 @@ impl Window {
let pipeline_id = self.id; let pipeline_id = self.id;
let (send, recv) = ipc::channel::<Point2D<f32>>().unwrap(); let (send, recv) = ipc::channel::<Point2D<f32>>().unwrap();
self.compositor.send(ScriptToCompositorMsg::GetScrollOffset(pipeline_id, layer_id, send)).unwrap(); self.constellation_chan.send(ConstellationMsg::GetScrollOffset(pipeline_id, layer_id, send)).unwrap();
recv.recv().unwrap_or(Point2D::zero()) recv.recv().unwrap_or(Point2D::zero())
} }
@ -1450,7 +1444,6 @@ impl Window {
file_task_source: FileReadingTaskSource, file_task_source: FileReadingTaskSource,
image_cache_chan: ImageCacheChan, image_cache_chan: ImageCacheChan,
custom_message_chan: IpcSender<CustomResponseSender>, custom_message_chan: IpcSender<CustomResponseSender>,
compositor: IpcSender<ScriptToCompositorMsg>,
image_cache_thread: ImageCacheThread, image_cache_thread: ImageCacheThread,
resource_threads: ResourceThreads, resource_threads: ResourceThreads,
bluetooth_thread: IpcSender<BluetoothMethodMsg>, bluetooth_thread: IpcSender<BluetoothMethodMsg>,
@ -1490,7 +1483,6 @@ impl Window {
custom_message_chan: custom_message_chan, custom_message_chan: custom_message_chan,
console: Default::default(), console: Default::default(),
crypto: Default::default(), crypto: Default::default(),
compositor: compositor,
navigator: Default::default(), navigator: Default::default(),
image_cache_thread: image_cache_thread, image_cache_thread: image_cache_thread,
mem_profiler_chan: mem_profiler_chan, mem_profiler_chan: mem_profiler_chan,

View file

@ -81,7 +81,7 @@ use script_traits::CompositorEvent::{TouchEvent, TouchpadPressureEvent};
use script_traits::{CompositorEvent, ConstellationControlMsg, EventResult}; use script_traits::{CompositorEvent, ConstellationControlMsg, EventResult};
use script_traits::{InitialScriptState, MouseButton, MouseEventType, MozBrowserEvent, NewLayoutInfo}; use script_traits::{InitialScriptState, MouseButton, MouseEventType, MozBrowserEvent, NewLayoutInfo};
use script_traits::{LayoutMsg, ScriptMsg as ConstellationMsg}; use script_traits::{LayoutMsg, ScriptMsg as ConstellationMsg};
use script_traits::{ScriptThreadFactory, ScriptToCompositorMsg, TimerEvent, TimerEventRequest, TimerSource}; use script_traits::{ScriptThreadFactory, TimerEvent, TimerEventRequest, TimerSource};
use script_traits::{TouchEventType, TouchId}; use script_traits::{TouchEventType, TouchId};
use std::borrow::ToOwned; use std::borrow::ToOwned;
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
@ -350,9 +350,6 @@ pub struct ScriptThread {
/// For communicating layout messages to the constellation /// For communicating layout messages to the constellation
layout_to_constellation_chan: IpcSender<LayoutMsg>, layout_to_constellation_chan: IpcSender<LayoutMsg>,
/// A handle to the compositor for communicating ready state messages.
compositor: IpcSender<ScriptToCompositorMsg>,
/// The port on which we receive messages from the image cache /// The port on which we receive messages from the image cache
image_cache_port: Receiver<ImageCacheResult>, image_cache_port: Receiver<ImageCacheResult>,
@ -465,7 +462,6 @@ impl ScriptThreadFactory for ScriptThread {
let reporter_name = format!("script-reporter-{}", id); let reporter_name = format!("script-reporter-{}", id);
mem_profiler_chan.run_with_memory_reporting(|| { mem_profiler_chan.run_with_memory_reporting(|| {
script_thread.start(); script_thread.start();
let _ = script_thread.compositor.send(ScriptToCompositorMsg::Exited);
let _ = script_thread.content_process_shutdown_chan.send(()); let _ = script_thread.content_process_shutdown_chan.send(());
}, reporter_name, script_chan, CommonScriptMsg::CollectReports); }, reporter_name, script_chan, CommonScriptMsg::CollectReports);
@ -577,7 +573,6 @@ impl ScriptThread {
control_port: control_port, control_port: control_port,
constellation_chan: state.constellation_chan, constellation_chan: state.constellation_chan,
layout_to_constellation_chan: state.layout_to_constellation_chan, layout_to_constellation_chan: state.layout_to_constellation_chan,
compositor: state.compositor,
time_profiler_chan: state.time_profiler_chan, time_profiler_chan: state.time_profiler_chan,
mem_profiler_chan: state.mem_profiler_chan, mem_profiler_chan: state.mem_profiler_chan,
panic_chan: state.panic_chan, panic_chan: state.panic_chan,
@ -1301,8 +1296,8 @@ impl ScriptThread {
// TODO(tkuehn): currently there is only one window, // TODO(tkuehn): currently there is only one window,
// so this can afford to be naive and just shut down the // so this can afford to be naive and just shut down the
// compositor. In the future it'll need to be smarter. // constellation. In the future it'll need to be smarter.
self.compositor.send(ScriptToCompositorMsg::Exit).unwrap(); self.constellation_chan.send(ConstellationMsg::Exit).unwrap();
} }
/// We have received notification that the response associated with a load has completed. /// We have received notification that the response associated with a load has completed.
@ -1459,7 +1454,6 @@ impl ScriptThread {
FileReadingTaskSource(file_sender.clone()), FileReadingTaskSource(file_sender.clone()),
self.image_cache_channel.clone(), self.image_cache_channel.clone(),
self.custom_message_chan.clone(), self.custom_message_chan.clone(),
self.compositor.clone(),
self.image_cache_thread.clone(), self.image_cache_thread.clone(),
self.resource_threads.clone(), self.resource_threads.clone(),
self.bluetooth_thread.clone(), self.bluetooth_thread.clone(),
@ -1682,8 +1676,11 @@ impl ScriptThread {
let point = Point2D::new(rect.origin.x.to_nearest_px() as f32, let point = Point2D::new(rect.origin.x.to_nearest_px() as f32,
rect.origin.y.to_nearest_px() as f32); rect.origin.y.to_nearest_px() as f32);
self.compositor.send(ScriptToCompositorMsg::ScrollFragmentPoint( let message = ConstellationMsg::ScrollFragmentPoint(pipeline_id,
pipeline_id, LayerId::null(), point, false)).unwrap(); LayerId::null(),
point,
false);
self.constellation_chan.send(message).unwrap();
} }
/// Reflows non-incrementally, rebuilding the entire layout tree in the process. /// Reflows non-incrementally, rebuilding the entire layout tree in the process.
@ -1768,16 +1765,14 @@ impl ScriptThread {
let handled = self.handle_touch_event(pipeline_id, event_type, identifier, point); let handled = self.handle_touch_event(pipeline_id, event_type, identifier, point);
match event_type { match event_type {
TouchEventType::Down => { TouchEventType::Down => {
if handled { let result = if handled {
// TODO: Wait to see if preventDefault is called on the first touchmove event. // TODO: Wait to see if preventDefault is called on the first touchmove event.
self.compositor EventResult::DefaultAllowed
.send(ScriptToCompositorMsg::TouchEventProcessed(
EventResult::DefaultAllowed)).unwrap();
} else { } else {
self.compositor EventResult::DefaultPrevented
.send(ScriptToCompositorMsg::TouchEventProcessed( };
EventResult::DefaultPrevented)).unwrap(); let message = ConstellationMsg::TouchEventProcessed(result);
} self.constellation_chan.send(message).unwrap();
} }
_ => { _ => {
// TODO: Calling preventDefault on a touchup event should prevent clicks. // TODO: Calling preventDefault on a touchup event should prevent clicks.
@ -1794,7 +1789,7 @@ impl ScriptThread {
KeyEvent(key, state, modifiers) => { KeyEvent(key, state, modifiers) => {
let context = get_browsing_context(&self.root_browsing_context(), pipeline_id); let context = get_browsing_context(&self.root_browsing_context(), pipeline_id);
let document = context.active_document(); let document = context.active_document();
document.dispatch_key_event(key, state, modifiers, &self.compositor); document.dispatch_key_event(key, state, modifiers, &self.constellation_chan);
} }
} }
} }

View file

@ -57,7 +57,7 @@ use std::sync::mpsc::{Sender, Receiver};
use url::Url; use url::Url;
use util::ipc::OptionalOpaqueIpcSender; use util::ipc::OptionalOpaqueIpcSender;
pub use script_msg::{LayoutMsg, ScriptMsg}; pub use script_msg::{LayoutMsg, ScriptMsg, EventResult};
/// The address of a node. Layout sends these back. They must be validated via /// The address of a node. Layout sends these back. They must be validated via
/// `from_untrusted_node_address` before they can be used, because we do not trust layout. /// `from_untrusted_node_address` before they can be used, because we do not trust layout.
@ -304,8 +304,6 @@ pub struct InitialScriptState {
/// The subpage ID of this pipeline to create in its pipeline parent. /// The subpage ID of this pipeline to create in its pipeline parent.
/// If `None`, this is the root. /// If `None`, this is the root.
pub parent_info: Option<(PipelineId, SubpageId)>, pub parent_info: Option<(PipelineId, SubpageId)>,
/// The compositor.
pub compositor: IpcSender<ScriptToCompositorMsg>,
/// A channel with which messages can be sent to us (the script thread). /// A channel with which messages can be sent to us (the script thread).
pub control_chan: IpcSender<ConstellationControlMsg>, pub control_chan: IpcSender<ConstellationControlMsg>,
/// A port on which messages sent by the constellation to script can be received. /// A port on which messages sent by the constellation to script can be received.
@ -349,41 +347,6 @@ pub trait ScriptThreadFactory {
-> (Sender<Self::Message>, Receiver<Self::Message>); -> (Sender<Self::Message>, Receiver<Self::Message>);
} }
/// Messages sent from the script thread to the compositor
#[derive(Deserialize, Serialize)]
pub enum ScriptToCompositorMsg {
/// Scroll a page in a window
ScrollFragmentPoint(PipelineId, LayerId, Point2D<f32>, bool),
/// Set title of current page
/// https://html.spec.whatwg.org/multipage/#document.title
SetTitle(PipelineId, Option<String>),
/// Send a key event
SendKeyEvent(Key, KeyState, KeyModifiers),
/// Get Window Informations size and position
GetClientWindow(IpcSender<(Size2D<u32>, Point2D<i32>)>),
/// Move the window to a point
MoveTo(Point2D<i32>),
/// Resize the window to size
ResizeTo(Size2D<u32>),
/// Script has handled a touch event, and either prevented or allowed default actions.
TouchEventProcessed(EventResult),
/// Get Scroll Offset
GetScrollOffset(PipelineId, LayerId, IpcSender<Point2D<f32>>),
/// Requests that the compositor shut down.
Exit,
/// Allow the compositor to free script-specific resources.
Exited,
}
/// Whether a DOM event was prevented by web content
#[derive(Deserialize, Serialize)]
pub enum EventResult {
/// Allowed by web content
DefaultAllowed,
/// Prevented by web content
DefaultPrevented,
}
/// Whether the sandbox attribute is present for an iframe element /// Whether the sandbox attribute is present for an iframe element
#[derive(PartialEq, Eq, Copy, Clone, Debug, Deserialize, Serialize)] #[derive(PartialEq, Eq, Copy, Clone, Debug, Deserialize, Serialize)]
pub enum IFrameSandboxState { pub enum IFrameSandboxState {

View file

@ -11,9 +11,10 @@ use MozBrowserEvent;
use canvas_traits::CanvasMsg; use canvas_traits::CanvasMsg;
use euclid::point::Point2D; use euclid::point::Point2D;
use euclid::size::Size2D; use euclid::size::Size2D;
use gfx_traits::LayerId;
use ipc_channel::ipc::IpcSender; use ipc_channel::ipc::IpcSender;
use msg::constellation_msg::{LoadData, SubpageId}; use msg::constellation_msg::{Key, KeyModifiers, KeyState, LoadData};
use msg::constellation_msg::{NavigationDirection, PipelineId}; use msg::constellation_msg::{NavigationDirection, PipelineId, SubpageId};
use offscreen_gl_context::{GLContextAttributes, GLLimits}; use offscreen_gl_context::{GLContextAttributes, GLLimits};
use style_traits::cursor::Cursor; use style_traits::cursor::Cursor;
use style_traits::viewport::ViewportConstraints; use style_traits::viewport::ViewportConstraints;
@ -30,6 +31,15 @@ pub enum LayoutMsg {
ViewportConstrained(PipelineId, ViewportConstraints), ViewportConstrained(PipelineId, ViewportConstraints),
} }
/// Whether a DOM event was prevented by web content
#[derive(Deserialize, Serialize)]
pub enum EventResult {
/// Allowed by web content
DefaultAllowed,
/// Prevented by web content
DefaultPrevented,
}
/// Messages from the script to the constellation. /// Messages from the script to the constellation.
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize)]
pub enum ScriptMsg { pub enum ScriptMsg {
@ -83,4 +93,23 @@ pub enum ScriptMsg {
SetFinalUrl(PipelineId, Url), SetFinalUrl(PipelineId, Url),
/// Check if an alert dialog box should be presented /// Check if an alert dialog box should be presented
Alert(PipelineId, String, IpcSender<bool>), Alert(PipelineId, String, IpcSender<bool>),
/// Scroll a page in a window
ScrollFragmentPoint(PipelineId, LayerId, Point2D<f32>, bool),
/// Set title of current page
/// https://html.spec.whatwg.org/multipage/#document.title
SetTitle(PipelineId, Option<String>),
/// Send a key event
SendKeyEvent(Key, KeyState, KeyModifiers),
/// Get Window Informations size and position
GetClientWindow(IpcSender<(Size2D<u32>, Point2D<i32>)>),
/// Move the window to a point
MoveTo(Point2D<i32>),
/// Resize the window to size
ResizeTo(Size2D<u32>),
/// Script has handled a touch event, and either prevented or allowed default actions.
TouchEventProcessed(EventResult),
/// Get Scroll Offset
GetScrollOffset(PipelineId, LayerId, IpcSender<Point2D<f32>>),
/// Requests that the compositor shut down.
Exit,
} }