Auto merge of #14141 - samuknet:home-end-key-scroll2, r=glennw

Implement home end key scrolling

<!-- Please describe your changes on the following line: -->
* Refactor all scroll related code to use a new `ScrollLocation` struct which can either be a `delta` (as before) or a `Start` or `End` request, to represent the desire to scroll to the start and end of the page.
Effectively, everywhere a delta was used, there is now a `ScrollLocation` struct instead.

* Add key press listeners for HOME and END keys so as to cause a scroll to be queued with `ScrollLocation::Start` (in HOME case) or `ScrollLocation::End` (in END case).

* These changes depend on added support for the new `ScrollLocation` in webrender and webrender_traits. See https://github.com/servo/webrender/pull/540.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [ x] These changes fix #13082 (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [x] These changes do not require tests because scrolling I/O

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->

---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/14141)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-01-23 07:26:00 -08:00 committed by GitHub
commit 1706ffd6e5
9 changed files with 118 additions and 47 deletions

2
Cargo.lock generated
View file

@ -674,6 +674,7 @@ dependencies = [
"servo_geometry 0.0.1", "servo_geometry 0.0.1",
"servo_url 0.0.1", "servo_url 0.0.1",
"style_traits 0.0.1", "style_traits 0.0.1",
"webrender_traits 0.11.0 (git+https://github.com/servo/webrender)",
"x11 2.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "x11 2.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -1037,6 +1038,7 @@ dependencies = [
"servo_url 0.0.1", "servo_url 0.0.1",
"style_traits 0.0.1", "style_traits 0.0.1",
"user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"webrender_traits 0.11.0 (git+https://github.com/servo/webrender)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"x11 2.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "x11 2.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]

View file

@ -39,7 +39,7 @@ use style_traits::viewport::ViewportConstraints;
use time::{precise_time_ns, precise_time_s}; use time::{precise_time_ns, precise_time_s};
use touch::{TouchHandler, TouchAction}; use touch::{TouchHandler, TouchAction};
use webrender; use webrender;
use webrender_traits::{self, ScrollEventPhase, ServoScrollRootId, LayoutPoint}; use webrender_traits::{self, ScrollEventPhase, ServoScrollRootId, LayoutPoint, ScrollLocation};
use windowing::{self, MouseWindowEvent, WindowEvent, WindowMethods, WindowNavigateMsg}; use windowing::{self, MouseWindowEvent, WindowEvent, WindowMethods, WindowNavigateMsg};
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
@ -227,8 +227,8 @@ pub struct IOCompositor<Window: WindowMethods> {
struct ScrollZoomEvent { struct ScrollZoomEvent {
/// Change the pinch zoom level by this factor /// Change the pinch zoom level by this factor
magnification: f32, magnification: f32,
/// Scroll by this offset /// Scroll by this offset, or to Start or End
delta: TypedPoint2D<f32, DevicePixel>, scroll_location: ScrollLocation,
/// Apply changes to the frame at this location /// Apply changes to the frame at this location
cursor: TypedPoint2D<i32, DevicePixel>, cursor: TypedPoint2D<i32, DevicePixel>,
/// The scroll event phase. /// The scroll event phase.
@ -1027,7 +1027,10 @@ impl<Window: WindowMethods> IOCompositor<Window> {
match self.touch_handler.on_touch_move(identifier, point) { match self.touch_handler.on_touch_move(identifier, point) {
TouchAction::Scroll(delta) => { TouchAction::Scroll(delta) => {
match point.cast() { match point.cast() {
Some(point) => self.on_scroll_window_event(delta, point), Some(point) => self.on_scroll_window_event(ScrollLocation::Delta(
webrender_traits::LayerPoint::from_untyped(
&delta.to_untyped())),
point),
None => error!("Point cast failed."), None => error!("Point cast failed."),
} }
} }
@ -1035,7 +1038,8 @@ impl<Window: WindowMethods> IOCompositor<Window> {
let cursor = TypedPoint2D::new(-1, -1); // Make sure this hits the base layer. let cursor = TypedPoint2D::new(-1, -1); // Make sure this hits the base layer.
self.pending_scroll_zoom_events.push(ScrollZoomEvent { self.pending_scroll_zoom_events.push(ScrollZoomEvent {
magnification: magnification, magnification: magnification,
delta: scroll_delta, scroll_location: ScrollLocation::Delta(webrender_traits::LayerPoint::from_untyped(
&scroll_delta.to_untyped())),
cursor: cursor, cursor: cursor,
phase: ScrollEventPhase::Move(true), phase: ScrollEventPhase::Move(true),
event_count: 1, event_count: 1,
@ -1096,7 +1100,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
} }
fn on_scroll_window_event(&mut self, fn on_scroll_window_event(&mut self,
delta: TypedPoint2D<f32, DevicePixel>, scroll_location: ScrollLocation,
cursor: TypedPoint2D<i32, DevicePixel>) { cursor: TypedPoint2D<i32, DevicePixel>) {
let event_phase = match (self.scroll_in_progress, self.in_scroll_transaction) { let event_phase = match (self.scroll_in_progress, self.in_scroll_transaction) {
(false, None) => ScrollEventPhase::Start, (false, None) => ScrollEventPhase::Start,
@ -1107,7 +1111,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
self.in_scroll_transaction = Some(Instant::now()); self.in_scroll_transaction = Some(Instant::now());
self.pending_scroll_zoom_events.push(ScrollZoomEvent { self.pending_scroll_zoom_events.push(ScrollZoomEvent {
magnification: 1.0, magnification: 1.0,
delta: delta, scroll_location: scroll_location,
cursor: cursor, cursor: cursor,
phase: event_phase, phase: event_phase,
event_count: 1, event_count: 1,
@ -1115,12 +1119,12 @@ impl<Window: WindowMethods> IOCompositor<Window> {
} }
fn on_scroll_start_window_event(&mut self, fn on_scroll_start_window_event(&mut self,
delta: TypedPoint2D<f32, DevicePixel>, scroll_location: ScrollLocation,
cursor: TypedPoint2D<i32, DevicePixel>) { cursor: TypedPoint2D<i32, DevicePixel>) {
self.scroll_in_progress = true; self.scroll_in_progress = true;
self.pending_scroll_zoom_events.push(ScrollZoomEvent { self.pending_scroll_zoom_events.push(ScrollZoomEvent {
magnification: 1.0, magnification: 1.0,
delta: delta, scroll_location: scroll_location,
cursor: cursor, cursor: cursor,
phase: ScrollEventPhase::Start, phase: ScrollEventPhase::Start,
event_count: 1, event_count: 1,
@ -1128,12 +1132,12 @@ impl<Window: WindowMethods> IOCompositor<Window> {
} }
fn on_scroll_end_window_event(&mut self, fn on_scroll_end_window_event(&mut self,
delta: TypedPoint2D<f32, DevicePixel>, scroll_location: ScrollLocation,
cursor: TypedPoint2D<i32, DevicePixel>) { cursor: TypedPoint2D<i32, DevicePixel>) {
self.scroll_in_progress = false; self.scroll_in_progress = false;
self.pending_scroll_zoom_events.push(ScrollZoomEvent { self.pending_scroll_zoom_events.push(ScrollZoomEvent {
magnification: 1.0, magnification: 1.0,
delta: delta, scroll_location: scroll_location,
cursor: cursor, cursor: cursor,
phase: ScrollEventPhase::End, phase: ScrollEventPhase::End,
event_count: 1, event_count: 1,
@ -1146,14 +1150,34 @@ impl<Window: WindowMethods> IOCompositor<Window> {
// Batch up all scroll events into one, or else we'll do way too much painting. // Batch up all scroll events into one, or else we'll do way too much painting.
let mut last_combined_event: Option<ScrollZoomEvent> = None; let mut last_combined_event: Option<ScrollZoomEvent> = None;
for scroll_event in self.pending_scroll_zoom_events.drain(..) { for scroll_event in self.pending_scroll_zoom_events.drain(..) {
let this_delta = scroll_event.delta;
let this_cursor = scroll_event.cursor; let this_cursor = scroll_event.cursor;
let this_delta = match scroll_event.scroll_location {
ScrollLocation::Delta(delta) => delta,
ScrollLocation::Start | ScrollLocation::End => {
// If this is an event which is scrolling to the start or end of the page,
// disregard other pending events and exit the loop.
last_combined_event = Some(scroll_event);
break;
}
};
if let Some(combined_event) = last_combined_event { if let Some(combined_event) = last_combined_event {
if combined_event.phase != scroll_event.phase { if combined_event.phase != scroll_event.phase {
let delta = (combined_event.delta / self.scale).to_untyped(); let combined_delta = match combined_event.scroll_location {
ScrollLocation::Delta(delta) => delta,
ScrollLocation::Start | ScrollLocation::End => {
// If this is an event which is scrolling to the start or end of the page,
// disregard other pending events and exit the loop.
last_combined_event = Some(scroll_event);
break;
}
};
let delta = (TypedPoint2D::from_untyped(&combined_delta.to_untyped()) / self.scale)
.to_untyped();
let delta = webrender_traits::LayerPoint::from_untyped(&delta);
let cursor = let cursor =
(combined_event.cursor.to_f32() / self.scale).to_untyped(); (combined_event.cursor.to_f32() / self.scale).to_untyped();
let delta = webrender_traits::LayerPoint::from_untyped(&delta);
let location = webrender_traits::ScrollLocation::Delta(delta); let location = webrender_traits::ScrollLocation::Delta(delta);
let cursor = webrender_traits::WorldPoint::from_untyped(&cursor); let cursor = webrender_traits::WorldPoint::from_untyped(&cursor);
self.webrender_api.scroll(location, cursor, combined_event.phase); self.webrender_api.scroll(location, cursor, combined_event.phase);
@ -1165,7 +1189,8 @@ impl<Window: WindowMethods> IOCompositor<Window> {
(last_combined_event @ &mut None, _) => { (last_combined_event @ &mut None, _) => {
*last_combined_event = Some(ScrollZoomEvent { *last_combined_event = Some(ScrollZoomEvent {
magnification: scroll_event.magnification, magnification: scroll_event.magnification,
delta: this_delta, scroll_location: ScrollLocation::Delta(webrender_traits::LayerPoint::from_untyped(
&this_delta.to_untyped())),
cursor: this_cursor, cursor: this_cursor,
phase: scroll_event.phase, phase: scroll_event.phase,
event_count: 1, event_count: 1,
@ -1177,30 +1202,41 @@ impl<Window: WindowMethods> IOCompositor<Window> {
// fling. This causes events to get bunched up occasionally, causing // fling. This causes events to get bunched up occasionally, causing
// nasty-looking "pops". To mitigate this, during a fling we average // nasty-looking "pops". To mitigate this, during a fling we average
// deltas instead of summing them. // deltas instead of summing them.
let old_event_count = if let ScrollLocation::Delta(delta) = last_combined_event.scroll_location {
ScaleFactor::new(last_combined_event.event_count as f32); let old_event_count =
last_combined_event.event_count += 1; ScaleFactor::new(last_combined_event.event_count as f32);
let new_event_count = last_combined_event.event_count += 1;
ScaleFactor::new(last_combined_event.event_count as f32); let new_event_count =
last_combined_event.delta = ScaleFactor::new(last_combined_event.event_count as f32);
(last_combined_event.delta * old_event_count + this_delta) / last_combined_event.scroll_location = ScrollLocation::Delta(
new_event_count; (delta * old_event_count + this_delta) /
new_event_count);
}
} }
(&mut Some(ref mut last_combined_event), _) => { (&mut Some(ref mut last_combined_event), _) => {
last_combined_event.delta = last_combined_event.delta + this_delta; if let ScrollLocation::Delta(delta) = last_combined_event.scroll_location {
last_combined_event.event_count += 1 last_combined_event.scroll_location = ScrollLocation::Delta(delta + this_delta);
last_combined_event.event_count += 1
}
} }
} }
} }
// TODO(gw): Support zoom (WR issue #28). // TODO(gw): Support zoom (WR issue #28).
if let Some(combined_event) = last_combined_event { if let Some(combined_event) = last_combined_event {
let delta = (combined_event.delta / self.scale).to_untyped(); let scroll_location = match combined_event.scroll_location {
let delta = webrender_traits::LayoutPoint::from_untyped(&delta); ScrollLocation::Delta(delta) => {
let scaled_delta = (TypedPoint2D::from_untyped(&delta.to_untyped()) / self.scale)
.to_untyped();
let calculated_delta = webrender_traits::LayoutPoint::from_untyped(&scaled_delta);
ScrollLocation::Delta(calculated_delta)
},
// Leave ScrollLocation unchanged if it is Start or End location.
sl @ ScrollLocation::Start | sl @ ScrollLocation::End => sl,
};
let cursor = (combined_event.cursor.to_f32() / self.scale).to_untyped(); let cursor = (combined_event.cursor.to_f32() / self.scale).to_untyped();
let location = webrender_traits::ScrollLocation::Delta(delta);
let cursor = webrender_traits::WorldPoint::from_untyped(&cursor); let cursor = webrender_traits::WorldPoint::from_untyped(&cursor);
self.webrender_api.scroll(location, cursor, combined_event.phase); self.webrender_api.scroll(scroll_location, cursor, combined_event.phase);
self.waiting_for_results_of_scroll = true self.waiting_for_results_of_scroll = true
} }
@ -1295,7 +1331,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
fn on_pinch_zoom_window_event(&mut self, magnification: f32) { fn on_pinch_zoom_window_event(&mut self, magnification: f32) {
self.pending_scroll_zoom_events.push(ScrollZoomEvent { self.pending_scroll_zoom_events.push(ScrollZoomEvent {
magnification: magnification, magnification: magnification,
delta: TypedPoint2D::zero(), // TODO: Scroll to keep the center in view? scroll_location: ScrollLocation::Delta(TypedPoint2D::zero()), // TODO: Scroll to keep the center in view?
cursor: TypedPoint2D::new(-1, -1), // Make sure this hits the base layer. cursor: TypedPoint2D::new(-1, -1), // Make sure this hits the base layer.
phase: ScrollEventPhase::Move(true), phase: ScrollEventPhase::Move(true),
event_count: 1, event_count: 1,
@ -1693,6 +1729,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
} }
} }
/// Why we performed a composite. This is used for debugging. /// Why we performed a composite. This is used for debugging.
#[derive(Copy, Clone, PartialEq, Debug)] #[derive(Copy, Clone, PartialEq, Debug)]
pub enum CompositingReason { pub enum CompositingReason {

View file

@ -16,6 +16,7 @@ use servo_geometry::ScreenPx;
use servo_url::ServoUrl; use servo_url::ServoUrl;
use std::fmt::{Debug, Error, Formatter}; use std::fmt::{Debug, Error, Formatter};
use style_traits::cursor::Cursor; use style_traits::cursor::Cursor;
use webrender_traits::ScrollLocation;
#[derive(Clone)] #[derive(Clone)]
pub enum MouseWindowEvent { pub enum MouseWindowEvent {
@ -62,7 +63,7 @@ pub enum WindowEvent {
Touch(TouchEventType, TouchId, TypedPoint2D<f32, DevicePixel>), Touch(TouchEventType, TouchId, TypedPoint2D<f32, DevicePixel>),
/// Sent when the user scrolls. The first point is the delta and the second point is the /// Sent when the user scrolls. The first point is the delta and the second point is the
/// origin. /// origin.
Scroll(TypedPoint2D<f32, DevicePixel>, TypedPoint2D<i32, DevicePixel>, TouchEventType), Scroll(ScrollLocation, TypedPoint2D<i32, DevicePixel>, TouchEventType),
/// Sent when the user zooms. /// Sent when the user zooms.
Zoom(f32), Zoom(f32),
/// Simulated "pinch zoom" gesture for non-touch platforms (e.g. ctrl-scrollwheel). /// Simulated "pinch zoom" gesture for non-touch platforms (e.g. ctrl-scrollwheel).

View file

@ -35,6 +35,11 @@ servo_geometry = {path = "../../components/geometry"}
servo_url = {path = "../../components/url"} servo_url = {path = "../../components/url"}
style_traits = {path = "../../components/style_traits"} style_traits = {path = "../../components/style_traits"}
[dependencies.webrender_traits]
git = "https://github.com/servo/webrender"
default-features = false
features = ["serde_derive", "ipc"]
[target.'cfg(target_os="macos")'.dependencies] [target.'cfg(target_os="macos")'.dependencies]
objc = "0.2" objc = "0.2"
cocoa = "0.5" cocoa = "0.5"

View file

@ -8,6 +8,7 @@ use interfaces::{CefBrowser, CefBrowserHost, CefClient, cef_browser_t, cef_brows
use types::cef_event_flags_t::{EVENTFLAG_ALT_DOWN, EVENTFLAG_CONTROL_DOWN, EVENTFLAG_SHIFT_DOWN}; use types::cef_event_flags_t::{EVENTFLAG_ALT_DOWN, EVENTFLAG_CONTROL_DOWN, EVENTFLAG_SHIFT_DOWN};
use types::cef_key_event_type_t::{KEYEVENT_CHAR, KEYEVENT_KEYDOWN, KEYEVENT_KEYUP, KEYEVENT_RAWKEYDOWN}; use types::cef_key_event_type_t::{KEYEVENT_CHAR, KEYEVENT_KEYDOWN, KEYEVENT_KEYUP, KEYEVENT_RAWKEYDOWN};
use types::{cef_mouse_button_type_t, cef_mouse_event, cef_rect_t, cef_key_event, cef_window_handle_t}; use types::{cef_mouse_button_type_t, cef_mouse_event, cef_rect_t, cef_key_event, cef_window_handle_t};
use webrender_traits::ScrollLocation;
use wrappers::CefWrap; use wrappers::CefWrap;
use compositing::windowing::{WindowEvent, MouseWindowEvent}; use compositing::windowing::{WindowEvent, MouseWindowEvent};
@ -471,7 +472,7 @@ full_cef_class_impl! {
let delta_y: c_int = delta_y; let delta_y: c_int = delta_y;
let delta = TypedPoint2D::new(delta_x as f32, delta_y as f32); let delta = TypedPoint2D::new(delta_x as f32, delta_y as f32);
let origin = TypedPoint2D::new((*event).x as i32, (*event).y as i32); let origin = TypedPoint2D::new((*event).x as i32, (*event).y as i32);
this.downcast().send_window_event(WindowEvent::Scroll(delta, this.downcast().send_window_event(WindowEvent::Scroll(ScrollLocation::Delta(delta),
origin, origin,
TouchEventType::Move)) TouchEventType::Move))
}} }}

View file

@ -28,6 +28,7 @@ extern crate style_traits;
extern crate net_traits; extern crate net_traits;
extern crate msg; extern crate msg;
extern crate webrender_traits;
extern crate libc; extern crate libc;

View file

@ -23,6 +23,10 @@ servo_config = {path = "../../components/config"}
servo_url = {path = "../../components/url"} servo_url = {path = "../../components/url"}
style_traits = {path = "../../components/style_traits"} style_traits = {path = "../../components/style_traits"}
[dependencies.webrender_traits]
git = "https://github.com/servo/webrender"
default_features = false
[target.'cfg(any(target_os = "linux", target_os = "macos"))'.dependencies] [target.'cfg(any(target_os = "linux", target_os = "macos"))'.dependencies]
osmesa-sys = "0.1.2" osmesa-sys = "0.1.2"

View file

@ -22,6 +22,8 @@ extern crate servo_config;
extern crate servo_geometry; extern crate servo_geometry;
extern crate servo_url; extern crate servo_url;
extern crate style_traits; extern crate style_traits;
extern crate webrender_traits;
#[cfg(target_os = "windows")] extern crate winapi; #[cfg(target_os = "windows")] extern crate winapi;
#[cfg(target_os = "windows")] extern crate user32; #[cfg(target_os = "windows")] extern crate user32;
#[cfg(target_os = "windows")] extern crate gdi32; #[cfg(target_os = "windows")] extern crate gdi32;

View file

@ -42,6 +42,7 @@ use std::sync::mpsc::{Sender, channel};
use style_traits::cursor::Cursor; use style_traits::cursor::Cursor;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
use user32; use user32;
use webrender_traits::ScrollLocation;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
use winapi; use winapi;
@ -425,8 +426,9 @@ impl Window {
MouseScrollDelta::LineDelta(dx, dy) => (dx, dy * LINE_HEIGHT), MouseScrollDelta::LineDelta(dx, dy) => (dx, dy * LINE_HEIGHT),
MouseScrollDelta::PixelDelta(dx, dy) => (dx, dy), MouseScrollDelta::PixelDelta(dx, dy) => (dx, dy),
}; };
let scroll_location = ScrollLocation::Delta(TypedPoint2D::new(dx, dy));
let phase = glutin_phase_to_touch_event_type(phase); let phase = glutin_phase_to_touch_event_type(phase);
self.scroll_window(dx, dy, phase); self.scroll_window(scroll_location, phase);
}, },
Event::Touch(touch) => { Event::Touch(touch) => {
use script_traits::TouchId; use script_traits::TouchId;
@ -461,16 +463,19 @@ impl Window {
} }
/// Helper function to send a scroll event. /// Helper function to send a scroll event.
fn scroll_window(&self, mut dx: f32, mut dy: f32, phase: TouchEventType) { fn scroll_window(&self, scroll_location: ScrollLocation, phase: TouchEventType) {
// Scroll events snap to the major axis of movement, with vertical // Scroll events snap to the major axis of movement, with vertical
// preferred over horizontal. // preferred over horizontal.
if dy.abs() >= dx.abs() { if let ScrollLocation::Delta(mut delta) = scroll_location {
dx = 0.0; if delta.y.abs() >= delta.x.abs() {
} else { delta.x = 0.0;
dy = 0.0; } else {
delta.y = 0.0;
}
} }
let mouse_pos = self.mouse_pos.get(); let mouse_pos = self.mouse_pos.get();
let event = WindowEvent::Scroll(TypedPoint2D::new(dx as f32, dy as f32), let event = WindowEvent::Scroll(scroll_location,
TypedPoint2D::new(mouse_pos.x as i32, mouse_pos.y as i32), TypedPoint2D::new(mouse_pos.x as i32, mouse_pos.y as i32),
phase); phase);
self.event_queue.borrow_mut().push(event); self.event_queue.borrow_mut().push(event);
@ -1034,33 +1039,46 @@ impl WindowMethods for Window {
(NONE, None, Key::PageDown) | (NONE, None, Key::PageDown) |
(NONE, Some(' '), _) => { (NONE, Some(' '), _) => {
self.scroll_window(0.0, let scroll_location = ScrollLocation::Delta(TypedPoint2D::new(0.0,
-self.framebuffer_size() -self.framebuffer_size()
.to_f32() .to_f32()
.to_untyped() .to_untyped()
.height + 2.0 * LINE_HEIGHT, .height + 2.0 * LINE_HEIGHT));
self.scroll_window(scroll_location,
TouchEventType::Move); TouchEventType::Move);
} }
(NONE, None, Key::PageUp) | (NONE, None, Key::PageUp) |
(SHIFT, Some(' '), _) => { (SHIFT, Some(' '), _) => {
self.scroll_window(0.0, let scroll_location = ScrollLocation::Delta(TypedPoint2D::new(0.0,
self.framebuffer_size() self.framebuffer_size()
.to_f32() .to_f32()
.to_untyped() .to_untyped()
.height - 2.0 * LINE_HEIGHT, .height - 2.0 * LINE_HEIGHT));
self.scroll_window(scroll_location,
TouchEventType::Move); TouchEventType::Move);
} }
(NONE, None, Key::Home) => {
self.scroll_window(ScrollLocation::Start, TouchEventType::Move);
}
(NONE, None, Key::End) => {
self.scroll_window(ScrollLocation::End, TouchEventType::Move);
}
(NONE, None, Key::Up) => { (NONE, None, Key::Up) => {
self.scroll_window(0.0, 3.0 * LINE_HEIGHT, TouchEventType::Move); self.scroll_window(ScrollLocation::Delta(TypedPoint2D::new(0.0, 3.0 * LINE_HEIGHT)),
TouchEventType::Move);
} }
(NONE, None, Key::Down) => { (NONE, None, Key::Down) => {
self.scroll_window(0.0, -3.0 * LINE_HEIGHT, TouchEventType::Move); self.scroll_window(ScrollLocation::Delta(TypedPoint2D::new(0.0, -3.0 * LINE_HEIGHT)),
TouchEventType::Move);
} }
(NONE, None, Key::Left) => { (NONE, None, Key::Left) => {
self.scroll_window(LINE_HEIGHT, 0.0, TouchEventType::Move); self.scroll_window(ScrollLocation::Delta(TypedPoint2D::new(LINE_HEIGHT, 0.0)), TouchEventType::Move);
} }
(NONE, None, Key::Right) => { (NONE, None, Key::Right) => {
self.scroll_window(-LINE_HEIGHT, 0.0, TouchEventType::Move); self.scroll_window(ScrollLocation::Delta(TypedPoint2D::new(-LINE_HEIGHT, 0.0)), TouchEventType::Move);
} }
(CMD_OR_CONTROL, Some('r'), _) => { (CMD_OR_CONTROL, Some('r'), _) => {
if let Some(true) = PREFS.get("shell.builtin-key-shortcuts.enabled").as_boolean() { if let Some(true) = PREFS.get("shell.builtin-key-shortcuts.enabled").as_boolean() {