mirror of
https://github.com/servo/servo.git
synced 2025-08-01 19:50:30 +01:00
script: Keep the DOM-side viewport up to date when scrolling happens in
WebRender. This happens asynchronously, just as it does in non-WebRender mode. This functionality is a prerequisite for doing proper display-list-based hit testing in WebRender, since it moves the scroll offsets into Servo (and, specifically, into the script thread, enabling iframe event forwarding) instead of keeping them private to WebRender. Requires servo/webrender_traits#55 and servo/webrender#277. Partially addresses #11108.
This commit is contained in:
parent
55b0bb027c
commit
a86f77e36d
32 changed files with 318 additions and 99 deletions
|
@ -995,13 +995,18 @@ impl Window {
|
|||
};
|
||||
|
||||
// TODO (farodin91): Raise an event to stop the current_viewport
|
||||
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.update_viewport_for_scroll(x, y);
|
||||
|
||||
let message = ConstellationMsg::ScrollFragmentPoint(self.pipeline(), layer_id, point, smooth);
|
||||
self.constellation_chan.send(message).unwrap();
|
||||
}
|
||||
|
||||
pub fn update_viewport_for_scroll(&self, x: f32, y: f32) {
|
||||
let size = self.current_viewport.get().size;
|
||||
let new_viewport = Rect::new(Point2D::new(Au::from_f32_px(x), Au::from_f32_px(y)), size);
|
||||
self.current_viewport.set(new_viewport)
|
||||
}
|
||||
|
||||
pub fn client_window(&self) -> (Size2D<u32>, Point2D<i32>) {
|
||||
let (send, recv) = ipc::channel::<(Size2D<u32>, Point2D<i32>)>().unwrap();
|
||||
self.constellation_chan.send(ConstellationMsg::GetClientWindow(send)).unwrap();
|
||||
|
|
|
@ -15,8 +15,8 @@ use ipc_channel::ipc::{IpcReceiver, IpcSender};
|
|||
use msg::constellation_msg::{PanicMsg, PipelineId, WindowSizeData};
|
||||
use net_traits::image_cache_thread::ImageCacheThread;
|
||||
use profile_traits::mem::ReportsChan;
|
||||
use script_traits::UntrustedNodeAddress;
|
||||
use script_traits::{ConstellationControlMsg, LayoutControlMsg, LayoutMsg as ConstellationMsg};
|
||||
use script_traits::{StackingContextScrollState, UntrustedNodeAddress};
|
||||
use std::sync::Arc;
|
||||
use std::sync::mpsc::{Receiver, Sender};
|
||||
use string_cache::Atom;
|
||||
|
@ -85,6 +85,9 @@ pub enum Msg {
|
|||
|
||||
/// Set the final Url.
|
||||
SetFinalUrl(Url),
|
||||
|
||||
/// Tells layout about the new scrolling offsets of each scrollable stacking context.
|
||||
SetStackingContextScrollStates(Vec<StackingContextScrollState>),
|
||||
}
|
||||
|
||||
/// Synchronous messages that script can send to layout.
|
||||
|
|
|
@ -62,6 +62,7 @@ pub enum ScriptThreadEventCategory {
|
|||
NetworkEvent,
|
||||
Resize,
|
||||
ScriptEvent,
|
||||
SetScrollState,
|
||||
SetViewport,
|
||||
StylesheetLoad,
|
||||
TimerEvent,
|
||||
|
|
|
@ -708,6 +708,11 @@ impl ScriptThread {
|
|||
self.handle_viewport(id, rect);
|
||||
})
|
||||
}
|
||||
FromConstellation(ConstellationControlMsg::SetScrollState(id, scroll_offset)) => {
|
||||
self.profile_event(ScriptThreadEventCategory::SetScrollState, || {
|
||||
self.handle_set_scroll_state(id, &scroll_offset);
|
||||
})
|
||||
}
|
||||
FromConstellation(ConstellationControlMsg::TickAllAnimations(
|
||||
pipeline_id)) => {
|
||||
if !animation_ticks.contains(&pipeline_id) {
|
||||
|
@ -850,6 +855,9 @@ impl ScriptThread {
|
|||
ScriptThreadEventCategory::NetworkEvent => ProfilerCategory::ScriptNetworkEvent,
|
||||
ScriptThreadEventCategory::Resize => ProfilerCategory::ScriptResize,
|
||||
ScriptThreadEventCategory::ScriptEvent => ProfilerCategory::ScriptEvent,
|
||||
ScriptThreadEventCategory::SetScrollState => {
|
||||
ProfilerCategory::ScriptSetScrollState
|
||||
}
|
||||
ScriptThreadEventCategory::UpdateReplacedElement => {
|
||||
ProfilerCategory::ScriptUpdateReplacedElement
|
||||
}
|
||||
|
@ -877,6 +885,8 @@ impl ScriptThread {
|
|||
self.handle_resize_inactive_msg(id, new_size),
|
||||
ConstellationControlMsg::Viewport(..) =>
|
||||
panic!("should have handled Viewport already"),
|
||||
ConstellationControlMsg::SetScrollState(..) =>
|
||||
panic!("should have handled SetScrollState already"),
|
||||
ConstellationControlMsg::Resize(..) =>
|
||||
panic!("should have handled Resize already"),
|
||||
ConstellationControlMsg::ExitPipeline(..) =>
|
||||
|
@ -1077,6 +1087,19 @@ impl ScriptThread {
|
|||
panic!("Page rect message sent to nonexistent pipeline");
|
||||
}
|
||||
|
||||
fn handle_set_scroll_state(&self, id: PipelineId, scroll_state: &Point2D<f32>) {
|
||||
let context = self.browsing_context.get();
|
||||
if let Some(context) = context {
|
||||
if let Some(inner_context) = context.find(id) {
|
||||
let window = inner_context.active_window();
|
||||
window.update_viewport_for_scroll(-scroll_state.x, -scroll_state.y);
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
panic!("Set scroll state message message sent to nonexistent pipeline: {:?}", id);
|
||||
}
|
||||
|
||||
fn handle_new_layout(&self, new_layout_info: NewLayoutInfo) {
|
||||
let NewLayoutInfo {
|
||||
containing_pipeline_id,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue