Use typed coordinates.

We use Size2D and Point2D across compositing, constellation and script,
losing the type of pixels we use (DevicePixel, DeviceIndepententPixel
or CSSPixel) along the way, which might lead to bugs like
window.outerHeight not taking into account the page zoom (using
DeviceIndepententPixel instead of CSSPixel).
This commit is contained in:
Paul Rouget 2018-03-01 07:41:00 +01:00
parent b93f153ed5
commit ac4614d6ce
10 changed files with 122 additions and 102 deletions

View file

@ -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<u32> {
let (send, recv) = ipc::channel::<(Size2D<u32>)>().unwrap();
fn screen_size(&self) -> TypedSize2D<u32, CSSPixel> {
let (send, recv) = ipc::channel::<(TypedSize2D<u32, DevicePixel>)>().unwrap();
self.window.upcast::<GlobalScope>()
.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<u32> {
let (send, recv) = ipc::channel::<(Size2D<u32>)>().unwrap();
fn screen_avail_size(&self) -> TypedSize2D<u32, CSSPixel> {
let (send, recv) = ipc::channel::<(TypedSize2D<u32, DevicePixel>)>().unwrap();
self.window.upcast::<GlobalScope>()
.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()
}
}

View file

@ -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<f64> {
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<u32>, Point2D<i32>) {
let (send, recv) = ipc::channel::<(Size2D<u32>, Point2D<i32>)>().unwrap();
pub fn device_pixel_ratio(&self) -> TypedScale<f32, CSSPixel, DevicePixel> {
self.window_size.get().map_or(TypedScale::new(1.0), |data| data.device_pixel_ratio)
}
fn client_window(&self) -> (TypedSize2D<u32, CSSPixel>, TypedPoint2D<i32, CSSPixel>) {
let (send, recv) = ipc::channel::<(TypedSize2D<u32, DevicePixel>, TypedPoint2D<i32, DevicePixel>)>().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