diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2016-03-15 00:18:05 +0530 |
---|---|---|
committer | bors-servo <lbergstrom+bors@mozilla.com> | 2016-03-15 00:18:05 +0530 |
commit | 881d6b4220f2391a22d4ea73b79415071626501f (patch) | |
tree | 75327e9b61f0d0f348144e3cc355d231514f3f78 | |
parent | 6895dab07ca1ff61579e9f7cd287b68f1a92f9d3 (diff) | |
parent | 8eb2cda4387baa28d0f43480348efe51c4507889 (diff) | |
download | servo-881d6b4220f2391a22d4ea73b79415071626501f.tar.gz servo-881d6b4220f2391a22d4ea73b79415071626501f.zip |
Auto merge of #9851 - pcwalton:overscroll, r=glennw
Implement support for overscrolling on the Mac.
Requires tomaka/glutin#734, servo/webrender_traits#14, and
servo/webrender#217.
r? whoever (waiting on the landing of the above)
<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.svg" height="40" alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/9851)
<!-- Reviewable:end -->
-rw-r--r-- | components/compositing/compositor.rs | 105 | ||||
-rw-r--r-- | components/compositing/windowing.rs | 2 | ||||
-rw-r--r-- | components/servo/Cargo.lock | 10 | ||||
-rw-r--r-- | ports/cef/Cargo.lock | 10 | ||||
-rw-r--r-- | ports/cef/browser_host.rs | 6 | ||||
-rw-r--r-- | ports/glutin/window.rs | 57 | ||||
-rw-r--r-- | ports/gonk/Cargo.lock | 8 | ||||
-rw-r--r-- | ports/gonk/src/input.rs | 5 |
8 files changed, 153 insertions, 50 deletions
diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index 793c72a5c0b..1a64c4bb8fb 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -53,7 +53,7 @@ use util::geometry::{PagePx, ScreenPx, ViewportPx}; use util::opts; use util::print_tree::PrintTree; use webrender; -use webrender_traits; +use webrender_traits::{self, ScrollEventPhase}; use windowing::{self, MouseWindowEvent, WindowEvent, WindowMethods, WindowNavigateMsg}; #[derive(Debug, PartialEq)] @@ -196,6 +196,9 @@ pub struct IOCompositor<Window: WindowMethods> { /// The id of the pipeline that was last sent a mouse move event, if any. last_mouse_move_recipient: Option<PipelineId>, + /// Whether a scroll is in progress; i.e. whether the user's fingers are down. + scroll_in_progress: bool, + /// The webrender renderer, if enabled. webrender: Option<webrender::Renderer>, @@ -203,6 +206,7 @@ pub struct IOCompositor<Window: WindowMethods> { webrender_api: Option<webrender_traits::RenderApi>, } +#[derive(Copy, Clone)] pub struct ScrollZoomEvent { /// Change the pinch zoom level by this factor magnification: f32, @@ -210,6 +214,8 @@ pub struct ScrollZoomEvent { delta: TypedPoint2D<DevicePixel, f32>, /// Apply changes to the frame at this location cursor: TypedPoint2D<DevicePixel, i32>, + /// The scroll event phase. + phase: ScrollEventPhase, } #[derive(PartialEq, Debug)] @@ -427,6 +433,7 @@ impl<Window: WindowMethods> IOCompositor<Window> { surface_map: SurfaceMap::new(BUFFER_MAP_SIZE), pending_subpages: HashSet::new(), last_mouse_move_recipient: None, + scroll_in_progress: false, webrender: state.webrender, webrender_api: webrender_api, } @@ -1184,8 +1191,16 @@ impl<Window: WindowMethods> IOCompositor<Window> { } } - WindowEvent::Scroll(delta, cursor) => { - self.on_scroll_window_event(delta, cursor); + WindowEvent::Scroll(delta, cursor, phase) => { + match phase { + TouchEventType::Move => self.on_scroll_window_event(delta, cursor), + TouchEventType::Up | TouchEventType::Cancel => { + self.on_scroll_end_window_event(delta, cursor); + } + TouchEventType::Down => { + self.on_scroll_start_window_event(delta, cursor); + } + } } WindowEvent::Zoom(magnification) => { @@ -1368,6 +1383,7 @@ impl<Window: WindowMethods> IOCompositor<Window> { magnification: magnification, delta: scroll_delta, cursor: cursor, + phase: ScrollEventPhase::Move(true), }); self.composite_if_necessary(CompositingReason::Zoom); } @@ -1421,8 +1437,34 @@ impl<Window: WindowMethods> IOCompositor<Window> { magnification: 1.0, delta: delta, cursor: cursor, + phase: ScrollEventPhase::Move(self.scroll_in_progress), }); + self.composite_if_necessary(CompositingReason::Scroll); + } + fn on_scroll_start_window_event(&mut self, + delta: TypedPoint2D<DevicePixel, f32>, + cursor: TypedPoint2D<DevicePixel, i32>) { + self.scroll_in_progress = true; + self.pending_scroll_zoom_events.push(ScrollZoomEvent { + magnification: 1.0, + delta: delta, + cursor: cursor, + phase: ScrollEventPhase::Start, + }); + self.composite_if_necessary(CompositingReason::Scroll); + } + + fn on_scroll_end_window_event(&mut self, + delta: TypedPoint2D<DevicePixel, f32>, + cursor: TypedPoint2D<DevicePixel, i32>) { + self.scroll_in_progress = false; + self.pending_scroll_zoom_events.push(ScrollZoomEvent { + magnification: 1.0, + delta: delta, + cursor: cursor, + phase: ScrollEventPhase::End, + }); self.composite_if_necessary(CompositingReason::Scroll); } @@ -1432,19 +1474,41 @@ impl<Window: WindowMethods> IOCompositor<Window> { match self.webrender_api { Some(ref webrender_api) => { // Batch up all scroll events into one, or else we'll do way too much painting. - let mut total_delta = None; - let mut last_cursor = Point2D::zero(); + let mut last_combined_event: Option<ScrollZoomEvent> = None; for scroll_event in self.pending_scroll_zoom_events.drain(..) { - let this_delta = scroll_event.delta / self.scene.scale; - last_cursor = scroll_event.cursor.as_f32() / self.scene.scale; - match total_delta { - None => total_delta = Some(this_delta), - Some(ref mut total_delta) => *total_delta = *total_delta + this_delta, + let this_delta = scroll_event.delta; + let this_cursor = scroll_event.cursor; + if let Some(combined_event) = last_combined_event { + if combined_event.phase != scroll_event.phase { + webrender_api.scroll( + (combined_event.delta / self.scene.scale).to_untyped(), + (combined_event.cursor.as_f32() / self.scene.scale).to_untyped(), + combined_event.phase); + last_combined_event = None + } + } + + match last_combined_event { + None => { + last_combined_event = Some(ScrollZoomEvent { + magnification: scroll_event.magnification, + delta: this_delta, + cursor: this_cursor, + phase: scroll_event.phase, + }) + } + Some(ref mut last_combined_event) => { + last_combined_event.delta = last_combined_event.delta + this_delta; + } } } + // TODO(gw): Support zoom (WR issue #28). - if let Some(total_delta) = total_delta { - webrender_api.scroll(total_delta.to_untyped(), last_cursor.to_untyped()); + if let Some(combined_event) = last_combined_event { + webrender_api.scroll( + (combined_event.delta / self.scene.scale).to_untyped(), + (combined_event.cursor.as_f32() / self.scene.scale).to_untyped(), + combined_event.phase); } } None => { @@ -1617,6 +1681,7 @@ impl<Window: WindowMethods> IOCompositor<Window> { magnification: magnification, delta: Point2D::typed(0.0, 0.0), // TODO: Scroll to keep the center in view? cursor: Point2D::typed(-1, -1), // Make sure this hits the base layer. + phase: ScrollEventPhase::Move(true), }); self.composite_if_necessary(CompositingReason::Zoom); } @@ -2016,6 +2081,7 @@ impl<Window: WindowMethods> IOCompositor<Window> { self.composition_request = CompositionRequest::NoCompositingNecessary; self.process_pending_scroll_events(); self.process_animations(); + self.start_scrolling_bounce_if_necessary(); Ok(rv) } @@ -2221,6 +2287,21 @@ impl<Window: WindowMethods> IOCompositor<Window> { print_tree.add_item(layer_string); } } + + fn start_scrolling_bounce_if_necessary(&mut self) { + if self.scroll_in_progress { + return + } + + match self.webrender { + Some(ref webrender) if webrender.layers_are_bouncing_back() => {} + _ => return, + } + + if let Some(ref webrender_api) = self.webrender_api { + webrender_api.tick_scrolling_bounce_animations() + } + } } fn find_layer_with_pipeline_and_layer_id_for_layer(layer: Rc<Layer<CompositorData>>, diff --git a/components/compositing/windowing.rs b/components/compositing/windowing.rs index 944431799c0..fc5a45dc7b1 100644 --- a/components/compositing/windowing.rs +++ b/components/compositing/windowing.rs @@ -63,7 +63,7 @@ pub enum WindowEvent { Touch(TouchEventType, TouchId, TypedPoint2D<DevicePixel, f32>), /// Sent when the user scrolls. The first point is the delta and the second point is the /// origin. - Scroll(TypedPoint2D<DevicePixel, f32>, TypedPoint2D<DevicePixel, i32>), + Scroll(TypedPoint2D<DevicePixel, f32>, TypedPoint2D<DevicePixel, i32>, TouchEventType), /// Sent when the user zooms. Zoom(f32), /// Simulated "pinch zoom" gesture for non-touch platforms (e.g. ctrl-scrollwheel). diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index 04129feb28f..022b80b08d6 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -788,7 +788,7 @@ dependencies = [ "net_traits 0.0.1", "script_traits 0.0.1", "servo-egl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "servo-glutin 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", + "servo-glutin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "style_traits 0.0.1", "url 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", @@ -1854,7 +1854,7 @@ dependencies = [ [[package]] name = "servo-glutin" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "android_glue 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1896,7 +1896,7 @@ dependencies = [ "servo-egl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "servo-fontconfig 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "servo-freetype-sys 2.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "servo-glutin 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", + "servo-glutin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "x11 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2292,7 +2292,7 @@ dependencies = [ [[package]] name = "webrender" version = "0.1.0" -source = "git+https://github.com/servo/webrender#38031eed57b2df8a57e4cff576e2b5b6f2cd8316" +source = "git+https://github.com/servo/webrender#9309d52279a73ea15f955424899fed9b9ab70c95" dependencies = [ "app_units 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2313,7 +2313,7 @@ dependencies = [ [[package]] name = "webrender_traits" version = "0.1.0" -source = "git+https://github.com/servo/webrender_traits#94f16f55e65d735a9c1dc38733937cb2774322e1" +source = "git+https://github.com/servo/webrender_traits#a4d2e91915512c3d6b08d0d391221bb240d972d5" dependencies = [ "app_units 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock index 55bc0699a01..6ef78957d39 100644 --- a/ports/cef/Cargo.lock +++ b/ports/cef/Cargo.lock @@ -708,7 +708,7 @@ dependencies = [ "net_traits 0.0.1", "script_traits 0.0.1", "servo-egl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "servo-glutin 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", + "servo-glutin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "style_traits 0.0.1", "url 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", @@ -1758,7 +1758,7 @@ dependencies = [ [[package]] name = "servo-glutin" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "android_glue 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1800,7 +1800,7 @@ dependencies = [ "servo-egl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "servo-fontconfig 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "servo-freetype-sys 2.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "servo-glutin 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", + "servo-glutin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "x11 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2168,7 +2168,7 @@ dependencies = [ [[package]] name = "webrender" version = "0.1.0" -source = "git+https://github.com/servo/webrender#38031eed57b2df8a57e4cff576e2b5b6f2cd8316" +source = "git+https://github.com/servo/webrender#9309d52279a73ea15f955424899fed9b9ab70c95" dependencies = [ "app_units 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2189,7 +2189,7 @@ dependencies = [ [[package]] name = "webrender_traits" version = "0.1.0" -source = "git+https://github.com/servo/webrender_traits#94f16f55e65d735a9c1dc38733937cb2774322e1" +source = "git+https://github.com/servo/webrender_traits#a4d2e91915512c3d6b08d0d391221bb240d972d5" dependencies = [ "app_units 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ports/cef/browser_host.rs b/ports/cef/browser_host.rs index 73ddfdb0676..bbf776ee839 100644 --- a/ports/cef/browser_host.rs +++ b/ports/cef/browser_host.rs @@ -15,7 +15,7 @@ use euclid::point::Point2D; use euclid::size::Size2D; use libc::{c_double, c_int}; use msg::constellation_msg::{self, KeyModifiers, KeyState}; -use script_traits::MouseButton; +use script_traits::{MouseButton, TouchEventType}; use std::cell::{Cell, RefCell}; pub struct ServoCefBrowserHost { @@ -469,7 +469,9 @@ full_cef_class_impl! { let delta_y: c_int = delta_y; let delta = Point2D::typed(delta_x as f32, delta_y as f32); let origin = Point2D::typed((*event).x as i32, (*event).y as i32); - this.downcast().send_window_event(WindowEvent::Scroll(delta, origin)) + this.downcast().send_window_event(WindowEvent::Scroll(delta, + origin, + TouchEventType::Move)) }} fn get_zoom_level(&this,) -> c_double {{ diff --git a/ports/glutin/window.rs b/ports/glutin/window.rs index a2550d76f77..e604e11a1a4 100644 --- a/ports/glutin/window.rs +++ b/ports/glutin/window.rs @@ -16,6 +16,7 @@ use gleam::gl; use glutin; #[cfg(feature = "window")] use glutin::{Api, ElementState, Event, GlRequest, MouseButton, VirtualKeyCode, MouseScrollDelta}; +use glutin::{TouchPhase}; use layers::geometry::DevicePixel; use layers::platform::surface::NativeDisplay; #[cfg(feature = "window")] @@ -23,6 +24,8 @@ use msg::constellation_msg::{KeyState, NONE, CONTROL, SHIFT, ALT, SUPER}; use msg::constellation_msg::{self, Key}; use net_traits::net_error_list::NetError; #[cfg(feature = "window")] +use script_traits::TouchEventType; +#[cfg(feature = "window")] use std::cell::{Cell, RefCell}; use std::os::raw::c_void; #[cfg(all(feature = "headless", target_os = "linux"))] @@ -226,23 +229,18 @@ impl Window { self.event_queue.borrow_mut().push( WindowEvent::MouseWindowMoveEventClass(Point2D::typed(x as f32, y as f32))); } - Event::MouseWheel(delta) => { + Event::MouseWheel(delta, phase) => { let (dx, dy) = match delta { MouseScrollDelta::LineDelta(dx, dy) => (dx, dy * LINE_HEIGHT), MouseScrollDelta::PixelDelta(dx, dy) => (dx, dy), }; - self.scroll_window(dx, dy); + let phase = glutin_phase_to_touch_event_type(phase); + self.scroll_window(dx, dy, phase); }, Event::Touch(touch) => { - use glutin::TouchPhase; - use script_traits::{TouchEventType, TouchId}; - - let phase = match touch.phase { - TouchPhase::Started => TouchEventType::Down, - TouchPhase::Moved => TouchEventType::Move, - TouchPhase::Ended => TouchEventType::Up, - TouchPhase::Cancelled => TouchEventType::Cancel, - }; + use script_traits::TouchId; + + let phase = glutin_phase_to_touch_event_type(touch.phase); let id = TouchId(touch.id as i32); let point = Point2D::typed(touch.location.0 as f32, touch.location.1 as f32); self.event_queue.borrow_mut().push(WindowEvent::Touch(phase, id, point)); @@ -266,10 +264,11 @@ impl Window { } /// Helper function to send a scroll event. - fn scroll_window(&self, dx: f32, dy: f32) { + fn scroll_window(&self, dx: f32, dy: f32, phase: TouchEventType) { let mouse_pos = self.mouse_pos.get(); let event = WindowEvent::Scroll(Point2D::typed(dx as f32, dy as f32), - Point2D::typed(mouse_pos.x as i32, mouse_pos.y as i32)); + Point2D::typed(mouse_pos.x as i32, mouse_pos.y as i32), + phase); self.event_queue.borrow_mut().push(event); } @@ -736,23 +735,33 @@ impl WindowMethods for Window { (NONE, Key::PageDown) | (NONE, Key::Space) => { - self.scroll_window(0.0, -self.framebuffer_size().as_f32().to_untyped().height + 2.0 * LINE_HEIGHT); + self.scroll_window(0.0, + -self.framebuffer_size() + .as_f32() + .to_untyped() + .height + 2.0 * LINE_HEIGHT, + TouchEventType::Move); } (NONE, Key::PageUp) | (SHIFT, Key::Space) => { - self.scroll_window(0.0, self.framebuffer_size().as_f32().to_untyped().height - 2.0 * LINE_HEIGHT); + self.scroll_window(0.0, + self.framebuffer_size() + .as_f32() + .to_untyped() + .height - 2.0 * LINE_HEIGHT, + TouchEventType::Move); } (NONE, Key::Up) => { - self.scroll_window(0.0, 3.0 * LINE_HEIGHT); + self.scroll_window(0.0, 3.0 * LINE_HEIGHT, TouchEventType::Move); } (NONE, Key::Down) => { - self.scroll_window(0.0, -3.0 * LINE_HEIGHT); + self.scroll_window(0.0, -3.0 * LINE_HEIGHT, TouchEventType::Move); } (NONE, Key::Left) => { - self.scroll_window(LINE_HEIGHT, 0.0); + self.scroll_window(LINE_HEIGHT, 0.0, TouchEventType::Move); } (NONE, Key::Right) => { - self.scroll_window(-LINE_HEIGHT, 0.0); + self.scroll_window(-LINE_HEIGHT, 0.0, TouchEventType::Move); } _ => { @@ -923,6 +932,16 @@ impl CompositorProxy for GlutinCompositorProxy { } } +#[cfg(feature = "window")] +fn glutin_phase_to_touch_event_type(phase: TouchPhase) -> TouchEventType { + match phase { + TouchPhase::Started => TouchEventType::Down, + TouchPhase::Moved => TouchEventType::Move, + TouchPhase::Ended => TouchEventType::Up, + TouchPhase::Cancelled => TouchEventType::Cancel, + } +} + // These functions aren't actually called. They are here as a link // hack because Skia references them. diff --git a/ports/gonk/Cargo.lock b/ports/gonk/Cargo.lock index 298de62fb40..1d2e33a6a5a 100644 --- a/ports/gonk/Cargo.lock +++ b/ports/gonk/Cargo.lock @@ -1738,7 +1738,7 @@ dependencies = [ [[package]] name = "servo-glutin" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "android_glue 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1780,7 +1780,7 @@ dependencies = [ "servo-egl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "servo-fontconfig 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "servo-freetype-sys 2.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "servo-glutin 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", + "servo-glutin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "x11 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2117,7 +2117,7 @@ dependencies = [ [[package]] name = "webrender" version = "0.1.0" -source = "git+https://github.com/servo/webrender#38031eed57b2df8a57e4cff576e2b5b6f2cd8316" +source = "git+https://github.com/servo/webrender#9309d52279a73ea15f955424899fed9b9ab70c95" dependencies = [ "app_units 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2138,7 +2138,7 @@ dependencies = [ [[package]] name = "webrender_traits" version = "0.1.0" -source = "git+https://github.com/servo/webrender_traits#94f16f55e65d735a9c1dc38733937cb2774322e1" +source = "git+https://github.com/servo/webrender_traits#a4d2e91915512c3d6b08d0d391221bb240d972d5" dependencies = [ "app_units 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ports/gonk/src/input.rs b/ports/gonk/src/input.rs index e40900f7acf..fd6ee3a14fc 100644 --- a/ports/gonk/src/input.rs +++ b/ports/gonk/src/input.rs @@ -6,7 +6,7 @@ use compositing::windowing::{WindowEvent, MouseWindowEvent}; use errno::errno; use euclid::point::Point2D; use libc::{c_int, c_long, time_t}; -use script_traits::MouseButton; +use script_traits::{MouseButton, TouchEventType}; use std::fs::File; use std::io::Read; use std::mem::{size_of, transmute, zeroed}; @@ -185,7 +185,8 @@ fn read_input_device(device_path: &Path, println!("Touch move x: {}, y: {}", slotA.x, slotA.y); sender.send( WindowEvent::Scroll(Point2D::typed((slotA.x - last_x) as f32, (slotA.y - last_y) as f32), - Point2D::typed(slotA.x, slotA.y))).ok().unwrap(); + Point2D::typed(slotA.x, slotA.y), + TouchEventType::Move)).ok().unwrap(); last_x = slotA.x; last_y = slotA.y; if touch_count >= 2 { |