servo: Merge #3318 - Store content offset in unscaled pixels (from mrobinson:scrolling)

Source-Repo: https://github.com/servo/servo
Source-Revision: ffd126a0ffa5fc813659d3e8e27dc9b5bfe59844
This commit is contained in:
Martin Robinson 2014-09-16 13:00:44 -07:00
Родитель cfb6235268
Коммит 361b24e470
5 изменённых файлов: 89 добавлений и 100 удалений

10
servo/Cargo.lock сгенерированный
Просмотреть файл

@ -33,7 +33,7 @@ dependencies = [
"freetype 0.1.0 (git+https://github.com/servo/rust-freetype#fb15dd309750c8ec664b2c9f245cfcb06731872e)",
"geom 0.1.0 (git+https://github.com/servo/rust-geom#2982b770db6e5e3270305e0fd6b8068f6f80a489)",
"glfw 0.0.1 (git+https://github.com/servo/glfw-rs?ref=servo#dd1a111c827994886d2cdebf91a1838603256390)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers#c04029907be1f2242d48235d3b03608b905bbd9f)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers#e29c5cd670a0b42e8ac50e7099c265c481640dd5)",
"opengles 0.1.0 (git+https://github.com/servo/rust-opengles#13cccda11011716fd75526a74dfd03122110f95a)",
"skia-sys 0.0.20130412 (git+https://github.com/servo/skia#6d696712962fd0d41120b7a414a48417da8e6a92)",
"xlib 0.1.0 (git+https://github.com/servo/rust-xlib#79904fb42ff8a0e888f70fae336fbf6c11f1e6c8)",
@ -64,7 +64,7 @@ dependencies = [
"gfx 0.0.1",
"glfw 0.0.1 (git+https://github.com/servo/glfw-rs?ref=servo#dd1a111c827994886d2cdebf91a1838603256390)",
"glut 0.0.1 (git+https://github.com/servo/rust-glut#d351eed425464c58671c6ec33445ee896fd42ff1)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers#c04029907be1f2242d48235d3b03608b905bbd9f)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers#e29c5cd670a0b42e8ac50e7099c265c481640dd5)",
"layout_traits 0.0.1",
"msg 0.0.1",
"net 0.0.1",
@ -164,7 +164,7 @@ dependencies = [
"freetype 0.1.0 (git+https://github.com/servo/rust-freetype#fb15dd309750c8ec664b2c9f245cfcb06731872e)",
"geom 0.1.0 (git+https://github.com/servo/rust-geom#2982b770db6e5e3270305e0fd6b8068f6f80a489)",
"harfbuzz 0.1.0 (git+https://github.com/servo/rust-harfbuzz#a502be3df659cd13bac0e62638f4dac3dfb2f52d)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers#c04029907be1f2242d48235d3b03608b905bbd9f)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers#e29c5cd670a0b42e8ac50e7099c265c481640dd5)",
"macros 0.0.1",
"msg 0.0.1",
"net 0.0.1",
@ -243,7 +243,7 @@ dependencies = [
[[package]]
name = "layers"
version = "0.1.0"
source = "git+https://github.com/servo/rust-layers#c04029907be1f2242d48235d3b03608b905bbd9f"
source = "git+https://github.com/servo/rust-layers#e29c5cd670a0b42e8ac50e7099c265c481640dd5"
dependencies = [
"core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation#9aeaee0bceb3241d6efca07cc6b82747339ffbff)",
"egl 0.1.0 (git+https://github.com/servo/rust-egl#48b85e30d557ab2ee536730a73dd86a8160d618b)",
@ -303,7 +303,7 @@ dependencies = [
"core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation#9aeaee0bceb3241d6efca07cc6b82747339ffbff)",
"geom 0.1.0 (git+https://github.com/servo/rust-geom#2982b770db6e5e3270305e0fd6b8068f6f80a489)",
"io_surface 0.1.0 (git+https://github.com/servo/rust-io-surface#05f102273e16e9432245f813e5fe6280087e2b44)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers#c04029907be1f2242d48235d3b03608b905bbd9f)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers#e29c5cd670a0b42e8ac50e7099c265c481640dd5)",
"url 0.1.0 (git+https://github.com/servo/rust-url#678bb4d52638b1cfdab78ef8e521566c9240fb1a)",
"util 0.0.1",
]

Просмотреть файл

@ -22,7 +22,6 @@ use windowing::PinchZoomWindowEvent;
use azure::azure_hl::SourceSurfaceMethods;
use azure::azure_hl;
use std::cmp;
use geom::matrix::identity;
use geom::point::{Point2D, TypedPoint2D};
use geom::rect::Rect;
use geom::size::TypedSize2D;
@ -159,7 +158,7 @@ impl IOCompositor {
context: rendergl::RenderContext::new(CompositorTask::create_graphics_context(),
show_debug_borders),
root_pipeline: None,
scene: Scene::new(window_size.as_f32().to_untyped(), identity()),
scene: Scene::new(window_size.as_f32().to_untyped()),
window_size: window_size,
hidpi_factor: hidpi_factor,
composite_ready: false,
@ -543,26 +542,41 @@ impl IOCompositor {
}));
}
pub fn move_layer(&self,
pipeline_id: PipelineId,
layer_id: LayerId,
origin: TypedPoint2D<DevicePixel, f32>)
-> bool {
match self.find_layer_with_pipeline_and_layer_id(pipeline_id, layer_id) {
Some(ref layer) => {
if layer.extra_data.borrow().wants_scroll_events == WantsScrollEvents {
events::clamp_scroll_offset_and_scroll_layer(layer.clone(),
TypedPoint2D(0f32, 0f32) - origin,
self.window_size.as_f32(),
self.device_pixels_per_page_px());
}
true
}
None => false,
}
}
fn scroll_layer_to_fragment_point_if_necessary(&mut self,
pipeline_id: PipelineId,
layer_id: LayerId) {
let device_pixels_per_page_px = self.device_pixels_per_page_px();
let window_size = self.window_size.as_f32();
let needs_recomposite = match self.scene.root {
Some(ref mut root_layer) => {
self.fragment_point.take().map_or(false, |fragment_point| {
let fragment_point = fragment_point * device_pixels_per_page_px.get();
events::move(root_layer.clone(),
pipeline_id,
layer_id,
Point2D::from_untyped(&fragment_point),
window_size)
})
}
None => fail!("Compositor: Tried to scroll to fragment without root layer."),
};
match self.fragment_point.take() {
Some(point) => {
let point = point * device_pixels_per_page_px.get();
if !self.move_layer(pipeline_id, layer_id, Point2D::from_untyped(&point)) {
fail!("Compositor: Tried to scroll to fragment with unknown layer.");
}
self.recomposite_if(needs_recomposite);
self.recomposite = true;
}
None => {}
};
}
fn set_layer_origin(&mut self,
@ -610,30 +624,13 @@ impl IOCompositor {
pipeline_id: PipelineId,
layer_id: LayerId,
point: Point2D<f32>) {
let device_pixels_per_page_px = self.device_pixels_per_page_px();
let device_point = point * device_pixels_per_page_px.get();
let window_size = self.window_size.as_f32();
let (ask, move): (bool, bool) = match self.scene.root {
Some(ref layer) if layer.extra_data.borrow().pipeline.id == pipeline_id => {
(true,
events::move(layer.clone(),
pipeline_id,
layer_id,
Point2D::from_untyped(&device_point),
window_size))
}
Some(_) | None => {
self.fragment_point = Some(point);
(false, false)
}
};
if ask {
self.recomposite_if(move);
if self.move_layer(pipeline_id, layer_id, Point2D::from_untyped(&device_point)) {
self.recomposite = true;
self.send_buffer_requests_for_all_layers();
} else {
self.fragment_point = Some(point);
}
}
@ -750,12 +747,14 @@ impl IOCompositor {
cursor: TypedPoint2D<DevicePixel, i32>) {
let mut scroll = false;
let window_size = self.window_size.as_f32();
let scene_scale = self.device_pixels_per_page_px();
match self.scene.root {
Some(ref mut layer) => {
scroll = events::handle_scroll_event(layer.clone(),
delta,
cursor.as_f32(),
window_size) || scroll;
window_size,
scene_scale) || scroll;
}
None => { }
}
@ -779,7 +778,7 @@ impl IOCompositor {
fn update_zoom_transform(&mut self) {
let scale = self.device_pixels_per_page_px();
self.scene.transform = identity().scale(scale.get(), scale.get(), 1f32);
self.scene.scale = scale.get();
}
fn on_zoom_window_event(&mut self, magnification: f32) {
@ -806,12 +805,14 @@ impl IOCompositor {
let delta = page_delta * self.device_pixels_per_page_px();
let cursor = TypedPoint2D(-1f32, -1f32); // Make sure this hits the base layer.
let scene_scale = self.device_pixels_per_page_px();
match self.scene.root {
Some(ref mut layer) => {
events::handle_scroll_event(layer.clone(),
delta,
cursor,
window_size);
window_size,
scene_scale);
}
None => { }
}

Просмотреть файл

@ -8,6 +8,7 @@ use pipeline::CompositionPipeline;
use azure::azure_hl::Color;
use geom::point::TypedPoint2D;
use geom::scale_factor::ScaleFactor;
use geom::size::{Size2D, TypedSize2D};
use geom::rect::Rect;
use gfx::render_task::UnusedBufferMsg;
@ -74,11 +75,13 @@ impl CompositorData {
layer.contents_changed();
// Call scroll for bounds checking if the page shrunk. Use (-1, -1) as the
// cursor position to make sure the scroll isn't propagated downwards.
// cursor position to make sure the scroll isn't propagated downwards. The
// scale doesn't matter here since 0, 0 is 0, 0 no matter the scene scale.
events::handle_scroll_event(layer.clone(),
TypedPoint2D(0f32, 0f32),
TypedPoint2D(-1f32, -1f32),
size);
size,
ScaleFactor(1.0) /* scene_scale */);
}
pub fn find_layer_with_pipeline_and_layer_id(layer: Rc<Layer<CompositorData>>,

Просмотреть файл

@ -7,15 +7,14 @@ use windowing::{MouseWindowEvent, MouseWindowClickEvent, MouseWindowMouseDownEve
use windowing::MouseWindowMouseUpEvent;
use geom::length::Length;
use geom::point::TypedPoint2D;
use geom::point::{Point2D, TypedPoint2D};
use geom::scale_factor::ScaleFactor;
use geom::size::TypedSize2D;
use layers::geometry::DevicePixel;
use layers::layers::Layer;
use script_traits::{ClickEvent, MouseDownEvent, MouseMoveEvent, MouseUpEvent, SendEventMsg};
use script_traits::{ScriptControlChan};
use servo_msg::compositor_msg::{FixedPosition, LayerId};
use servo_msg::constellation_msg::PipelineId;
use servo_msg::compositor_msg::FixedPosition;
use servo_util::geometry::PagePx;
use std::rc::Rc;
@ -47,7 +46,8 @@ impl Clampable for f32 {
pub fn handle_scroll_event(layer: Rc<Layer<CompositorData>>,
delta: TypedPoint2D<DevicePixel, f32>,
cursor: TypedPoint2D<DevicePixel, f32>,
window_size: TypedSize2D<DevicePixel, f32>)
window_size: TypedSize2D<DevicePixel, f32>,
scale: ScaleFactor<PagePx, DevicePixel, f32>)
-> bool {
// If this layer doesn't want scroll events, neither it nor its children can handle scroll
// events.
@ -56,53 +56,60 @@ pub fn handle_scroll_event(layer: Rc<Layer<CompositorData>>,
}
// Allow children to scroll.
let content_offset = layer.content_offset.borrow().clone();
let cursor = cursor - content_offset;
let content_offset_in_page_pixels : TypedPoint2D<PagePx, f32> =
Point2D::from_untyped(&*layer.content_offset.borrow());
let content_offset : TypedPoint2D<DevicePixel, f32> = content_offset_in_page_pixels * scale;
let new_cursor = cursor - content_offset;
for child in layer.children().iter() {
let child_bounds = child.bounds.borrow();
if child_bounds.contains(&cursor) &&
if child_bounds.contains(&new_cursor) &&
handle_scroll_event(child.clone(),
delta,
cursor - child_bounds.origin,
child_bounds.size) {
new_cursor - child_bounds.origin,
child_bounds.size,
scale) {
return true
}
}
clamp_scroll_offset_and_scroll_layer(layer, content_offset + delta, window_size)
clamp_scroll_offset_and_scroll_layer(layer, content_offset + delta, window_size, scale)
}
pub fn clamp_scroll_offset_and_scroll_layer(layer: Rc<Layer<CompositorData>>,
mut new_offset: TypedPoint2D<DevicePixel, f32>,
window_size: TypedSize2D<DevicePixel, f32>)
new_offset: TypedPoint2D<DevicePixel, f32>,
window_size: TypedSize2D<DevicePixel, f32>,
scale: ScaleFactor<PagePx, DevicePixel, f32>)
-> bool {
let layer_size = layer.bounds.borrow().size;
let min_x = (window_size.width - layer_size.width).get().min(0.0);
new_offset.x = Length(new_offset.x.get().clamp(&min_x, &0.0));
let min_y = (window_size.height - layer_size.height).get().min(0.0);
new_offset.y = Length(new_offset.y.get().clamp(&min_y, &0.0));
let new_offset : TypedPoint2D<DevicePixel, f32> =
Point2D(Length(new_offset.x.get().clamp(&min_x, &0.0)),
Length(new_offset.y.get().clamp(&min_y, &0.0)));
if *layer.content_offset.borrow() == new_offset {
let new_offset_in_page_px = new_offset / scale;
let untyped_new_offset = new_offset_in_page_px.to_untyped();
if *layer.content_offset.borrow() == untyped_new_offset {
return false
}
// FIXME: This allows the base layer to record the current content offset without
// updating its transform. This should be replaced with something less strange.
*layer.content_offset.borrow_mut() = new_offset;
scroll_layer_and_all_child_layers(layer.clone(), new_offset)
*layer.content_offset.borrow_mut() = untyped_new_offset;
scroll_layer_and_all_child_layers(layer.clone(), new_offset_in_page_px)
}
fn scroll_layer_and_all_child_layers(layer: Rc<Layer<CompositorData>>,
new_offset: TypedPoint2D<DevicePixel, f32>)
new_offset: TypedPoint2D<PagePx, f32>)
-> bool {
let mut result = false;
// Only scroll this layer if it's not fixed-positioned.
if layer.extra_data.borrow().scroll_policy != FixedPosition {
*layer.transform.borrow_mut() = identity().translate(new_offset.x.get(),
new_offset.y.get(),
let new_offset = new_offset.to_untyped();
*layer.transform.borrow_mut() = identity().translate(new_offset.x,
new_offset.y,
0.0);
*layer.content_offset.borrow_mut() = new_offset;
result = true
@ -122,7 +129,9 @@ pub fn send_mouse_event(layer: Rc<Layer<CompositorData>>,
event: MouseWindowEvent,
cursor: TypedPoint2D<DevicePixel, f32>,
device_pixels_per_page_px: ScaleFactor<PagePx, DevicePixel, f32>) {
let cursor = cursor - *layer.content_offset.borrow();
let content_offset = *layer.content_offset.borrow() * device_pixels_per_page_px.get();
let content_offset : TypedPoint2D<DevicePixel, f32> = Point2D::from_untyped(&content_offset);
let cursor = cursor - content_offset;
for child in layer.children().iter() {
let child_bounds = child.bounds.borrow();
if child_bounds.contains(&cursor) {
@ -152,27 +161,3 @@ pub fn send_mouse_move_event(layer: Rc<Layer<CompositorData>>,
let _ = chan.send_opt(SendEventMsg(layer.extra_data.borrow().pipeline.id.clone(), message));
}
pub fn move(layer: Rc<Layer<CompositorData>>,
pipeline_id: PipelineId,
layer_id: LayerId,
origin: TypedPoint2D<DevicePixel, f32>,
window_size: TypedSize2D<DevicePixel, f32>)
-> bool {
// Search children for the right layer to move.
if layer.extra_data.borrow().pipeline.id != pipeline_id ||
layer.extra_data.borrow().id != layer_id {
return layer.children().iter().any(|kid| {
move(kid.clone(),
pipeline_id,
layer_id,
origin,
window_size)
});
}
if layer.extra_data.borrow().wants_scroll_events != WantsScrollEvents {
return false
}
clamp_scroll_offset_and_scroll_layer(layer, TypedPoint2D(0f32, 0f32) - origin, window_size)
}

12
servo/ports/cef/Cargo.lock сгенерированный
Просмотреть файл

@ -10,7 +10,7 @@ dependencies = [
"glfw 0.0.1 (git+https://github.com/servo/glfw-rs?ref=servo#a646f0badaccaebd61d0f8aaec5646da0a7c2a14)",
"glut 0.0.1 (git+https://github.com/servo/rust-glut#d351eed425464c58671c6ec33445ee896fd42ff1)",
"js 0.1.0 (git+https://github.com/servo/rust-mozjs#c9bd679428e8e83e585702a949d593bda8ac04d6)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers#c04029907be1f2242d48235d3b03608b905bbd9f)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers#e29c5cd670a0b42e8ac50e7099c265c481640dd5)",
"macros 0.0.1",
"msg 0.0.1",
"net 0.0.1",
@ -45,7 +45,7 @@ dependencies = [
"freetype 0.1.0 (git+https://github.com/servo/rust-freetype#fb15dd309750c8ec664b2c9f245cfcb06731872e)",
"geom 0.1.0 (git+https://github.com/servo/rust-geom#2982b770db6e5e3270305e0fd6b8068f6f80a489)",
"glfw 0.0.1 (git+https://github.com/servo/glfw-rs?ref=servo#a646f0badaccaebd61d0f8aaec5646da0a7c2a14)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers#c04029907be1f2242d48235d3b03608b905bbd9f)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers#e29c5cd670a0b42e8ac50e7099c265c481640dd5)",
"opengles 0.1.0 (git+https://github.com/servo/rust-opengles#13cccda11011716fd75526a74dfd03122110f95a)",
"skia-sys 0.0.20130412 (git+https://github.com/servo/skia#6d696712962fd0d41120b7a414a48417da8e6a92)",
"xlib 0.1.0 (git+https://github.com/servo/rust-xlib#79904fb42ff8a0e888f70fae336fbf6c11f1e6c8)",
@ -76,7 +76,7 @@ dependencies = [
"gfx 0.0.1",
"glfw 0.0.1 (git+https://github.com/servo/glfw-rs?ref=servo#a646f0badaccaebd61d0f8aaec5646da0a7c2a14)",
"glut 0.0.1 (git+https://github.com/servo/rust-glut#d351eed425464c58671c6ec33445ee896fd42ff1)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers#c04029907be1f2242d48235d3b03608b905bbd9f)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers#e29c5cd670a0b42e8ac50e7099c265c481640dd5)",
"layout_traits 0.0.1",
"msg 0.0.1",
"net 0.0.1",
@ -176,7 +176,7 @@ dependencies = [
"freetype 0.1.0 (git+https://github.com/servo/rust-freetype#fb15dd309750c8ec664b2c9f245cfcb06731872e)",
"geom 0.1.0 (git+https://github.com/servo/rust-geom#2982b770db6e5e3270305e0fd6b8068f6f80a489)",
"harfbuzz 0.1.0 (git+https://github.com/servo/rust-harfbuzz#a502be3df659cd13bac0e62638f4dac3dfb2f52d)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers#c04029907be1f2242d48235d3b03608b905bbd9f)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers#e29c5cd670a0b42e8ac50e7099c265c481640dd5)",
"macros 0.0.1",
"msg 0.0.1",
"net 0.0.1",
@ -255,7 +255,7 @@ dependencies = [
[[package]]
name = "layers"
version = "0.1.0"
source = "git+https://github.com/servo/rust-layers#c04029907be1f2242d48235d3b03608b905bbd9f"
source = "git+https://github.com/servo/rust-layers#e29c5cd670a0b42e8ac50e7099c265c481640dd5"
dependencies = [
"core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation#9aeaee0bceb3241d6efca07cc6b82747339ffbff)",
"egl 0.1.0 (git+https://github.com/servo/rust-egl#48b85e30d557ab2ee536730a73dd86a8160d618b)",
@ -314,7 +314,7 @@ dependencies = [
"core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation#9aeaee0bceb3241d6efca07cc6b82747339ffbff)",
"geom 0.1.0 (git+https://github.com/servo/rust-geom#2982b770db6e5e3270305e0fd6b8068f6f80a489)",
"io_surface 0.1.0 (git+https://github.com/servo/rust-io-surface#05f102273e16e9432245f813e5fe6280087e2b44)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers#c04029907be1f2242d48235d3b03608b905bbd9f)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers#e29c5cd670a0b42e8ac50e7099c265c481640dd5)",
"url 0.1.0 (git+https://github.com/servo/rust-url#678bb4d52638b1cfdab78ef8e521566c9240fb1a)",
"util 0.0.1",
]