diff --git a/src/components/main/compositing/compositor.rs b/src/components/main/compositing/compositor.rs index 3eba8719b55..9a29ca083f8 100644 --- a/src/components/main/compositing/compositor.rs +++ b/src/components/main/compositing/compositor.rs @@ -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, + /// "Mobile-style" zoom that does not reflow the page. + viewport_zoom: ScaleFactor, + + /// "Desktop-style" zoom that resizes the viewport to fit the window. + /// See `ViewportPx` docs in util/geom.rs for details. + page_zoom: ScaleFactor, + /// The device pixel ratio for this window. hidpi_factor: ScaleFactor, @@ -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, - /// 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 { - 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(); diff --git a/src/components/main/compositing/headless.rs b/src/components/main/compositing/headless.rs index 14e587cba32..0260518c582 100644 --- a/src/components/main/compositing/headless.rs +++ b/src/components/main/compositing/headless.rs @@ -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); diff --git a/src/components/main/constellation.rs b/src/components/main/constellation.rs index b43f113abb6..6aee7078ee5 100644 --- a/src/components/main/constellation.rs +++ b/src/components/main/constellation.rs @@ -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, pending_sizes: HashMap<(PipelineId, SubpageId), TypedRect>, pub profiler_chan: ProfilerChan, - pub window_size: TypedSize2D, + 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) { + 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"); diff --git a/src/components/main/layout/layout_task.rs b/src/components/main/layout/layout_task.rs index d3ed609a004..8e8b5f60bf5 100644 --- a/src/components/main/layout/layout_task.rs +++ b/src/components/main/layout/layout_task.rs @@ -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 } diff --git a/src/components/main/pipeline.rs b/src/components/main/pipeline.rs index 04902ff0a10..8d62cc106a9 100644 --- a/src/components/main/pipeline.rs +++ b/src/components/main/pipeline.rs @@ -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, + window_size: WindowSizeData, opts: Opts, url: Url) -> Pipeline { diff --git a/src/components/main/platform/common/glfw_windowing.rs b/src/components/main/platform/common/glfw_windowing.rs index 5821dbd21cb..ca42af1f13f 100644 --- a/src/components/main/platform/common/glfw_windowing.rs +++ b/src/components/main/platform/common/glfw_windowing.rs @@ -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)); diff --git a/src/components/main/windowing.rs b/src/components/main/windowing.rs index adb7942f460..9abd2d3de42 100644 --- a/src/components/main/windowing.rs +++ b/src/components/main/windowing.rs @@ -43,6 +43,8 @@ pub enum WindowEvent { ScrollWindowEvent(TypedPoint2D, TypedPoint2D), /// 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. diff --git a/src/components/msg/constellation_msg.rs b/src/components/msg/constellation_msg.rs index c75d8a02a10..f287398302a 100644 --- a/src/components/msg/constellation_msg.rs +++ b/src/components/msg/constellation_msg.rs @@ -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, } +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, + + /// The "viewing area" in page px. See `PagePx` documentation for details. + pub visible_viewport: TypedSize2D, + + /// The resolution of the window in dppx, not including any "pinch zoom" factor. + pub device_pixel_ratio: ScaleFactor, +} + /// 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), + ResizedWindowMsg(WindowSizeData), } /// Represents the two different ways to which a page can be navigated diff --git a/src/components/script/dom/event.rs b/src/components/script/dom/event.rs index 213aaa10e46..e3406fb1013 100644 --- a/src/components/script/dom/event.rs +++ b/src/components/script/dom/event.rs @@ -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), + ResizeEvent(WindowSizeData), ReflowEvent, ClickEvent(uint, Point2D), MouseDownEvent(uint, Point2D), diff --git a/src/components/script/layout_interface.rs b/src/components/script/layout_interface.rs index a91309446c7..487fb8f0862 100644 --- a/src/components/script/layout_interface.rs +++ b/src/components/script/layout_interface.rs @@ -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, + pub window_size: WindowSizeData, /// The channel that we send a notification to. pub script_join_chan: Sender<()>, /// Unique identifier diff --git a/src/components/script/page.rs b/src/components/script/page.rs index a508aadda5b..c8f884e6b08 100644 --- a/src/components/script/page.rs +++ b/src/components/script/page.rs @@ -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>>, /// The current size of the window, in pixels. - pub window_size: Untraceable>>, + pub window_size: Untraceable>, js_info: Traceable>>, @@ -75,7 +73,7 @@ pub struct Page { next_subpage_id: Untraceable>, /// Pending resize event, if any. - pub resize_event: Untraceable>>>, + pub resize_event: Untraceable>>, /// Pending scroll to fragment event, if any pub fragment_node: Cell>>, @@ -119,7 +117,8 @@ impl IterablePage for Rc { impl Page { pub fn new(id: PipelineId, subpage_id: Option, layout_chan: LayoutChan, - window_size: TypedSize2D, resource_task: ResourceTask, + window_size: WindowSizeData, + resource_task: ResourceTask, constellation_chan: ConstellationChan, js_context: Rc) -> Page { let js_info = JSPageInfo { diff --git a/src/components/script/script_task.rs b/src/components/script/script_task.rs index eadbf4f7819..eab376411de 100644 --- a/src/components/script/script_task.rs +++ b/src/components/script/script_task.rs @@ -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), + 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), + 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) + window_size: WindowSizeData) -> Rc { 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) { + 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) { + 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."); diff --git a/src/components/util/geometry.rs b/src/components/util/geometry.rs index 9e70e0bdf10..e8f8afd4638 100644 --- a/src/components/util/geometry.rs +++ b/src/components/util/geometry.rs @@ -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.