diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index 027151af9b4..a05b2a5bccb 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -6,7 +6,7 @@ use CompositionPipeline; use SendableFrameTree; use compositor_thread::{CompositorProxy, CompositorReceiver}; use compositor_thread::{InitialCompositorState, Msg}; -use euclid::{TypedPoint2D, TypedVector2D, TypedScale}; +use euclid::{Length, TypedPoint2D, TypedVector2D, TypedScale}; use gfx_traits::Epoch; use gleam::gl; use image::{DynamicImage, ImageFormat, RgbImage}; @@ -274,15 +274,15 @@ impl RenderTargetInfo { } } -fn initialize_png(gl: &gl::Gl, width: usize, height: usize) -> RenderTargetInfo { +fn initialize_png(gl: &gl::Gl, width: Length, height: Length) -> 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); @@ -296,8 +296,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, @@ -646,9 +646,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) { @@ -1253,8 +1255,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) } @@ -1374,9 +1375,11 @@ impl IOCompositor { fn draw_img(&self, render_target_info: RenderTargetInfo, - width: usize, - height: usize) + width: Length, + height: Length) -> 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..143107504e2 100644 --- a/components/compositing/compositor_thread.rs +++ b/components/compositing/compositor_thread.rs @@ -6,7 +6,7 @@ use SendableFrameTree; use compositor::CompositingReason; -use euclid::{Point2D, Size2D}; +use euclid::{TypedPoint2D, TypedSize2D}; use gfx_traits::Epoch; use ipc_channel::ipc::IpcSender; use msg::constellation_msg::{Key, KeyModifiers, KeyState, PipelineId, TopLevelBrowsingContextId}; @@ -17,6 +17,7 @@ use script_traits::{AnimationState, ConstellationMsg, EventResult, LoadData}; use servo_url::ServoUrl; use std::fmt::{Debug, Error, Formatter}; use std::sync::mpsc::{Receiver, Sender}; +use style_traits::DevicePixel; use style_traits::cursor::CursorKind; use style_traits::viewport::ViewportConstraints; use webrender; @@ -119,15 +120,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, TypedPoint2D), /// Resize the window to size - ResizeTo(TopLevelBrowsingContextId, Size2D), + ResizeTo(TopLevelBrowsingContextId, TypedSize2D), /// Get Window Informations size and position - GetClientWindow(TopLevelBrowsingContextId, IpcSender<(Size2D, Point2D)>), + GetClientWindow(TopLevelBrowsingContextId, + IpcSender<(TypedSize2D, TypedPoint2D)>), /// Get screen size (pixel) - GetScreenSize(TopLevelBrowsingContextId, IpcSender<(Size2D)>), + GetScreenSize(TopLevelBrowsingContextId, IpcSender<(TypedSize2D)>), /// Get screen available size (pixel) - GetScreenAvailSize(TopLevelBrowsingContextId, IpcSender<(Size2D)>), + GetScreenAvailSize(TopLevelBrowsingContextId, IpcSender<(TypedSize2D)>), /// 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 473e85fcb07..4be339718fe 100644 --- a/components/compositing/windowing.rs +++ b/components/compositing/windowing.rs @@ -5,8 +5,7 @@ //! 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::{Length, TypedScale, TypedPoint2D, TypedSize2D}; use gleam::gl; use ipc_channel::ipc::IpcSender; use msg::constellation_msg::{Key, KeyModifiers, KeyState, TopLevelBrowsingContextId, TraversalDirection}; @@ -123,21 +122,22 @@ 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; + /// Returns the size of the window. + 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) -> + (TypedSize2D, TypedPoint2D); + /// Return the size of the screen. + fn screen_size(&self, ctx: TopLevelBrowsingContextId) -> TypedSize2D; + /// Return the available size of the screen. + fn screen_avail_size(&self, ctx: TopLevelBrowsingContextId) -> TypedSize2D; /// 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: TypedSize2D); /// Set the window position - fn set_position(&self, ctx: TopLevelBrowsingContextId, point: Point2D); + fn set_position(&self, ctx: TopLevelBrowsingContextId, point: TypedPoint2D); /// Set fullscreen state fn set_fullscreen_state(&self, ctx: TopLevelBrowsingContextId, state: bool); @@ -167,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: Length, height: Length) -> bool; /// Sets the cursor to be used in the window. fn set_cursor(&self, cursor: CursorKind); diff --git a/components/script/dom/screen.rs b/components/script/dom/screen.rs index 3cd54034994..6893bf6c8da 100644 --- a/components/script/dom/screen.rs +++ b/components/script/dom/screen.rs @@ -11,9 +11,10 @@ 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, DevicePixel}; #[dom_struct] pub struct Screen { @@ -35,18 +36,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::<(TypedSize2D)>().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::<(TypedSize2D)>().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..8494e2f4f16 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; @@ -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::<(TypedSize2D, TypedPoint2D)>().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..e51e49865bc 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; @@ -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, TypedSize2D, 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..1d524b89710 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, TypedPoint2D, TypedSize2D}; use gfx_traits::Epoch; use ipc_channel::ipc::{IpcReceiver, IpcSender}; use msg::constellation_msg::{BrowsingContextId, PipelineId, TraversalDirection}; @@ -23,7 +23,7 @@ use net_traits::request::RequestInit; use net_traits::storage_thread::StorageType; use servo_url::ImmutableOrigin; use servo_url::ServoUrl; -use style_traits::CSSPixel; +use style_traits::{DevicePixel, CSSPixel}; use style_traits::cursor::CursorKind; use style_traits::viewport::ViewportConstraints; @@ -136,11 +136,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<(TypedSize2D, TypedPoint2D)>), /// Move the window to a point - MoveTo(Point2D), + MoveTo(TypedPoint2D), /// Resize the window to size - ResizeTo(Size2D), + ResizeTo(TypedSize2D), /// 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 +155,9 @@ pub enum ScriptMsg { /// Enter or exit fullscreen SetFullscreenState(bool), /// Get the screen size (pixel) - GetScreenSize(IpcSender<(Size2D)>), + GetScreenSize(IpcSender<(TypedSize2D)>), /// Get the available screen size (pixel) - GetScreenAvailSize(IpcSender<(Size2D)>), + GetScreenAvailSize(IpcSender<(TypedSize2D)>), /// Requests that the compositor shut down. Exit, } diff --git a/components/servo/lib.rs b/components/servo/lib.rs index 45b6af50c89..05712aee18a 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 a243d32e4c8..2893c2eff6d 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; @@ -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>, @@ -223,8 +223,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"); + (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 +236,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 +267,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 +315,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 +421,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 +431,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 +479,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 +516,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 +869,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.size().to_u32() } fn window_rect(&self) -> DeviceUintRect { @@ -880,34 +878,36 @@ impl WindowMethods for Window { DeviceUintRect::new(origin, size) } - fn size(&self) -> TypedSize2D { - self.inner_size.get().to_f32() + fn size(&self) -> TypedSize2D { + self.inner_size.get().to_f32() * self.hidpi_factor() } - fn client_window(&self, _: BrowserId) -> (Size2D, Point2D) { - match self.kind { + fn client_window(&self, _: BrowserId) -> (TypedSize2D, TypedPoint2D) { + 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) -> TypedSize2D { + (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) -> TypedSize2D { // FIXME: Glutin doesn't have API for available size. Fallback to screen size self.screen_size(browser_id) } @@ -916,19 +916,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: TypedSize2D) { 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: TypedPoint2D) { 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 +1114,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 }