mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
Merge pull request #2666 from mbrubeck/pinch
Separate "desktop" and "mobile" zoom calculations.
This commit is contained in:
commit
6c150724f4
13 changed files with 149 additions and 66 deletions
|
@ -12,6 +12,7 @@ use windowing::{MouseWindowEvent, MouseWindowEventClass, MouseWindowMouseDownEve
|
|||
use windowing::{MouseWindowMouseUpEvent, MouseWindowMoveEventClass, NavigationWindowEvent};
|
||||
use windowing::{QuitWindowEvent, RefreshWindowEvent, ResizeWindowEvent, ScrollWindowEvent};
|
||||
use windowing::{WindowEvent, WindowMethods, WindowNavigateMsg, ZoomWindowEvent};
|
||||
use windowing::PinchZoomWindowEvent;
|
||||
|
||||
use azure::azure_hl::{SourceSurfaceMethods, Color};
|
||||
use azure::azure_hl;
|
||||
|
@ -30,9 +31,9 @@ use png;
|
|||
use servo_msg::compositor_msg::{Blank, Epoch, FinishedLoading, IdleRenderState, LayerBufferSet};
|
||||
use servo_msg::compositor_msg::{LayerId, ReadyState, RenderState, ScrollPolicy, Scrollable};
|
||||
use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, LoadUrlMsg, NavigateMsg};
|
||||
use servo_msg::constellation_msg::{PipelineId, ResizedWindowMsg};
|
||||
use servo_msg::constellation_msg::{PipelineId, ResizedWindowMsg, WindowSizeData};
|
||||
use servo_msg::constellation_msg;
|
||||
use servo_util::geometry::{DevicePixel, PagePx, ScreenPx};
|
||||
use servo_util::geometry::{DevicePixel, PagePx, ScreenPx, ViewportPx};
|
||||
use servo_util::opts::Opts;
|
||||
use servo_util::time::{profile, ProfilerChan};
|
||||
use servo_util::{time, url};
|
||||
|
@ -64,6 +65,13 @@ pub struct IOCompositor {
|
|||
/// The application window size.
|
||||
window_size: TypedSize2D<DevicePixel, uint>,
|
||||
|
||||
/// "Mobile-style" zoom that does not reflow the page.
|
||||
viewport_zoom: ScaleFactor<PagePx, ViewportPx, f32>,
|
||||
|
||||
/// "Desktop-style" zoom that resizes the viewport to fit the window.
|
||||
/// See `ViewportPx` docs in util/geom.rs for details.
|
||||
page_zoom: ScaleFactor<ViewportPx, ScreenPx, f32>,
|
||||
|
||||
/// The device pixel ratio for this window.
|
||||
hidpi_factor: ScaleFactor<ScreenPx, DevicePixel, f32>,
|
||||
|
||||
|
@ -82,9 +90,6 @@ pub struct IOCompositor {
|
|||
/// Tracks whether we need to re-composite a page.
|
||||
recomposite: bool,
|
||||
|
||||
/// Keeps track of the current zoom factor.
|
||||
world_zoom: ScaleFactor<PagePx, ScreenPx, f32>,
|
||||
|
||||
/// Tracks whether the zoom action has happend recently.
|
||||
zoom_action: bool,
|
||||
|
||||
|
@ -146,7 +151,8 @@ impl IOCompositor {
|
|||
shutting_down: false,
|
||||
done: false,
|
||||
recomposite: false,
|
||||
world_zoom: ScaleFactor(1.0),
|
||||
page_zoom: ScaleFactor(1.0),
|
||||
viewport_zoom: ScaleFactor(1.0),
|
||||
zoom_action: false,
|
||||
zoom_time: 0f64,
|
||||
ready_state: Blank,
|
||||
|
@ -417,10 +423,17 @@ impl IOCompositor {
|
|||
self.window_size.as_f32() / self.device_pixels_per_page_px()
|
||||
}
|
||||
|
||||
/// The size of the window in screen px.
|
||||
fn send_window_size(&self) {
|
||||
let dppx = self.page_zoom * self.device_pixels_per_screen_px();
|
||||
let initial_viewport = self.window_size.as_f32() / dppx;
|
||||
let visible_viewport = initial_viewport / self.viewport_zoom;
|
||||
|
||||
let ConstellationChan(ref chan) = self.constellation_chan;
|
||||
chan.send(ResizedWindowMsg(self.page_window()));
|
||||
chan.send(ResizedWindowMsg(WindowSizeData {
|
||||
device_pixel_ratio: dppx,
|
||||
initial_viewport: initial_viewport,
|
||||
visible_viewport: visible_viewport,
|
||||
}));
|
||||
}
|
||||
|
||||
fn set_layer_page_size(&mut self,
|
||||
|
@ -549,6 +562,10 @@ impl IOCompositor {
|
|||
self.on_zoom_window_event(magnification);
|
||||
}
|
||||
|
||||
PinchZoomWindowEvent(magnification) => {
|
||||
self.on_pinch_zoom_window_event(magnification);
|
||||
}
|
||||
|
||||
NavigationWindowEvent(direction) => {
|
||||
self.on_navigation_window_event(direction);
|
||||
}
|
||||
|
@ -647,7 +664,7 @@ impl IOCompositor {
|
|||
}
|
||||
|
||||
fn device_pixels_per_page_px(&self) -> ScaleFactor<PagePx, DevicePixel, f32> {
|
||||
self.world_zoom * self.device_pixels_per_screen_px()
|
||||
self.viewport_zoom * self.page_zoom * self.device_pixels_per_screen_px()
|
||||
}
|
||||
|
||||
fn update_zoom_transform(&mut self) {
|
||||
|
@ -656,21 +673,26 @@ impl IOCompositor {
|
|||
}
|
||||
|
||||
fn on_zoom_window_event(&mut self, magnification: f32) {
|
||||
self.page_zoom = ScaleFactor((self.page_zoom.get() * magnification).max(1.0));
|
||||
self.update_zoom_transform();
|
||||
self.send_window_size();
|
||||
}
|
||||
|
||||
fn on_pinch_zoom_window_event(&mut self, magnification: f32) {
|
||||
self.zoom_action = true;
|
||||
self.zoom_time = precise_time_s();
|
||||
let old_world_zoom = self.world_zoom;
|
||||
let old_viewport_zoom = self.viewport_zoom;
|
||||
let window_size = self.window_size.as_f32();
|
||||
|
||||
// Determine zoom amount
|
||||
self.world_zoom = ScaleFactor((self.world_zoom.get() * magnification).max(1.0));
|
||||
let world_zoom = self.world_zoom;
|
||||
self.viewport_zoom = ScaleFactor((self.viewport_zoom.get() * magnification).max(1.0));
|
||||
let viewport_zoom = self.viewport_zoom;
|
||||
|
||||
self.update_zoom_transform();
|
||||
|
||||
// Scroll as needed
|
||||
let page_delta = TypedPoint2D(
|
||||
window_size.width.get() * (world_zoom.inv() - old_world_zoom.inv()).get() * 0.5,
|
||||
window_size.height.get() * (world_zoom.inv() - old_world_zoom.inv()).get() * 0.5);
|
||||
window_size.width.get() * (viewport_zoom.inv() - old_viewport_zoom.inv()).get() * 0.5,
|
||||
window_size.height.get() * (viewport_zoom.inv() - old_viewport_zoom.inv()).get() * 0.5);
|
||||
// TODO: modify delta to snap scroll to pixels.
|
||||
let page_cursor = TypedPoint2D(-1f32, -1f32); // Make sure this hits the base layer
|
||||
let page_window = self.page_window();
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
|
||||
use compositing::*;
|
||||
|
||||
use geom::scale_factor::ScaleFactor;
|
||||
use geom::size::TypedSize2D;
|
||||
use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, ResizedWindowMsg};
|
||||
use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, ResizedWindowMsg, WindowSizeData};
|
||||
use servo_util::time::ProfilerChan;
|
||||
use servo_util::time;
|
||||
|
||||
|
@ -33,7 +34,11 @@ impl NullCompositor {
|
|||
// Tell the constellation about the initial fake size.
|
||||
{
|
||||
let ConstellationChan(ref chan) = constellation_chan;
|
||||
chan.send(ResizedWindowMsg(TypedSize2D(640_f32, 480_f32)));
|
||||
chan.send(ResizedWindowMsg(WindowSizeData {
|
||||
initial_viewport: TypedSize2D(640_f32, 480_f32),
|
||||
visible_viewport: TypedSize2D(640_f32, 480_f32),
|
||||
device_pixel_ratio: ScaleFactor(1.0),
|
||||
}));
|
||||
}
|
||||
compositor.handle_message(constellation_chan);
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ use compositing::{CompositorChan, LoadComplete, SetIds, SetLayerClipRect, Shutdo
|
|||
|
||||
use collections::hashmap::{HashMap, HashSet};
|
||||
use geom::rect::{Rect, TypedRect};
|
||||
use geom::scale_factor::ScaleFactor;
|
||||
use geom::size::TypedSize2D;
|
||||
use gfx::render_task;
|
||||
use libc;
|
||||
|
@ -19,7 +20,7 @@ use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, FailureMsg, Failu
|
|||
use servo_msg::constellation_msg::{IFrameSandboxState, IFrameUnsandboxed, InitLoadUrlMsg};
|
||||
use servo_msg::constellation_msg::{LoadCompleteMsg, LoadIframeUrlMsg, LoadUrlMsg, Msg, NavigateMsg};
|
||||
use servo_msg::constellation_msg::{NavigationType, PipelineId, RendererReadyMsg, ResizedWindowMsg};
|
||||
use servo_msg::constellation_msg::SubpageId;
|
||||
use servo_msg::constellation_msg::{SubpageId, WindowSizeData};
|
||||
use servo_msg::constellation_msg;
|
||||
use servo_net::image_cache_task::{ImageCacheTask, ImageCacheTaskClient};
|
||||
use servo_net::resource_task::ResourceTask;
|
||||
|
@ -48,7 +49,7 @@ pub struct Constellation {
|
|||
pending_frames: Vec<FrameChange>,
|
||||
pending_sizes: HashMap<(PipelineId, SubpageId), TypedRect<PagePx, f32>>,
|
||||
pub profiler_chan: ProfilerChan,
|
||||
pub window_size: TypedSize2D<PagePx, f32>,
|
||||
pub window_size: WindowSizeData,
|
||||
pub opts: Opts,
|
||||
}
|
||||
|
||||
|
@ -261,7 +262,11 @@ impl Constellation {
|
|||
pending_frames: vec!(),
|
||||
pending_sizes: HashMap::new(),
|
||||
profiler_chan: profiler_chan,
|
||||
window_size: TypedSize2D(800_f32, 600_f32),
|
||||
window_size: WindowSizeData {
|
||||
visible_viewport: TypedSize2D(800_f32, 600_f32),
|
||||
initial_viewport: TypedSize2D(800_f32, 600_f32),
|
||||
device_pixel_ratio: ScaleFactor(1.0),
|
||||
},
|
||||
opts: opts_clone,
|
||||
};
|
||||
constellation.run();
|
||||
|
@ -491,7 +496,11 @@ impl Constellation {
|
|||
if !already_sent.contains(&pipeline.id) {
|
||||
if is_active {
|
||||
let ScriptChan(ref script_chan) = pipeline.script_chan;
|
||||
script_chan.send(ResizeMsg(pipeline.id, rect.size));
|
||||
script_chan.send(ResizeMsg(pipeline.id, WindowSizeData {
|
||||
visible_viewport: rect.size,
|
||||
initial_viewport: rect.size * ScaleFactor(1.0),
|
||||
device_pixel_ratio: self.window_size.device_pixel_ratio,
|
||||
}));
|
||||
self.compositor_chan.send(SetLayerClipRect(pipeline.id,
|
||||
LayerId::null(),
|
||||
rect.to_untyped()));
|
||||
|
@ -788,7 +797,7 @@ impl Constellation {
|
|||
}
|
||||
|
||||
/// Called when the window is resized.
|
||||
fn handle_resized_window_msg(&mut self, new_size: TypedSize2D<PagePx, f32>) {
|
||||
fn handle_resized_window_msg(&mut self, new_size: WindowSizeData) {
|
||||
let mut already_seen = HashSet::new();
|
||||
for frame_tree in self.current_frame().iter() {
|
||||
debug!("constellation sending resize message to active frame");
|
||||
|
|
|
@ -581,8 +581,12 @@ impl LayoutTask {
|
|||
_ => false
|
||||
};
|
||||
|
||||
let current_screen_size = Size2D(Au::from_page_px(data.window_size.width),
|
||||
Au::from_page_px(data.window_size.height));
|
||||
// TODO: Calculate the "actual viewport":
|
||||
// http://www.w3.org/TR/css-device-adapt/#actual-viewport
|
||||
let viewport_size = data.window_size.initial_viewport;
|
||||
|
||||
let current_screen_size = Size2D(Au::from_frac32_px(viewport_size.width.get()),
|
||||
Au::from_frac32_px(viewport_size.height.get()));
|
||||
if self.screen_size != current_screen_size {
|
||||
all_style_damage = true
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
use compositing::CompositorChan;
|
||||
use layout::layout_task::LayoutTask;
|
||||
|
||||
use geom::size::TypedSize2D;
|
||||
use gfx::render_task::{PaintPermissionGranted, PaintPermissionRevoked};
|
||||
use gfx::render_task::{RenderChan, RenderTask};
|
||||
use script::layout_interface::LayoutChan;
|
||||
|
@ -13,9 +12,9 @@ use script::script_task::LoadMsg;
|
|||
use script::script_task::{AttachLayoutMsg, NewLayoutInfo, ScriptTask, ScriptChan};
|
||||
use script::script_task;
|
||||
use servo_msg::constellation_msg::{ConstellationChan, Failure, PipelineId, SubpageId};
|
||||
use servo_msg::constellation_msg::WindowSizeData;
|
||||
use servo_net::image_cache_task::ImageCacheTask;
|
||||
use servo_net::resource_task::ResourceTask;
|
||||
use servo_util::geometry::PagePx;
|
||||
use servo_util::opts::Opts;
|
||||
use servo_util::time::ProfilerChan;
|
||||
use std::rc::Rc;
|
||||
|
@ -113,7 +112,7 @@ impl Pipeline {
|
|||
image_cache_task: ImageCacheTask,
|
||||
resource_task: ResourceTask,
|
||||
profiler_chan: ProfilerChan,
|
||||
window_size: TypedSize2D<PagePx, f32>,
|
||||
window_size: WindowSizeData,
|
||||
opts: Opts,
|
||||
url: Url)
|
||||
-> Pipeline {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
use windowing::{ApplicationMethods, WindowEvent, WindowMethods};
|
||||
use windowing::{IdleWindowEvent, ResizeWindowEvent, LoadUrlWindowEvent, MouseWindowEventClass, MouseWindowMoveEventClass};
|
||||
use windowing::{ScrollWindowEvent, ZoomWindowEvent, NavigationWindowEvent, FinishedWindowEvent};
|
||||
use windowing::{ScrollWindowEvent, ZoomWindowEvent, PinchZoomWindowEvent, NavigationWindowEvent, FinishedWindowEvent};
|
||||
use windowing::{QuitWindowEvent, MouseWindowClickEvent, MouseWindowMouseDownEvent, MouseWindowMouseUpEvent};
|
||||
use windowing::RefreshWindowEvent;
|
||||
use windowing::{Forward, Back};
|
||||
|
@ -240,19 +240,33 @@ impl Window {
|
|||
MouseWindowMoveEventClass(TypedPoint2D(xpos as f32, ypos as f32)));
|
||||
},
|
||||
glfw::ScrollEvent(xpos, ypos) => {
|
||||
let dx = (xpos as f32) * 30.0;
|
||||
let dy = (ypos as f32) * 30.0;
|
||||
match (window.get_key(glfw::KeyLeftControl),
|
||||
window.get_key(glfw::KeyRightControl)) {
|
||||
(glfw::Press, _) | (_, glfw::Press) => {
|
||||
// Ctrl-Scrollwheel simulates a "pinch zoom" gesture.
|
||||
if ypos < 0.0 {
|
||||
self.event_queue.borrow_mut().push(PinchZoomWindowEvent(1.0/1.1));
|
||||
} else if ypos > 0.0 {
|
||||
self.event_queue.borrow_mut().push(PinchZoomWindowEvent(1.1));
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
let dx = (xpos as f32) * 30.0;
|
||||
let dy = (ypos as f32) * 30.0;
|
||||
|
||||
let (x, y) = window.get_cursor_pos();
|
||||
//handle hidpi displays, since GLFW returns non-hi-def coordinates.
|
||||
let (backing_size, _) = window.get_framebuffer_size();
|
||||
let (window_size, _) = window.get_size();
|
||||
let hidpi = (backing_size as f32) / (window_size as f32);
|
||||
let x = x as f32 * hidpi;
|
||||
let y = y as f32 * hidpi;
|
||||
let (x, y) = window.get_cursor_pos();
|
||||
//handle hidpi displays, since GLFW returns non-hi-def coordinates.
|
||||
let (backing_size, _) = window.get_framebuffer_size();
|
||||
let (window_size, _) = window.get_size();
|
||||
let hidpi = (backing_size as f32) / (window_size as f32);
|
||||
let x = x as f32 * hidpi;
|
||||
let y = y as f32 * hidpi;
|
||||
|
||||
self.event_queue.borrow_mut().push(ScrollWindowEvent(TypedPoint2D(dx, dy),
|
||||
TypedPoint2D(x as i32, y as i32)));
|
||||
}
|
||||
}
|
||||
|
||||
self.event_queue.borrow_mut().push(ScrollWindowEvent(TypedPoint2D(dx, dy),
|
||||
TypedPoint2D(x as i32, y as i32)));
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
|
@ -298,7 +312,7 @@ impl Window {
|
|||
self.event_queue.borrow_mut().push(ZoomWindowEvent(1.1));
|
||||
}
|
||||
glfw::KeyMinus if mods.contains(glfw::Control) => { // Ctrl--
|
||||
self.event_queue.borrow_mut().push(ZoomWindowEvent(0.90909090909));
|
||||
self.event_queue.borrow_mut().push(ZoomWindowEvent(1.0/1.1));
|
||||
}
|
||||
glfw::KeyBackspace if mods.contains(glfw::Shift) => { // Shift-Backspace
|
||||
self.event_queue.borrow_mut().push(NavigationWindowEvent(Forward));
|
||||
|
|
|
@ -43,6 +43,8 @@ pub enum WindowEvent {
|
|||
ScrollWindowEvent(TypedPoint2D<DevicePixel, f32>, TypedPoint2D<DevicePixel, i32>),
|
||||
/// Sent when the user zooms.
|
||||
ZoomWindowEvent(f32),
|
||||
/// Simulated "pinch zoom" gesture for non-touch platforms (e.g. ctrl-scrollwheel).
|
||||
PinchZoomWindowEvent(f32),
|
||||
/// Sent when the user uses chrome navigation (i.e. backspace or shift-backspace).
|
||||
NavigationWindowEvent(WindowNavigateMsg),
|
||||
/// Sent when rendering is finished.
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
|
||||
use geom::rect::Rect;
|
||||
use geom::size::TypedSize2D;
|
||||
use servo_util::geometry::PagePx;
|
||||
use geom::scale_factor::ScaleFactor;
|
||||
use servo_util::geometry::{DevicePixel, PagePx, ViewportPx};
|
||||
use std::comm::{channel, Sender, Receiver};
|
||||
use url::Url;
|
||||
|
||||
|
@ -34,6 +35,18 @@ pub struct Failure {
|
|||
pub subpage_id: Option<SubpageId>,
|
||||
}
|
||||
|
||||
pub struct WindowSizeData {
|
||||
/// The size of the initial layout viewport, before parsing an
|
||||
/// http://www.w3.org/TR/css-device-adapt/#initial-viewport
|
||||
pub initial_viewport: TypedSize2D<ViewportPx, f32>,
|
||||
|
||||
/// The "viewing area" in page px. See `PagePx` documentation for details.
|
||||
pub visible_viewport: TypedSize2D<PagePx, f32>,
|
||||
|
||||
/// The resolution of the window in dppx, not including any "pinch zoom" factor.
|
||||
pub device_pixel_ratio: ScaleFactor<ViewportPx, DevicePixel, f32>,
|
||||
}
|
||||
|
||||
/// Messages from the compositor and script to the constellation.
|
||||
pub enum Msg {
|
||||
ExitMsg,
|
||||
|
@ -45,7 +58,7 @@ pub enum Msg {
|
|||
LoadIframeUrlMsg(Url, PipelineId, SubpageId, IFrameSandboxState),
|
||||
NavigateMsg(NavigationDirection),
|
||||
RendererReadyMsg(PipelineId),
|
||||
ResizedWindowMsg(TypedSize2D<PagePx, f32>),
|
||||
ResizedWindowMsg(WindowSizeData),
|
||||
}
|
||||
|
||||
/// Represents the two different ways to which a page can be navigated
|
||||
|
|
|
@ -10,17 +10,16 @@ use dom::bindings::trace::Traceable;
|
|||
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
|
||||
use dom::eventtarget::EventTarget;
|
||||
use dom::window::Window;
|
||||
use servo_msg::constellation_msg::WindowSizeData;
|
||||
use servo_util::str::DOMString;
|
||||
use servo_util::geometry::PagePx;
|
||||
use std::cell::{Cell, RefCell};
|
||||
|
||||
use geom::point::Point2D;
|
||||
use geom::size::TypedSize2D;
|
||||
|
||||
use time;
|
||||
|
||||
pub enum Event_ {
|
||||
ResizeEvent(TypedSize2D<PagePx, f32>),
|
||||
ResizeEvent(WindowSizeData),
|
||||
ReflowEvent,
|
||||
ClickEvent(uint, Point2D<f32>),
|
||||
MouseDownEvent(uint, Point2D<f32>),
|
||||
|
|
|
@ -11,10 +11,10 @@ use dom::node::{Node, LayoutDataRef};
|
|||
|
||||
use geom::point::Point2D;
|
||||
use geom::rect::Rect;
|
||||
use geom::size::TypedSize2D;
|
||||
use libc::c_void;
|
||||
use script_task::{ScriptChan};
|
||||
use servo_util::geometry::{Au, PagePx};
|
||||
use servo_msg::constellation_msg::WindowSizeData;
|
||||
use servo_util::geometry::Au;
|
||||
use std::cmp;
|
||||
use std::comm::{channel, Receiver, Sender};
|
||||
use style::Stylesheet;
|
||||
|
@ -137,7 +137,7 @@ pub struct Reflow {
|
|||
/// The channel through which messages can be sent back to the script task.
|
||||
pub script_chan: ScriptChan,
|
||||
/// The current window size.
|
||||
pub window_size: TypedSize2D<PagePx, f32>,
|
||||
pub window_size: WindowSizeData,
|
||||
/// The channel that we send a notification to.
|
||||
pub script_join_chan: Sender<()>,
|
||||
/// Unique identifier
|
||||
|
|
|
@ -19,14 +19,12 @@ use layout_interface::UntrustedNodeAddress;
|
|||
use script_task::ScriptChan;
|
||||
|
||||
use geom::point::Point2D;
|
||||
use geom::size::TypedSize2D;
|
||||
use js::rust::Cx;
|
||||
use servo_msg::compositor_msg::PerformingLayout;
|
||||
use servo_msg::compositor_msg::ScriptListener;
|
||||
use servo_msg::constellation_msg::ConstellationChan;
|
||||
use servo_msg::constellation_msg::{ConstellationChan, WindowSizeData};
|
||||
use servo_msg::constellation_msg::{PipelineId, SubpageId};
|
||||
use servo_net::resource_task::ResourceTask;
|
||||
use servo_util::geometry::PagePx;
|
||||
use servo_util::namespace::Null;
|
||||
use servo_util::str::DOMString;
|
||||
use std::cell::{Cell, RefCell, Ref, RefMut};
|
||||
|
@ -62,7 +60,7 @@ pub struct Page {
|
|||
damage: Traceable<RefCell<Option<DocumentDamage>>>,
|
||||
|
||||
/// The current size of the window, in pixels.
|
||||
pub window_size: Untraceable<Cell<TypedSize2D<PagePx, f32>>>,
|
||||
pub window_size: Untraceable<Cell<WindowSizeData>>,
|
||||
|
||||
js_info: Traceable<RefCell<Option<JSPageInfo>>>,
|
||||
|
||||
|
@ -75,7 +73,7 @@ pub struct Page {
|
|||
next_subpage_id: Untraceable<Cell<SubpageId>>,
|
||||
|
||||
/// Pending resize event, if any.
|
||||
pub resize_event: Untraceable<Cell<Option<TypedSize2D<PagePx, f32>>>>,
|
||||
pub resize_event: Untraceable<Cell<Option<WindowSizeData>>>,
|
||||
|
||||
/// Pending scroll to fragment event, if any
|
||||
pub fragment_node: Cell<Option<JS<Element>>>,
|
||||
|
@ -119,7 +117,8 @@ impl IterablePage for Rc<Page> {
|
|||
impl Page {
|
||||
pub fn new(id: PipelineId, subpage_id: Option<SubpageId>,
|
||||
layout_chan: LayoutChan,
|
||||
window_size: TypedSize2D<PagePx, f32>, resource_task: ResourceTask,
|
||||
window_size: WindowSizeData,
|
||||
resource_task: ResourceTask,
|
||||
constellation_chan: ConstellationChan,
|
||||
js_context: Rc<Cx>) -> Page {
|
||||
let js_info = JSPageInfo {
|
||||
|
|
|
@ -32,7 +32,6 @@ use layout_interface;
|
|||
use page::{Page, IterablePage, Frame};
|
||||
|
||||
use geom::point::Point2D;
|
||||
use geom::size::TypedSize2D;
|
||||
use js::jsapi::JS_CallFunctionValue;
|
||||
use js::jsapi::{JS_SetWrapObjectCallbacks, JS_SetGCZeal, JS_DEFAULT_ZEAL_FREQ, JS_GC};
|
||||
use js::jsapi::{JSContext, JSRuntime};
|
||||
|
@ -43,11 +42,11 @@ use js;
|
|||
use servo_msg::compositor_msg::{FinishedLoading, LayerId, Loading};
|
||||
use servo_msg::compositor_msg::{ScriptListener};
|
||||
use servo_msg::constellation_msg::{ConstellationChan, LoadCompleteMsg, LoadUrlMsg, NavigationDirection};
|
||||
use servo_msg::constellation_msg::{PipelineId, SubpageId, Failure, FailureMsg};
|
||||
use servo_msg::constellation_msg::{PipelineId, SubpageId, Failure, FailureMsg, WindowSizeData};
|
||||
use servo_msg::constellation_msg;
|
||||
use servo_net::image_cache_task::ImageCacheTask;
|
||||
use servo_net::resource_task::ResourceTask;
|
||||
use servo_util::geometry::{PagePx, to_frac_px};
|
||||
use servo_util::geometry::to_frac_px;
|
||||
use servo_util::task::send_on_failure;
|
||||
use std::cell::RefCell;
|
||||
use std::comm::{channel, Sender, Receiver};
|
||||
|
@ -76,13 +75,13 @@ pub enum ScriptMsg {
|
|||
/// Sends a DOM event.
|
||||
SendEventMsg(PipelineId, Event_),
|
||||
/// Window resized. Sends a DOM event eventually, but first we combine events.
|
||||
ResizeMsg(PipelineId, TypedSize2D<PagePx, f32>),
|
||||
ResizeMsg(PipelineId, WindowSizeData),
|
||||
/// Fires a JavaScript timeout.
|
||||
FireTimerMsg(PipelineId, TimerId),
|
||||
/// Notifies script that reflow is finished.
|
||||
ReflowCompleteMsg(PipelineId, uint),
|
||||
/// Notifies script that window has been resized but to not take immediate action.
|
||||
ResizeInactiveMsg(PipelineId, TypedSize2D<PagePx, f32>),
|
||||
ResizeInactiveMsg(PipelineId, WindowSizeData),
|
||||
/// Notifies the script that a pipeline should be closed.
|
||||
ExitPipelineMsg(PipelineId),
|
||||
/// Notifies the script that a window associated with a particular pipeline should be closed.
|
||||
|
@ -208,7 +207,7 @@ impl ScriptTask {
|
|||
constellation_chan: ConstellationChan,
|
||||
resource_task: ResourceTask,
|
||||
img_cache_task: ImageCacheTask,
|
||||
window_size: TypedSize2D<PagePx, f32>)
|
||||
window_size: WindowSizeData)
|
||||
-> Rc<ScriptTask> {
|
||||
let (js_runtime, js_context) = ScriptTask::new_rt_and_cx();
|
||||
let page = Page::new(id, None, layout_chan, window_size,
|
||||
|
@ -289,7 +288,7 @@ impl ScriptTask {
|
|||
failure_msg: Failure,
|
||||
resource_task: ResourceTask,
|
||||
image_cache_task: ImageCacheTask,
|
||||
window_size: TypedSize2D<PagePx, f32>) {
|
||||
window_size: WindowSizeData) {
|
||||
let mut builder = TaskBuilder::new().named("ScriptTask");
|
||||
let ConstellationChan(const_chan) = constellation_chan.clone();
|
||||
send_on_failure(&mut builder, FailureMsg(failure_msg), const_chan);
|
||||
|
@ -463,7 +462,7 @@ impl ScriptTask {
|
|||
}
|
||||
|
||||
/// Window was resized, but this script was not active, so don't reflow yet
|
||||
fn handle_resize_inactive_msg(&self, id: PipelineId, new_size: TypedSize2D<PagePx, f32>) {
|
||||
fn handle_resize_inactive_msg(&self, id: PipelineId, new_size: WindowSizeData) {
|
||||
let mut page = self.page.borrow_mut();
|
||||
let page = page.find(id).expect("Received resize message for PipelineId not associated
|
||||
with a page in the page tree. This is a bug.");
|
||||
|
|
|
@ -33,14 +33,32 @@ pub enum DevicePixel {}
|
|||
/// `servo::windowing::WindowMethods::hidpi_factor`.
|
||||
pub enum ScreenPx {}
|
||||
|
||||
/// One CSS "px" in the coordinate system of the "initial viewport":
|
||||
/// http://www.w3.org/TR/css-device-adapt/#initial-viewport
|
||||
///
|
||||
/// ViewportPx is equal to ScreenPx times a "page zoom" factor controlled by the user. This is
|
||||
/// the desktop-style "full page" zoom that enlarges content but then reflows the layout viewport
|
||||
/// so it still exactly fits the visible area.
|
||||
///
|
||||
/// At the default zoom level of 100%, one PagePx is equal to one ScreenPx. However, if the
|
||||
/// document is zoomed in or out then this scale may be larger or smaller.
|
||||
pub enum ViewportPx {}
|
||||
|
||||
/// One CSS "px" in the root coordinate system for the content document.
|
||||
///
|
||||
///
|
||||
/// PagePx is equal to ScreenPx multiplied by a "zoom" factor controlled by the user. At the
|
||||
/// default zoom level of 100%, one PagePx is equal to one ScreenPx. However, if the document
|
||||
/// is zoomed in or out then this scale may be larger or smaller.
|
||||
/// PagePx is equal to ViewportPx multiplied by a "viewport zoom" factor controlled by the user.
|
||||
/// This is the mobile-style "pinch zoom" that enlarges content without reflowing it. When the
|
||||
/// viewport zoom is not equal to 1.0, then the layout viewport is no longer the same physical size
|
||||
/// as the viewable area.
|
||||
pub enum PagePx {}
|
||||
|
||||
// In summary, the hierarchy of pixel units and the factors to convert from one to the next:
|
||||
//
|
||||
// DevicePixel
|
||||
// / hidpi_ratio => ScreenPx
|
||||
// / desktop_zoom => ViewportPx
|
||||
// / pinch_zoom => PagePx
|
||||
|
||||
// An Au is an "App Unit" and represents 1/60th of a CSS pixel. It was
|
||||
// originally proposed in 2002 as a standard unit of measure in Gecko.
|
||||
// See https://bugzilla.mozilla.org/show_bug.cgi?id=177805 for more info.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue