diff --git a/Cargo.lock b/Cargo.lock index ae1ca42f20e..1270490786f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2815,6 +2815,7 @@ dependencies = [ "euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)", "malloc_size_of 0.0.1", "malloc_size_of_derive 0.0.1", + "style_traits 0.0.1", "webrender_api 0.57.0 (git+https://github.com/servo/webrender)", ] diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index 88a3dc6b5ef..2b409b7ae3d 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -21,7 +21,7 @@ use script_traits::{MouseButton, MouseEventType, ScrollState, TouchEventType, To use script_traits::{UntrustedNodeAddress, WindowSizeData, WindowSizeType}; use script_traits::CompositorEvent::{MouseMoveEvent, MouseButtonEvent, TouchEvent}; use servo_config::opts; -use servo_geometry::DeviceIndependentPixel; +use servo_geometry::{DeviceIndependentPixel, DeviceUintLength}; use std::collections::HashMap; use std::env; use std::fs::File; @@ -34,7 +34,7 @@ use style_traits::viewport::ViewportConstraints; use time::{now, precise_time_ns, precise_time_s}; use touch::{TouchHandler, TouchAction}; use webrender; -use webrender_api::{self, DeviceUintRect, DeviceUintSize, HitTestFlags, HitTestResult}; +use webrender_api::{self, DeviceIntPoint, DevicePoint, DeviceUintRect, DeviceUintSize, HitTestFlags, HitTestResult}; use webrender_api::{LayoutVector2D, ScrollEventPhase, ScrollLocation}; use windowing::{self, MouseWindowEvent, WebRenderDebugOption, WindowMethods}; @@ -202,7 +202,7 @@ struct ScrollZoomEvent { /// Scroll by this offset, or to Start or End scroll_location: ScrollLocation, /// Apply changes to the frame at this location - cursor: TypedPoint2D, + cursor: DeviceIntPoint, /// The scroll event phase. phase: ScrollEventPhase, /// The number of OS events that have been coalesced together into this one event. @@ -275,15 +275,15 @@ impl RenderTargetInfo { } } -fn initialize_png(gl: &gl::Gl, width: usize, height: usize) -> RenderTargetInfo { +fn initialize_png(gl: &gl::Gl, width: DeviceUintLength, height: DeviceUintLength) -> RenderTargetInfo { let framebuffer_ids = gl.gen_framebuffers(1); gl.bind_framebuffer(gl::FRAMEBUFFER, framebuffer_ids[0]); let texture_ids = gl.gen_textures(1); gl.bind_texture(gl::TEXTURE_2D, texture_ids[0]); - gl.tex_image_2d(gl::TEXTURE_2D, 0, gl::RGB as gl::GLint, width as gl::GLsizei, - height as gl::GLsizei, 0, gl::RGB, gl::UNSIGNED_BYTE, None); + gl.tex_image_2d(gl::TEXTURE_2D, 0, gl::RGB as gl::GLint, width.get() as gl::GLsizei, + height.get() as gl::GLsizei, 0, gl::RGB, gl::UNSIGNED_BYTE, None); gl.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST as gl::GLint); gl.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as gl::GLint); @@ -297,8 +297,8 @@ fn initialize_png(gl: &gl::Gl, width: usize, height: usize) -> RenderTargetInfo gl.bind_renderbuffer(gl::RENDERBUFFER, depth_rb); gl.renderbuffer_storage(gl::RENDERBUFFER, gl::DEPTH_COMPONENT24, - width as gl::GLsizei, - height as gl::GLsizei); + width.get() as gl::GLsizei, + height.get() as gl::GLsizei); gl.framebuffer_renderbuffer(gl::FRAMEBUFFER, gl::DEPTH_ATTACHMENT, gl::RENDERBUFFER, @@ -647,9 +647,11 @@ impl IOCompositor { device_pixel_ratio: dppx, initial_viewport: initial_viewport, }; + let top_level_browsing_context_id = self.root_pipeline.as_ref().map(|pipeline| { pipeline.top_level_browsing_context_id }); + let msg = ConstellationMsg::WindowSize(top_level_browsing_context_id, data, size_type); if let Err(e) = self.constellation_chan.send(msg) { @@ -728,7 +730,7 @@ impl IOCompositor { } } - fn hit_test_at_point(&self, point: TypedPoint2D) -> HitTestResult { + fn hit_test_at_point(&self, point: DevicePoint) -> HitTestResult { let dppx = self.page_zoom * self.hidpi_factor(); let scaled_point = (point / dppx).to_untyped(); @@ -742,7 +744,7 @@ impl IOCompositor { } - pub fn on_mouse_window_move_event_class(&mut self, cursor: TypedPoint2D) { + pub fn on_mouse_window_move_event_class(&mut self, cursor: DevicePoint) { if opts::get().convert_mouse_to_touch { self.on_touch_move(TouchId(0), cursor); return @@ -751,7 +753,7 @@ impl IOCompositor { self.dispatch_mouse_window_move_event_class(cursor); } - fn dispatch_mouse_window_move_event_class(&mut self, cursor: TypedPoint2D) { + fn dispatch_mouse_window_move_event_class(&mut self, cursor: DevicePoint) { let root_pipeline_id = match self.get_root_pipeline_id() { Some(root_pipeline_id) => root_pipeline_id, None => return, @@ -783,7 +785,7 @@ impl IOCompositor { &self, event_type: TouchEventType, identifier: TouchId, - point: TypedPoint2D) + point: DevicePoint) { let results = self.hit_test_at_point(point); if let Some(item) = results.items.first() { @@ -804,7 +806,7 @@ impl IOCompositor { pub fn on_touch_event(&mut self, event_type: TouchEventType, identifier: TouchId, - location: TypedPoint2D) { + location: DevicePoint) { match event_type { TouchEventType::Down => self.on_touch_down(identifier, location), TouchEventType::Move => self.on_touch_move(identifier, location), @@ -813,12 +815,12 @@ impl IOCompositor { } } - fn on_touch_down(&mut self, identifier: TouchId, point: TypedPoint2D) { + fn on_touch_down(&mut self, identifier: TouchId, point: DevicePoint) { self.touch_handler.on_touch_down(identifier, point); self.send_touch_event(TouchEventType::Down, identifier, point); } - fn on_touch_move(&mut self, identifier: TouchId, point: TypedPoint2D) { + fn on_touch_move(&mut self, identifier: TouchId, point: DevicePoint) { match self.touch_handler.on_touch_move(identifier, point) { TouchAction::Scroll(delta) => { match point.cast() { @@ -849,7 +851,7 @@ impl IOCompositor { } } - fn on_touch_up(&mut self, identifier: TouchId, point: TypedPoint2D) { + fn on_touch_up(&mut self, identifier: TouchId, point: DevicePoint) { self.send_touch_event(TouchEventType::Up, identifier, point); if let TouchAction::Click = self.touch_handler.on_touch_up(identifier, point) { @@ -857,14 +859,14 @@ impl IOCompositor { } } - fn on_touch_cancel(&mut self, identifier: TouchId, point: TypedPoint2D) { + fn on_touch_cancel(&mut self, identifier: TouchId, point: DevicePoint) { // Send the event to script. self.touch_handler.on_touch_cancel(identifier, point); self.send_touch_event(TouchEventType::Cancel, identifier, point); } /// - fn simulate_mouse_click(&mut self, p: TypedPoint2D) { + fn simulate_mouse_click(&mut self, p: DevicePoint) { let button = MouseButton::Left; self.dispatch_mouse_window_move_event_class(p); self.dispatch_mouse_window_event_class(MouseWindowEvent::MouseDown(button, p)); @@ -874,7 +876,7 @@ impl IOCompositor { pub fn on_scroll_event(&mut self, delta: ScrollLocation, - cursor: TypedPoint2D, + cursor: DeviceIntPoint, phase: TouchEventType) { match phase { TouchEventType::Move => self.on_scroll_window_event(delta, cursor), @@ -889,7 +891,7 @@ impl IOCompositor { fn on_scroll_window_event(&mut self, scroll_location: ScrollLocation, - cursor: TypedPoint2D) { + cursor: DeviceIntPoint) { let event_phase = match (self.scroll_in_progress, self.in_scroll_transaction) { (false, None) => ScrollEventPhase::Start, (false, Some(last_scroll)) if last_scroll.elapsed() > Duration::from_millis(80) => @@ -908,7 +910,7 @@ impl IOCompositor { fn on_scroll_start_window_event(&mut self, scroll_location: ScrollLocation, - cursor: TypedPoint2D) { + cursor: DeviceIntPoint) { self.scroll_in_progress = true; self.pending_scroll_zoom_events.push(ScrollZoomEvent { magnification: 1.0, @@ -921,7 +923,7 @@ impl IOCompositor { fn on_scroll_end_window_event(&mut self, scroll_location: ScrollLocation, - cursor: TypedPoint2D) { + cursor: DeviceIntPoint) { self.scroll_in_progress = false; self.pending_scroll_zoom_events.push(ScrollZoomEvent { magnification: 1.0, @@ -1254,8 +1256,7 @@ impl IOCompositor { fn composite_specific_target(&mut self, target: CompositeTarget) -> Result, UnableToComposite> { - let (width, height) = - (self.frame_size.width as usize, self.frame_size.height as usize); + let (width, height) = (self.frame_size.width_typed(), self.frame_size.height_typed()); if !self.window.prepare_for_composite(width, height) { return Err(UnableToComposite::WindowUnprepared) } @@ -1375,9 +1376,11 @@ impl IOCompositor { fn draw_img(&self, render_target_info: RenderTargetInfo, - width: usize, - height: usize) + width: DeviceUintLength, + height: DeviceUintLength) -> RgbImage { + let width = width.get() as usize; + let height = height.get() as usize; // For some reason, OSMesa fails to render on the 3rd // attempt in headless mode, under some conditions. // I think this can only be some kind of synchronization diff --git a/components/compositing/compositor_thread.rs b/components/compositing/compositor_thread.rs index 2695970e320..d93c2c4a2bd 100644 --- a/components/compositing/compositor_thread.rs +++ b/components/compositing/compositor_thread.rs @@ -6,7 +6,6 @@ use SendableFrameTree; use compositor::CompositingReason; -use euclid::{Point2D, Size2D}; use gfx_traits::Epoch; use ipc_channel::ipc::IpcSender; use msg::constellation_msg::{Key, KeyModifiers, KeyState, PipelineId, TopLevelBrowsingContextId}; @@ -20,7 +19,7 @@ use std::sync::mpsc::{Receiver, Sender}; use style_traits::cursor::CursorKind; use style_traits::viewport::ViewportConstraints; use webrender; -use webrender_api; +use webrender_api::{self, DeviceIntPoint, DeviceUintSize}; /// Used to wake up the event loop, provided by the servo port/embedder. @@ -119,15 +118,16 @@ pub enum EmbedderMsg { /// Alerts the embedder that the current page has changed its title. ChangePageTitle(TopLevelBrowsingContextId, Option), /// Move the window to a point - MoveTo(TopLevelBrowsingContextId, Point2D), + MoveTo(TopLevelBrowsingContextId, DeviceIntPoint), /// Resize the window to size - ResizeTo(TopLevelBrowsingContextId, Size2D), + ResizeTo(TopLevelBrowsingContextId, DeviceUintSize), /// Get Window Informations size and position - GetClientWindow(TopLevelBrowsingContextId, IpcSender<(Size2D, Point2D)>), + GetClientWindow(TopLevelBrowsingContextId, + IpcSender<(DeviceUintSize, DeviceIntPoint)>), /// Get screen size (pixel) - GetScreenSize(TopLevelBrowsingContextId, IpcSender<(Size2D)>), + GetScreenSize(TopLevelBrowsingContextId, IpcSender<(DeviceUintSize)>), /// Get screen available size (pixel) - GetScreenAvailSize(TopLevelBrowsingContextId, IpcSender<(Size2D)>), + GetScreenAvailSize(TopLevelBrowsingContextId, IpcSender<(DeviceUintSize)>), /// Wether or not to follow a link AllowNavigation(TopLevelBrowsingContextId, ServoUrl, IpcSender), /// Sends an unconsumed key event back to the embedder. diff --git a/components/compositing/windowing.rs b/components/compositing/windowing.rs index 0426f0317bf..a1fb50d4626 100644 --- a/components/compositing/windowing.rs +++ b/components/compositing/windowing.rs @@ -5,26 +5,25 @@ //! Abstract windowing methods. The concrete implementations of these can be found in `platform/`. use compositor_thread::EventLoopWaker; -use euclid::{Point2D, Size2D}; -use euclid::{TypedScale, TypedPoint2D, TypedSize2D}; +use euclid::TypedScale; use gleam::gl; use ipc_channel::ipc::IpcSender; use msg::constellation_msg::{Key, KeyModifiers, KeyState, TopLevelBrowsingContextId, TraversalDirection}; use net_traits::net_error_list::NetError; use script_traits::{LoadData, MouseButton, TouchEventType, TouchId}; -use servo_geometry::DeviceIndependentPixel; +use servo_geometry::{DeviceIndependentPixel, DeviceUintLength}; use servo_url::ServoUrl; use std::fmt::{Debug, Error, Formatter}; use std::rc::Rc; use style_traits::DevicePixel; use style_traits::cursor::CursorKind; -use webrender_api::{DeviceUintSize, DeviceUintRect, ScrollLocation}; +use webrender_api::{DeviceIntPoint, DevicePoint, DeviceUintSize, DeviceUintRect, ScrollLocation}; #[derive(Clone)] pub enum MouseWindowEvent { - Click(MouseButton, TypedPoint2D), - MouseDown(MouseButton, TypedPoint2D), - MouseUp(MouseButton, TypedPoint2D), + Click(MouseButton, DevicePoint), + MouseDown(MouseButton, DevicePoint), + MouseUp(MouseButton, DevicePoint), } /// Various debug and profiling flags that WebRender supports. @@ -55,12 +54,12 @@ pub enum WindowEvent { /// Sent when a mouse hit test is to be performed. MouseWindowEventClass(MouseWindowEvent), /// Sent when a mouse move. - MouseWindowMoveEventClass(TypedPoint2D), + MouseWindowMoveEventClass(DevicePoint), /// Touch event: type, identifier, point - Touch(TouchEventType, TouchId, TypedPoint2D), + Touch(TouchEventType, TouchId, DevicePoint), /// Sent when the user scrolls. The first point is the delta and the second point is the /// origin. - Scroll(ScrollLocation, TypedPoint2D, TouchEventType), + Scroll(ScrollLocation, DeviceIntPoint, TouchEventType), /// Sent when the user zooms. Zoom(f32), /// Simulated "pinch zoom" gesture for non-touch platforms (e.g. ctrl-scrollwheel). @@ -126,21 +125,19 @@ pub trait WindowMethods { fn framebuffer_size(&self) -> DeviceUintSize; /// Returns the position and size of the window within the rendering area. fn window_rect(&self) -> DeviceUintRect; - /// Returns the size of the window in density-independent "px" units. - fn size(&self) -> TypedSize2D; /// Presents the window to the screen (perhaps by page flipping). fn present(&self); /// Return the size of the window with head and borders and position of the window values - fn client_window(&self, ctx: TopLevelBrowsingContextId) -> (Size2D, Point2D); - /// Return the size of the screen (pixel) - fn screen_size(&self, ctx: TopLevelBrowsingContextId) -> Size2D; - /// Return the available size of the screen (pixel) - fn screen_avail_size(&self, ctx: TopLevelBrowsingContextId) -> Size2D; + fn client_window(&self, ctx: TopLevelBrowsingContextId) -> (DeviceUintSize, DeviceIntPoint); + /// Return the size of the screen. + fn screen_size(&self, ctx: TopLevelBrowsingContextId) -> DeviceUintSize; + /// Return the available size of the screen. + fn screen_avail_size(&self, ctx: TopLevelBrowsingContextId) -> DeviceUintSize; /// Set the size inside of borders and head - fn set_inner_size(&self, ctx: TopLevelBrowsingContextId, size: Size2D); + fn set_inner_size(&self, ctx: TopLevelBrowsingContextId, size: DeviceUintSize); /// Set the window position - fn set_position(&self, ctx: TopLevelBrowsingContextId, point: Point2D); + fn set_position(&self, ctx: TopLevelBrowsingContextId, point: DeviceIntPoint); /// Set fullscreen state fn set_fullscreen_state(&self, ctx: TopLevelBrowsingContextId, state: bool); @@ -170,7 +167,7 @@ pub trait WindowMethods { /// Requests that the window system prepare a composite. Typically this will involve making /// some type of platform-specific graphics context current. Returns true if the composite may /// proceed and false if it should not. - fn prepare_for_composite(&self, width: usize, height: usize) -> bool; + fn prepare_for_composite(&self, width: DeviceUintLength, height: DeviceUintLength) -> bool; /// Sets the cursor to be used in the window. fn set_cursor(&self, cursor: CursorKind); diff --git a/components/geometry/Cargo.toml b/components/geometry/Cargo.toml index 8ca688bd64c..d37b8b9e64d 100644 --- a/components/geometry/Cargo.toml +++ b/components/geometry/Cargo.toml @@ -14,4 +14,5 @@ app_units = "0.6" euclid = "0.17" malloc_size_of = { path = "../malloc_size_of" } malloc_size_of_derive = { path = "../malloc_size_of_derive" } +style_traits = { path = "../style_traits" } webrender_api = { git = "https://github.com/servo/webrender" } diff --git a/components/geometry/lib.rs b/components/geometry/lib.rs index c22c9d16055..c4bb9721bf6 100644 --- a/components/geometry/lib.rs +++ b/components/geometry/lib.rs @@ -5,16 +5,20 @@ extern crate app_units; extern crate euclid; extern crate malloc_size_of; +extern crate style_traits; #[macro_use] extern crate malloc_size_of_derive; extern crate webrender_api; use app_units::{Au, MAX_AU, MIN_AU}; -use euclid::{Point2D, Rect, Size2D}; +use euclid::{Length, Point2D, Rect, Size2D}; use std::f32; +use style_traits::DevicePixel; use webrender_api::{LayoutPoint, LayoutRect, LayoutSize}; // Units for use with euclid::length and euclid::scale_factor. +pub type DeviceUintLength = Length; + /// A normalized "pixel" at the default resolution for the display. /// /// Like the CSS "px" unit, the exact physical size of this unit may vary between devices, but it diff --git a/components/script/dom/screen.rs b/components/script/dom/screen.rs index 3cd54034994..e83cffd93a4 100644 --- a/components/script/dom/screen.rs +++ b/components/script/dom/screen.rs @@ -11,9 +11,11 @@ use dom::bindings::root::{Dom, DomRoot}; use dom::globalscope::GlobalScope; use dom::window::Window; use dom_struct::dom_struct; -use euclid::Size2D; +use euclid::TypedSize2D; use ipc_channel::ipc; use script_traits::ScriptMsg; +use style_traits::CSSPixel; +use webrender_api::DeviceUintSize; #[dom_struct] pub struct Screen { @@ -35,18 +37,22 @@ impl Screen { ScreenBinding::Wrap) } - fn screen_size(&self) -> Size2D { - let (send, recv) = ipc::channel::<(Size2D)>().unwrap(); + fn screen_size(&self) -> TypedSize2D { + let (send, recv) = ipc::channel::().unwrap(); self.window.upcast::() .script_to_constellation_chan().send(ScriptMsg::GetScreenSize(send)).unwrap(); - recv.recv().unwrap_or(Size2D::zero()) + let dpr = self.window.device_pixel_ratio(); + let screen = recv.recv().unwrap_or(TypedSize2D::zero()); + (screen.to_f32() / dpr).to_u32() } - fn screen_avail_size(&self) -> Size2D { - let (send, recv) = ipc::channel::<(Size2D)>().unwrap(); + fn screen_avail_size(&self) -> TypedSize2D { + let (send, recv) = ipc::channel::().unwrap(); self.window.upcast::() .script_to_constellation_chan().send(ScriptMsg::GetScreenAvailSize(send)).unwrap(); - recv.recv().unwrap_or(Size2D::zero()) + let dpr = self.window.device_pixel_ratio(); + let screen = recv.recv().unwrap_or(TypedSize2D::zero()); + (screen.to_f32() / dpr).to_u32() } } diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index f6177e90fcf..37f65f774b2 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -48,7 +48,7 @@ use dom::windowproxy::WindowProxy; use dom::worklet::Worklet; use dom::workletglobalscope::WorkletGlobalScopeType; use dom_struct::dom_struct; -use euclid::{Point2D, Vector2D, Rect, Size2D}; +use euclid::{Point2D, Vector2D, Rect, Size2D, TypedPoint2D, TypedScale, TypedSize2D}; use fetch; use ipc_channel::ipc::{self, IpcSender}; use ipc_channel::router::ROUTER; @@ -102,7 +102,7 @@ use style::properties::{ComputedValues, PropertyId}; use style::selector_parser::PseudoElement; use style::str::HTML_SPACE_CHARACTERS; use style::stylesheets::CssRuleType; -use style_traits::ParsingMode; +use style_traits::{CSSPixel, DevicePixel, ParsingMode}; use task::TaskCanceller; use task_source::dom_manipulation::DOMManipulationTaskSource; use task_source::file_reading::FileReadingTaskSource; @@ -116,7 +116,7 @@ use timers::{IsInterval, TimerCallback}; use tinyfiledialogs::{self, MessageBoxIcon}; use url::Position; use webdriver_handlers::jsval_to_webdriver; -use webrender_api::{ExternalScrollId, DocumentId}; +use webrender_api::{ExternalScrollId, DeviceIntPoint, DeviceUintSize, DocumentId}; use webvr_traits::WebVRMsg; /// Current state of the window object @@ -930,11 +930,12 @@ impl WindowMethods for Window { } // https://drafts.csswg.org/cssom-view/#dom-window-resizeto - fn ResizeTo(&self, x: i32, y: i32) { + fn ResizeTo(&self, width: i32, height: i32) { // Step 1 //TODO determine if this operation is allowed - let size = Size2D::new(x.to_u32().unwrap_or(1), y.to_u32().unwrap_or(1)); - self.send_to_constellation(ScriptMsg::ResizeTo(size)); + let dpr = self.device_pixel_ratio(); + let size = TypedSize2D::new(width, height).to_f32() * dpr; + self.send_to_constellation(ScriptMsg::ResizeTo(size.to_u32())); } // https://drafts.csswg.org/cssom-view/#dom-window-resizeby @@ -948,8 +949,9 @@ impl WindowMethods for Window { fn MoveTo(&self, x: i32, y: i32) { // Step 1 //TODO determine if this operation is allowed - let point = Point2D::new(x, y); - self.send_to_constellation(ScriptMsg::MoveTo(point)); + let dpr = self.device_pixel_ratio(); + let point = TypedPoint2D::new(x, y).to_f32() * dpr; + self.send_to_constellation(ScriptMsg::MoveTo(point.to_i32())); } // https://drafts.csswg.org/cssom-view/#dom-window-moveby @@ -985,8 +987,7 @@ impl WindowMethods for Window { // https://drafts.csswg.org/cssom-view/#dom-window-devicepixelratio fn DevicePixelRatio(&self) -> Finite { - let dpr = self.window_size.get().map_or(1.0f32, |data| data.device_pixel_ratio.get()); - Finite::wrap(dpr as f64) + Finite::wrap(self.device_pixel_ratio().get() as f64) } // https://html.spec.whatwg.org/multipage/#dom-window-status @@ -1174,10 +1175,16 @@ impl Window { self.current_viewport.set(new_viewport) } - pub fn client_window(&self) -> (Size2D, Point2D) { - let (send, recv) = ipc::channel::<(Size2D, Point2D)>().unwrap(); + pub fn device_pixel_ratio(&self) -> TypedScale { + self.window_size.get().map_or(TypedScale::new(1.0), |data| data.device_pixel_ratio) + } + + fn client_window(&self) -> (TypedSize2D, TypedPoint2D) { + let (send, recv) = ipc::channel::<(DeviceUintSize, DeviceIntPoint)>().unwrap(); self.send_to_constellation(ScriptMsg::GetClientWindow(send)); - recv.recv().unwrap_or((Size2D::zero(), Point2D::zero())) + let (size, point) = recv.recv().unwrap_or((TypedSize2D::zero(), TypedPoint2D::zero())); + let dpr = self.device_pixel_ratio(); + ((size.to_f32() / dpr).to_u32(), (point.to_f32() / dpr).to_i32()) } /// Advances the layout animation clock by `delta` milliseconds, and then diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs index 46f5ed6c90c..c65ad10be4b 100644 --- a/components/script_traits/lib.rs +++ b/components/script_traits/lib.rs @@ -41,7 +41,7 @@ pub mod webdriver_msg; use bluetooth_traits::BluetoothRequest; use canvas_traits::webgl::WebGLPipeline; use devtools_traits::{DevtoolScriptControlMsg, ScriptToDevtoolsControlMsg, WorkerId}; -use euclid::{Size2D, Length, Point2D, Vector2D, Rect, TypedScale, TypedSize2D}; +use euclid::{Length, Point2D, Vector2D, Rect, TypedSize2D, TypedScale}; use gfx_traits::Epoch; use hyper::header::Headers; use hyper::method::Method; @@ -69,7 +69,7 @@ use style_traits::CSSPixel; use style_traits::SpeculativePainter; use style_traits::cursor::CursorKind; use webdriver_msg::{LoadStatus, WebDriverScriptCommand}; -use webrender_api::{ExternalScrollId, DevicePixel, DocumentId, ImageKey}; +use webrender_api::{ExternalScrollId, DevicePixel, DeviceUintSize, DocumentId, ImageKey}; use webvr_traits::{WebVREvent, WebVRMsg}; pub use script_msg::{LayoutMsg, ScriptMsg, EventResult, LogEntry}; @@ -650,7 +650,7 @@ pub enum WebDriverCommandMsg { /// Act as if keys were pressed in the browsing context with the given ID. SendKeys(BrowsingContextId, Vec<(Key, KeyModifiers, KeyState)>), /// Set the window size. - SetWindowSize(TopLevelBrowsingContextId, Size2D, IpcSender), + SetWindowSize(TopLevelBrowsingContextId, DeviceUintSize, IpcSender), /// Take a screenshot of the window. TakeScreenshot(TopLevelBrowsingContextId, IpcSender>), } diff --git a/components/script_traits/script_msg.rs b/components/script_traits/script_msg.rs index 524a87d039a..153adbd98fe 100644 --- a/components/script_traits/script_msg.rs +++ b/components/script_traits/script_msg.rs @@ -13,7 +13,7 @@ use WorkerGlobalScopeInit; use WorkerScriptLoadOrigin; use canvas_traits::canvas::CanvasMsg; use devtools_traits::{ScriptToDevtoolsControlMsg, WorkerId}; -use euclid::{Point2D, Size2D, TypedSize2D}; +use euclid::{Size2D, TypedSize2D}; use gfx_traits::Epoch; use ipc_channel::ipc::{IpcReceiver, IpcSender}; use msg::constellation_msg::{BrowsingContextId, PipelineId, TraversalDirection}; @@ -26,6 +26,7 @@ use servo_url::ServoUrl; use style_traits::CSSPixel; use style_traits::cursor::CursorKind; use style_traits::viewport::ViewportConstraints; +use webrender_api::{DeviceIntPoint, DeviceUintSize}; /// Messages from the layout to the constellation. #[derive(Deserialize, Serialize)] @@ -136,11 +137,11 @@ pub enum ScriptMsg { /// Send a key event SendKeyEvent(Option, Key, KeyState, KeyModifiers), /// Get Window Informations size and position - GetClientWindow(IpcSender<(Size2D, Point2D)>), + GetClientWindow(IpcSender<(DeviceUintSize, DeviceIntPoint)>), /// Move the window to a point - MoveTo(Point2D), + MoveTo(DeviceIntPoint), /// Resize the window to size - ResizeTo(Size2D), + ResizeTo(DeviceUintSize), /// Script has handled a touch event, and either prevented or allowed default actions. TouchEventProcessed(EventResult), /// A log entry, with the top-level browsing context id and thread name @@ -155,9 +156,9 @@ pub enum ScriptMsg { /// Enter or exit fullscreen SetFullscreenState(bool), /// Get the screen size (pixel) - GetScreenSize(IpcSender<(Size2D)>), + GetScreenSize(IpcSender<(DeviceUintSize)>), /// Get the available screen size (pixel) - GetScreenAvailSize(IpcSender<(Size2D)>), + GetScreenAvailSize(IpcSender<(DeviceUintSize)>), /// Requests that the compositor shut down. Exit, } diff --git a/components/servo/lib.rs b/components/servo/lib.rs index f5ebed9f04d..bc1a7f6a8f1 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -81,6 +81,7 @@ use constellation::{FromCompositorLogger, FromScriptLogger}; #[cfg(all(not(target_os = "windows"), not(target_os = "ios")))] use constellation::content_process_sandbox_profile; use env_logger::Logger as EnvLogger; +use euclid::Length; #[cfg(all(not(target_os = "windows"), not(target_os = "ios")))] use gaol::sandbox::{ChildSandbox, ChildSandboxMethods}; use gfx::font_cache_thread::FontCacheThread; @@ -133,7 +134,7 @@ impl Servo where Window: WindowMethods + 'static { let opts = opts::get(); // Make sure the gl context is made current. - window.prepare_for_composite(0, 0); + window.prepare_for_composite(Length::new(0), Length::new(0)); // Get both endpoints of a special channel for communication between // the client window and the compositor. This channel is unique because diff --git a/components/webdriver_server/lib.rs b/components/webdriver_server/lib.rs index 0a77762994e..f660690a96c 100644 --- a/components/webdriver_server/lib.rs +++ b/components/webdriver_server/lib.rs @@ -27,7 +27,7 @@ extern crate webdriver; mod keys; -use euclid::Size2D; +use euclid::TypedSize2D; use hyper::method::Method::{self, Post}; use image::{DynamicImage, ImageFormat, RgbImage}; use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; @@ -418,7 +418,7 @@ impl Handler { Nullable::Value(v) => v, Nullable::Null => 0, }; - let size = Size2D::new(width as u32, height as u32); + let size = TypedSize2D::new(width as u32, height as u32); let top_level_browsing_context_id = self.session()?.top_level_browsing_context_id; let cmd_msg = WebDriverCommandMsg::SetWindowSize(top_level_browsing_context_id, size, sender.clone()); diff --git a/ports/servo/glutin_app/window.rs b/ports/servo/glutin_app/window.rs index 542715a85ed..2add73f9b18 100644 --- a/ports/servo/glutin_app/window.rs +++ b/ports/servo/glutin_app/window.rs @@ -7,7 +7,7 @@ use compositing::compositor_thread::EventLoopWaker; use compositing::windowing::{AnimationState, MouseWindowEvent, WindowEvent}; use compositing::windowing::{WebRenderDebugOption, WindowMethods}; -use euclid::{Point2D, Size2D, TypedPoint2D, TypedVector2D, TypedScale, TypedSize2D}; +use euclid::{Length, TypedPoint2D, TypedVector2D, TypedScale, TypedSize2D}; #[cfg(target_os = "windows")] use gdi32; use gleam::gl; @@ -40,7 +40,7 @@ use style_traits::cursor::CursorKind; use tinyfiledialogs; #[cfg(target_os = "windows")] use user32; -use webrender_api::{DeviceUintRect, DeviceUintSize, ScrollLocation}; +use webrender_api::{DeviceIntPoint, DeviceUintRect, DeviceUintSize, ScrollLocation}; #[cfg(target_os = "windows")] use winapi; use winit; @@ -177,18 +177,18 @@ enum WindowKind { /// The type of a window. pub struct Window { kind: WindowKind, - screen_size: Size2D, + screen_size: TypedSize2D, inner_size: Cell>, mouse_down_button: Cell>, - mouse_down_point: Cell>, + mouse_down_point: Cell>, event_queue: RefCell>, /// id of the top level browsing context. It is unique as tabs /// are not supported yet. None until created. browser_id: Cell>, - mouse_pos: Cell>, + mouse_pos: Cell>, key_modifiers: Cell, current_url: RefCell>, @@ -222,9 +222,7 @@ impl Window { pub fn new(is_foreground: bool, window_size: TypedSize2D) -> Rc { - let win_size: TypedSize2D = - (window_size.to_f32() * window_creation_scale_factor()) - .to_usize().cast().expect("Window size should fit in u32"); + let win_size: DeviceUintSize = (window_size.to_f32() * window_creation_scale_factor()).to_u32(); let width = win_size.to_untyped().width; let height = win_size.to_untyped().height; @@ -237,7 +235,7 @@ impl Window { let screen_size; let inner_size; let window_kind = if opts::get().headless { - screen_size = Size2D::new(width, height); + screen_size = TypedSize2D::new(width, height); inner_size = TypedSize2D::new(width, height); WindowKind::Headless(HeadlessContext::new(width, height)) } else { @@ -268,7 +266,7 @@ impl Window { } let (screen_width, screen_height) = events_loop.get_primary_monitor().get_dimensions(); - screen_size = Size2D::new(screen_width, screen_height); + screen_size = TypedSize2D::new(screen_width, screen_height); // TODO(ajeffrey): can this fail? let (width, height) = glutin_window.get_inner_size().expect("Failed to get window inner size."); inner_size = TypedSize2D::new(width, height); @@ -316,11 +314,11 @@ impl Window { kind: window_kind, event_queue: RefCell::new(vec!()), mouse_down_button: Cell::new(None), - mouse_down_point: Cell::new(Point2D::new(0, 0)), + mouse_down_point: Cell::new(TypedPoint2D::new(0, 0)), browser_id: Cell::new(None), - mouse_pos: Cell::new(Point2D::new(0, 0)), + mouse_pos: Cell::new(TypedPoint2D::new(0, 0)), key_modifiers: Cell::new(GlutinKeyModifiers::empty()), current_url: RefCell::new(None), @@ -422,8 +420,7 @@ impl Window { }, .. } => { if button == MouseButton::Left || button == MouseButton::Right { - let mouse_pos = self.mouse_pos.get(); - self.handle_mouse(button, state, mouse_pos.x, mouse_pos.y); + self.handle_mouse(button, state, self.mouse_pos.get()); } }, Event::WindowEvent { @@ -433,7 +430,7 @@ impl Window { }, .. } => { - self.mouse_pos.set(Point2D::new(x as i32, y as i32)); + self.mouse_pos.set(TypedPoint2D::new(x as i32, y as i32)); self.event_queue.borrow_mut().push( WindowEvent::MouseWindowMoveEventClass(TypedPoint2D::new(x as f32, y as f32))); } @@ -481,7 +478,7 @@ impl Window { } // window.set_inner_size() takes DeviceIndependentPixel. let new_size = TypedSize2D::new(width as f32, height as f32); - let new_size = (new_size / self.hidpi_factor()).cast().expect("Window size should fit in u32"); + let new_size = (new_size / self.hidpi_factor()).to_u32(); if self.inner_size.get() != new_size { self.inner_size.set(new_size); self.event_queue.borrow_mut().push(WindowEvent::Resize); @@ -518,37 +515,37 @@ impl Window { } } - let mouse_pos = self.mouse_pos.get(); - let event = WindowEvent::Scroll(scroll_location, - TypedPoint2D::new(mouse_pos.x as i32, mouse_pos.y as i32), - phase); + let pos = self.mouse_pos.get().to_f32() * self.hidpi_factor(); + let event = WindowEvent::Scroll(scroll_location, pos.to_i32(), phase); self.event_queue.borrow_mut().push(event); } /// Helper function to handle a click - fn handle_mouse(&self, button: winit::MouseButton, action: winit::ElementState, x: i32, y: i32) { + fn handle_mouse(&self, button: winit::MouseButton, + action: winit::ElementState, + coords: TypedPoint2D) { use script_traits::MouseButton; // FIXME(tkuehn): max pixel dist should be based on pixel density let max_pixel_dist = 10f64; + let scaled_coords = coords.to_f32() * self.hidpi_factor(); let event = match action { ElementState::Pressed => { - self.mouse_down_point.set(Point2D::new(x, y)); + self.mouse_down_point.set(coords); self.mouse_down_button.set(Some(button)); - MouseWindowEvent::MouseDown(MouseButton::Left, TypedPoint2D::new(x as f32, y as f32)) + MouseWindowEvent::MouseDown(MouseButton::Left, scaled_coords) } ElementState::Released => { - let mouse_up_event = MouseWindowEvent::MouseUp(MouseButton::Left, - TypedPoint2D::new(x as f32, y as f32)); + let mouse_up_event = MouseWindowEvent::MouseUp(MouseButton::Left, scaled_coords); match self.mouse_down_button.get() { None => mouse_up_event, Some(but) if button == but => { - let pixel_dist = self.mouse_down_point.get() - Point2D::new(x, y); + let pixel_dist = self.mouse_down_point.get() - coords; let pixel_dist = ((pixel_dist.x * pixel_dist.x + pixel_dist.y * pixel_dist.y) as f64).sqrt(); if pixel_dist < max_pixel_dist { self.event_queue.borrow_mut().push(WindowEvent::MouseWindowEventClass(mouse_up_event)); - MouseWindowEvent::Click(MouseButton::Left, TypedPoint2D::new(x as f32, y as f32)) + MouseWindowEvent::Click(MouseButton::Left, scaled_coords) } else { mouse_up_event } @@ -871,7 +868,7 @@ impl WindowMethods for Window { } fn framebuffer_size(&self) -> DeviceUintSize { - (self.inner_size.get().to_f32() * self.hidpi_factor()).to_usize().cast().expect("Window size should fit in u32") + (self.inner_size.get().to_f32() * self.hidpi_factor()).to_u32() } fn window_rect(&self) -> DeviceUintRect { @@ -880,34 +877,32 @@ impl WindowMethods for Window { DeviceUintRect::new(origin, size) } - fn size(&self) -> TypedSize2D { - self.inner_size.get().to_f32() - } - - fn client_window(&self, _: BrowserId) -> (Size2D, Point2D) { - match self.kind { + fn client_window(&self, _: BrowserId) -> (DeviceUintSize, DeviceIntPoint) { + let (size, point) = match self.kind { WindowKind::Window(ref window, ..) => { // TODO(ajeffrey): can this fail? let (width, height) = window.get_outer_size().expect("Failed to get window outer size."); - let size = Size2D::new(width, height); + let size = TypedSize2D::new(width as f32, height as f32); // TODO(ajeffrey): can this fail? let (x, y) = window.get_position().expect("Failed to get window position."); - let origin = Point2D::new(x as i32, y as i32); + let origin = TypedPoint2D::new(x as f32, y as f32); (size, origin) } WindowKind::Headless(ref context) => { - let size = TypedSize2D::new(context.width, context.height); - (size, Point2D::zero()) + let size = TypedSize2D::new(context.width as f32, context.height as f32); + let origin = TypedPoint2D::zero(); + (size, origin) } - } - + }; + let dpr = self.hidpi_factor(); + ((size * dpr).to_u32(), (point * dpr).to_i32()) } - fn screen_size(&self, _: BrowserId) -> Size2D { - self.screen_size + fn screen_size(&self, _: BrowserId) -> DeviceUintSize { + (self.screen_size.to_f32() * self.hidpi_factor()).to_u32() } - fn screen_avail_size(&self, browser_id: BrowserId) -> Size2D { + fn screen_avail_size(&self, browser_id: BrowserId) -> DeviceUintSize { // FIXME: Glutin doesn't have API for available size. Fallback to screen size self.screen_size(browser_id) } @@ -916,19 +911,21 @@ impl WindowMethods for Window { self.animation_state.set(state); } - fn set_inner_size(&self, _: BrowserId, size: Size2D) { + fn set_inner_size(&self, _: BrowserId, size: DeviceUintSize) { match self.kind { WindowKind::Window(ref window, ..) => { + let size = size.to_f32() / self.hidpi_factor(); window.set_inner_size(size.width as u32, size.height as u32) } WindowKind::Headless(..) => {} } } - fn set_position(&self, _: BrowserId, point: Point2D) { + fn set_position(&self, _: BrowserId, point: DeviceIntPoint) { match self.kind { WindowKind::Window(ref window, ..) => { - window.set_position(point.x, point.y) + let point = point.to_f32() / self.hidpi_factor(); + window.set_position(point.x as i32, point.y as i32) } WindowKind::Headless(..) => {} } @@ -1112,7 +1109,7 @@ impl WindowMethods for Window { fn set_favicon(&self, _: BrowserId, _: ServoUrl) { } - fn prepare_for_composite(&self, _width: usize, _height: usize) -> bool { + fn prepare_for_composite(&self, _width: Length, _height: Length) -> bool { true }