mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Outside of compositor, store window size in CSS px
This fixes an issue where the CSS viewport was too large on high-DPI displays because it was set to the window size in device pixels, instead of px. This patch ensures that the window size is converted from device pixels to px before being passed to script/layout code. The Window trait now exposes the window size in both device pixels and density-independent screen coordinates, with clearer method names.
This commit is contained in:
parent
e98b03f581
commit
89327aa5be
15 changed files with 104 additions and 85 deletions
|
@ -235,12 +235,12 @@ DONE_net = $(B)src/components/net/libnet.dummy
|
||||||
|
|
||||||
DEPS_net = $(CRATE_net) $(SRC_net) $(DONE_SUBMODULES) $(DONE_util)
|
DEPS_net = $(CRATE_net) $(SRC_net) $(DONE_SUBMODULES) $(DONE_util)
|
||||||
|
|
||||||
RFLAGS_msg = $(strip $(CFG_RUSTC_FLAGS)) $(addprefix -L $(B)src/,$(DEPS_SUBMODULES))
|
RFLAGS_msg = $(strip $(CFG_RUSTC_FLAGS)) $(addprefix -L $(B)src/,$(DEPS_SUBMODULES)) -L $(B)src/components/util
|
||||||
SRC_msg = $(call rwildcard,$(S)src/components/msg/,*.rs)
|
SRC_msg = $(call rwildcard,$(S)src/components/msg/,*.rs)
|
||||||
CRATE_msg = $(S)src/components/msg/msg.rs
|
CRATE_msg = $(S)src/components/msg/msg.rs
|
||||||
DONE_msg = $(B)src/components/msg/libmsg.dummy
|
DONE_msg = $(B)src/components/msg/libmsg.dummy
|
||||||
|
|
||||||
DEPS_msg = $(CRATE_msg) $(SRC_msg) $(DONE_SUBMODULES)
|
DEPS_msg = $(CRATE_msg) $(SRC_msg) $(DONE_SUBMODULES) $(DONE_util)
|
||||||
|
|
||||||
RFLAGS_gfx = $(strip $(CFG_RUSTC_FLAGS)) $(addprefix -L $(B)src/,$(DEPS_SUBMODULES)) -L $(B)src/components/util -L $(B)src/components/style -L $(B)src/components/net -L $(B)src/components/msg -L$(B)src/components/macros
|
RFLAGS_gfx = $(strip $(CFG_RUSTC_FLAGS)) $(addprefix -L $(B)src/,$(DEPS_SUBMODULES)) -L $(B)src/components/util -L $(B)src/components/style -L $(B)src/components/net -L $(B)src/components/msg -L$(B)src/components/macros
|
||||||
SRC_gfx = $(call rwildcard,$(S)src/components/gfx/,*.rs)
|
SRC_gfx = $(call rwildcard,$(S)src/components/gfx/,*.rs)
|
||||||
|
|
|
@ -128,7 +128,7 @@ impl IOCompositor {
|
||||||
// TODO: There should be no initial layer tree until the renderer creates one from the display
|
// TODO: There should be no initial layer tree until the renderer creates one from the display
|
||||||
// list. This is only here because we don't have that logic in the renderer yet.
|
// list. This is only here because we don't have that logic in the renderer yet.
|
||||||
let root_layer = Rc::new(ContainerLayer());
|
let root_layer = Rc::new(ContainerLayer());
|
||||||
let window_size = window.size();
|
let window_size = window.framebuffer_size();
|
||||||
let hidpi_factor = window.hidpi_factor();
|
let hidpi_factor = window.hidpi_factor();
|
||||||
|
|
||||||
IOCompositor {
|
IOCompositor {
|
||||||
|
@ -138,8 +138,8 @@ impl IOCompositor {
|
||||||
context: rendergl::init_render_context(),
|
context: rendergl::init_render_context(),
|
||||||
root_layer: root_layer.clone(),
|
root_layer: root_layer.clone(),
|
||||||
root_pipeline: None,
|
root_pipeline: None,
|
||||||
scene: Scene(ContainerLayerKind(root_layer), window_size.to_untyped(), identity()),
|
scene: Scene(ContainerLayerKind(root_layer), window_size.as_f32().to_untyped(), identity()),
|
||||||
window_size: window_size.as_uint(),
|
window_size: window_size,
|
||||||
hidpi_factor: hidpi_factor,
|
hidpi_factor: hidpi_factor,
|
||||||
graphics_context: CompositorTask::create_graphics_context(),
|
graphics_context: CompositorTask::create_graphics_context(),
|
||||||
composite_ready: false,
|
composite_ready: false,
|
||||||
|
@ -176,10 +176,7 @@ impl IOCompositor {
|
||||||
|
|
||||||
fn run (&mut self) {
|
fn run (&mut self) {
|
||||||
// Tell the constellation about the initial window size.
|
// Tell the constellation about the initial window size.
|
||||||
{
|
self.send_window_size();
|
||||||
let ConstellationChan(ref chan) = self.constellation_chan;
|
|
||||||
chan.send(ResizedWindowMsg(self.window_size.to_untyped()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enter the main event loop.
|
// Enter the main event loop.
|
||||||
while !self.done {
|
while !self.done {
|
||||||
|
@ -339,13 +336,8 @@ impl IOCompositor {
|
||||||
self.root_pipeline = Some(frame_tree.pipeline.clone());
|
self.root_pipeline = Some(frame_tree.pipeline.clone());
|
||||||
|
|
||||||
// Initialize the new constellation channel by sending it the root window size.
|
// Initialize the new constellation channel by sending it the root window size.
|
||||||
let window_size = self.window.size().as_uint();
|
|
||||||
{
|
|
||||||
let ConstellationChan(ref chan) = new_constellation_chan;
|
|
||||||
chan.send(ResizedWindowMsg(window_size.to_untyped()));
|
|
||||||
}
|
|
||||||
|
|
||||||
self.constellation_chan = new_constellation_chan;
|
self.constellation_chan = new_constellation_chan;
|
||||||
|
self.send_window_size();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_root_compositor_layer_if_necessary(&mut self,
|
fn create_root_compositor_layer_if_necessary(&mut self,
|
||||||
|
@ -425,6 +417,12 @@ impl IOCompositor {
|
||||||
self.window_size.as_f32() / self.device_pixels_per_page_px()
|
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 ConstellationChan(ref chan) = self.constellation_chan;
|
||||||
|
chan.send(ResizedWindowMsg(self.page_window()));
|
||||||
|
}
|
||||||
|
|
||||||
fn set_layer_page_size(&mut self,
|
fn set_layer_page_size(&mut self,
|
||||||
pipeline_id: PipelineId,
|
pipeline_id: PipelineId,
|
||||||
layer_id: LayerId,
|
layer_id: LayerId,
|
||||||
|
@ -527,8 +525,8 @@ impl IOCompositor {
|
||||||
self.recomposite = true;
|
self.recomposite = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResizeWindowEvent(width, height) => {
|
ResizeWindowEvent(size) => {
|
||||||
self.on_resize_window_event(width, height);
|
self.on_resize_window_event(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadUrlWindowEvent(url_string) => {
|
LoadUrlWindowEvent(url_string) => {
|
||||||
|
@ -574,22 +572,20 @@ impl IOCompositor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_resize_window_event(&mut self, width: uint, height: uint) {
|
fn on_resize_window_event(&mut self, new_size: TypedSize2D<DevicePixel, uint>) {
|
||||||
let new_size: TypedSize2D<DevicePixel, uint> = TypedSize2D(width, height);
|
|
||||||
if self.window_size != new_size {
|
|
||||||
debug!("osmain: window resized to {:u}x{:u}", width, height);
|
|
||||||
self.window_size = new_size;
|
|
||||||
let ConstellationChan(ref chan) = self.constellation_chan;
|
|
||||||
chan.send(ResizedWindowMsg(new_size.to_untyped()))
|
|
||||||
} else {
|
|
||||||
debug!("osmain: dropping window resize since size is still {:u}x{:u}", width, height);
|
|
||||||
}
|
|
||||||
// A size change could also mean a resolution change.
|
// A size change could also mean a resolution change.
|
||||||
let new_hidpi_factor = self.window.hidpi_factor();
|
let new_hidpi_factor = self.window.hidpi_factor();
|
||||||
if self.hidpi_factor != new_hidpi_factor {
|
if self.hidpi_factor != new_hidpi_factor {
|
||||||
self.hidpi_factor = new_hidpi_factor;
|
self.hidpi_factor = new_hidpi_factor;
|
||||||
self.update_zoom_transform();
|
self.update_zoom_transform();
|
||||||
}
|
}
|
||||||
|
if self.window_size != new_size {
|
||||||
|
debug!("osmain: window resized to {:?}", new_size);
|
||||||
|
self.window_size = new_size;
|
||||||
|
self.send_window_size();
|
||||||
|
} else {
|
||||||
|
debug!("osmain: dropping window resize since size is still {:?}", new_size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_load_url_window_event(&mut self, url_string: String) {
|
fn on_load_url_window_event(&mut self, url_string: String) {
|
||||||
|
@ -717,7 +713,7 @@ impl IOCompositor {
|
||||||
profile(time::CompositingCategory, self.profiler_chan.clone(), || {
|
profile(time::CompositingCategory, self.profiler_chan.clone(), || {
|
||||||
debug!("compositor: compositing");
|
debug!("compositor: compositing");
|
||||||
// Adjust the layer dimensions as necessary to correspond to the size of the window.
|
// Adjust the layer dimensions as necessary to correspond to the size of the window.
|
||||||
self.scene.size = self.window.size().to_untyped();
|
self.scene.size = self.window_size.as_f32().to_untyped();
|
||||||
// Render the scene.
|
// Render the scene.
|
||||||
match self.compositor_layer {
|
match self.compositor_layer {
|
||||||
Some(ref mut layer) => {
|
Some(ref mut layer) => {
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use compositing::*;
|
use compositing::*;
|
||||||
|
|
||||||
use geom::size::Size2D;
|
use geom::size::TypedSize2D;
|
||||||
use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, ResizedWindowMsg};
|
use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, ResizedWindowMsg};
|
||||||
use servo_util::time::ProfilerChan;
|
use servo_util::time::ProfilerChan;
|
||||||
use servo_util::time;
|
use servo_util::time;
|
||||||
|
@ -33,7 +33,7 @@ impl NullCompositor {
|
||||||
// Tell the constellation about the initial fake size.
|
// Tell the constellation about the initial fake size.
|
||||||
{
|
{
|
||||||
let ConstellationChan(ref chan) = constellation_chan;
|
let ConstellationChan(ref chan) = constellation_chan;
|
||||||
chan.send(ResizedWindowMsg(Size2D(640u, 480u)));
|
chan.send(ResizedWindowMsg(TypedSize2D(640_f32, 480_f32)));
|
||||||
}
|
}
|
||||||
compositor.handle_message(constellation_chan);
|
compositor.handle_message(constellation_chan);
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
use compositing::{CompositorChan, LoadComplete, SetIds, SetLayerClipRect, ShutdownComplete};
|
use compositing::{CompositorChan, LoadComplete, SetIds, SetLayerClipRect, ShutdownComplete};
|
||||||
|
|
||||||
use collections::hashmap::{HashMap, HashSet};
|
use collections::hashmap::{HashMap, HashSet};
|
||||||
use geom::rect::Rect;
|
use geom::rect::{Rect, TypedRect};
|
||||||
use geom::size::Size2D;
|
use geom::size::TypedSize2D;
|
||||||
use gfx::render_task;
|
use gfx::render_task;
|
||||||
use libc;
|
use libc;
|
||||||
use pipeline::{Pipeline, CompositionPipeline};
|
use pipeline::{Pipeline, CompositionPipeline};
|
||||||
|
@ -24,6 +24,7 @@ use servo_msg::constellation_msg;
|
||||||
use servo_net::image_cache_task::{ImageCacheTask, ImageCacheTaskClient};
|
use servo_net::image_cache_task::{ImageCacheTask, ImageCacheTaskClient};
|
||||||
use servo_net::resource_task::ResourceTask;
|
use servo_net::resource_task::ResourceTask;
|
||||||
use servo_net::resource_task;
|
use servo_net::resource_task;
|
||||||
|
use servo_util::geometry::PagePx;
|
||||||
use servo_util::opts::Opts;
|
use servo_util::opts::Opts;
|
||||||
use servo_util::time::ProfilerChan;
|
use servo_util::time::ProfilerChan;
|
||||||
use servo_util::url::parse_url;
|
use servo_util::url::parse_url;
|
||||||
|
@ -45,9 +46,9 @@ pub struct Constellation {
|
||||||
navigation_context: NavigationContext,
|
navigation_context: NavigationContext,
|
||||||
next_pipeline_id: PipelineId,
|
next_pipeline_id: PipelineId,
|
||||||
pending_frames: Vec<FrameChange>,
|
pending_frames: Vec<FrameChange>,
|
||||||
pending_sizes: HashMap<(PipelineId, SubpageId), Rect<f32>>,
|
pending_sizes: HashMap<(PipelineId, SubpageId), TypedRect<PagePx, f32>>,
|
||||||
pub profiler_chan: ProfilerChan,
|
pub profiler_chan: ProfilerChan,
|
||||||
pub window_size: Size2D<uint>,
|
pub window_size: TypedSize2D<PagePx, f32>,
|
||||||
pub opts: Opts,
|
pub opts: Opts,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +64,7 @@ struct ChildFrameTree {
|
||||||
frame_tree: Rc<FrameTree>,
|
frame_tree: Rc<FrameTree>,
|
||||||
/// Clipping rect representing the size and position, in page coordinates, of the visible
|
/// Clipping rect representing the size and position, in page coordinates, of the visible
|
||||||
/// region of the child frame relative to the parent.
|
/// region of the child frame relative to the parent.
|
||||||
pub rect: Option<Rect<f32>>,
|
pub rect: Option<TypedRect<PagePx, f32>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SendableFrameTree {
|
pub struct SendableFrameTree {
|
||||||
|
@ -73,7 +74,7 @@ pub struct SendableFrameTree {
|
||||||
|
|
||||||
pub struct SendableChildFrameTree {
|
pub struct SendableChildFrameTree {
|
||||||
pub frame_tree: SendableFrameTree,
|
pub frame_tree: SendableFrameTree,
|
||||||
pub rect: Option<Rect<f32>>,
|
pub rect: Option<TypedRect<PagePx, f32>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ReplaceResult {
|
enum ReplaceResult {
|
||||||
|
@ -260,7 +261,7 @@ impl Constellation {
|
||||||
pending_frames: vec!(),
|
pending_frames: vec!(),
|
||||||
pending_sizes: HashMap::new(),
|
pending_sizes: HashMap::new(),
|
||||||
profiler_chan: profiler_chan,
|
profiler_chan: profiler_chan,
|
||||||
window_size: Size2D(800u, 600u),
|
window_size: TypedSize2D(800_f32, 600_f32),
|
||||||
opts: opts_clone,
|
opts: opts_clone,
|
||||||
};
|
};
|
||||||
constellation.run();
|
constellation.run();
|
||||||
|
@ -320,7 +321,7 @@ impl Constellation {
|
||||||
// all frame trees in the navigation context containing the subframe.
|
// all frame trees in the navigation context containing the subframe.
|
||||||
FrameRectMsg(pipeline_id, subpage_id, rect) => {
|
FrameRectMsg(pipeline_id, subpage_id, rect) => {
|
||||||
debug!("constellation got frame rect message");
|
debug!("constellation got frame rect message");
|
||||||
self.handle_frame_rect_msg(pipeline_id, subpage_id, rect);
|
self.handle_frame_rect_msg(pipeline_id, subpage_id, Rect::from_untyped(&rect));
|
||||||
}
|
}
|
||||||
LoadIframeUrlMsg(url, source_pipeline_id, subpage_id, sandbox) => {
|
LoadIframeUrlMsg(url, source_pipeline_id, subpage_id, sandbox) => {
|
||||||
debug!("constellation got iframe URL load message");
|
debug!("constellation got iframe URL load message");
|
||||||
|
@ -464,8 +465,9 @@ impl Constellation {
|
||||||
self.pipelines.insert(pipeline_wrapped.id, pipeline_wrapped);
|
self.pipelines.insert(pipeline_wrapped.id, pipeline_wrapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_frame_rect_msg(&mut self, pipeline_id: PipelineId, subpage_id: SubpageId, rect: Rect<f32>) {
|
fn handle_frame_rect_msg(&mut self, pipeline_id: PipelineId, subpage_id: SubpageId,
|
||||||
debug!("Received frame rect {} from {:?}, {:?}", rect, pipeline_id, subpage_id);
|
rect: TypedRect<PagePx, f32>) {
|
||||||
|
debug!("Received frame rect {:?} from {:?}, {:?}", rect, pipeline_id, subpage_id);
|
||||||
let mut already_sent = HashSet::new();
|
let mut already_sent = HashSet::new();
|
||||||
|
|
||||||
// Returns true if a child frame tree's subpage id matches the given subpage id
|
// Returns true if a child frame tree's subpage id matches the given subpage id
|
||||||
|
@ -483,20 +485,16 @@ impl Constellation {
|
||||||
// if it hasn't been already. Optionally inform the compositor if
|
// if it hasn't been already. Optionally inform the compositor if
|
||||||
// resize happens immediately.
|
// resize happens immediately.
|
||||||
let update_child_rect = |child_frame_tree: &mut ChildFrameTree, is_active: bool| {
|
let update_child_rect = |child_frame_tree: &mut ChildFrameTree, is_active: bool| {
|
||||||
child_frame_tree.rect = Some(rect.clone());
|
child_frame_tree.rect = Some(rect);
|
||||||
// NOTE: work around borrowchk issues
|
// NOTE: work around borrowchk issues
|
||||||
let pipeline = &child_frame_tree.frame_tree.pipeline;
|
let pipeline = &child_frame_tree.frame_tree.pipeline;
|
||||||
if !already_sent.contains(&pipeline.id) {
|
if !already_sent.contains(&pipeline.id) {
|
||||||
let Size2D { width, height } = rect.size;
|
|
||||||
if is_active {
|
if is_active {
|
||||||
let ScriptChan(ref script_chan) = pipeline.script_chan;
|
let ScriptChan(ref script_chan) = pipeline.script_chan;
|
||||||
script_chan.send(ResizeMsg(pipeline.id, Size2D {
|
script_chan.send(ResizeMsg(pipeline.id, rect.size));
|
||||||
width: width as uint,
|
|
||||||
height: height as uint
|
|
||||||
}));
|
|
||||||
self.compositor_chan.send(SetLayerClipRect(pipeline.id,
|
self.compositor_chan.send(SetLayerClipRect(pipeline.id,
|
||||||
LayerId::null(),
|
LayerId::null(),
|
||||||
rect));
|
rect.to_untyped()));
|
||||||
} else {
|
} else {
|
||||||
already_sent.insert(pipeline.id);
|
already_sent.insert(pipeline.id);
|
||||||
}
|
}
|
||||||
|
@ -790,7 +788,7 @@ impl Constellation {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Called when the window is resized.
|
/// Called when the window is resized.
|
||||||
fn handle_resized_window_msg(&mut self, new_size: Size2D<uint>) {
|
fn handle_resized_window_msg(&mut self, new_size: TypedSize2D<PagePx, f32>) {
|
||||||
let mut already_seen = HashSet::new();
|
let mut already_seen = HashSet::new();
|
||||||
for frame_tree in self.current_frame().iter() {
|
for frame_tree in self.current_frame().iter() {
|
||||||
debug!("constellation sending resize message to active frame");
|
debug!("constellation sending resize message to active frame");
|
||||||
|
|
|
@ -581,8 +581,8 @@ impl LayoutTask {
|
||||||
_ => false
|
_ => false
|
||||||
};
|
};
|
||||||
|
|
||||||
let current_screen_size = Size2D(Au::from_px(data.window_size.width as int),
|
let current_screen_size = Size2D(Au::from_page_px(data.window_size.width),
|
||||||
Au::from_px(data.window_size.height as int));
|
Au::from_page_px(data.window_size.height));
|
||||||
if self.screen_size != current_screen_size {
|
if self.screen_size != current_screen_size {
|
||||||
all_style_damage = true
|
all_style_damage = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
use compositing::CompositorChan;
|
use compositing::CompositorChan;
|
||||||
use layout::layout_task::LayoutTask;
|
use layout::layout_task::LayoutTask;
|
||||||
|
|
||||||
use geom::size::Size2D;
|
use geom::size::TypedSize2D;
|
||||||
use gfx::render_task::{PaintPermissionGranted, PaintPermissionRevoked};
|
use gfx::render_task::{PaintPermissionGranted, PaintPermissionRevoked};
|
||||||
use gfx::render_task::{RenderChan, RenderTask};
|
use gfx::render_task::{RenderChan, RenderTask};
|
||||||
use script::layout_interface::LayoutChan;
|
use script::layout_interface::LayoutChan;
|
||||||
|
@ -15,6 +15,7 @@ use script::script_task;
|
||||||
use servo_msg::constellation_msg::{ConstellationChan, Failure, PipelineId, SubpageId};
|
use servo_msg::constellation_msg::{ConstellationChan, Failure, PipelineId, SubpageId};
|
||||||
use servo_net::image_cache_task::ImageCacheTask;
|
use servo_net::image_cache_task::ImageCacheTask;
|
||||||
use servo_net::resource_task::ResourceTask;
|
use servo_net::resource_task::ResourceTask;
|
||||||
|
use servo_util::geometry::PagePx;
|
||||||
use servo_util::opts::Opts;
|
use servo_util::opts::Opts;
|
||||||
use servo_util::time::ProfilerChan;
|
use servo_util::time::ProfilerChan;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
@ -112,7 +113,7 @@ impl Pipeline {
|
||||||
image_cache_task: ImageCacheTask,
|
image_cache_task: ImageCacheTask,
|
||||||
resource_task: ResourceTask,
|
resource_task: ResourceTask,
|
||||||
profiler_chan: ProfilerChan,
|
profiler_chan: ProfilerChan,
|
||||||
window_size: Size2D<uint>,
|
window_size: TypedSize2D<PagePx, f32>,
|
||||||
opts: Opts,
|
opts: Opts,
|
||||||
url: Url)
|
url: Url)
|
||||||
-> Pipeline {
|
-> Pipeline {
|
||||||
|
|
|
@ -145,9 +145,15 @@ impl WindowMethods<Application> for Window {
|
||||||
wrapped_window
|
wrapped_window
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the size of the window.
|
/// Returns the size of the window in hardware pixels.
|
||||||
fn size(&self) -> TypedSize2D<DevicePixel, f32> {
|
fn framebuffer_size(&self) -> TypedSize2D<DevicePixel, uint> {
|
||||||
let (width, height) = self.glfw_window.get_framebuffer_size();
|
let (width, height) = self.glfw_window.get_framebuffer_size();
|
||||||
|
TypedSize2D(width as uint, height as uint)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the size of the window in density-independent "px" units.
|
||||||
|
fn size(&self) -> TypedSize2D<ScreenPx, f32> {
|
||||||
|
let (width, height) = self.glfw_window.get_size();
|
||||||
TypedSize2D(width as f32, height as f32)
|
TypedSize2D(width as f32, height as f32)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,9 +202,9 @@ impl WindowMethods<Application> for Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hidpi_factor(&self) -> ScaleFactor<ScreenPx, DevicePixel, f32> {
|
fn hidpi_factor(&self) -> ScaleFactor<ScreenPx, DevicePixel, f32> {
|
||||||
let (backing_size, _) = self.glfw_window.get_framebuffer_size();
|
let backing_size = self.framebuffer_size().width.get();
|
||||||
let (window_size, _) = self.glfw_window.get_size();
|
let window_size = self.size().width.get();
|
||||||
ScaleFactor((backing_size as f32) / (window_size as f32))
|
ScaleFactor((backing_size as f32) / window_size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,7 +217,8 @@ impl Window {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
glfw::FramebufferSizeEvent(width, height) => {
|
glfw::FramebufferSizeEvent(width, height) => {
|
||||||
self.event_queue.borrow_mut().push(ResizeWindowEvent(width as uint, height as uint));
|
self.event_queue.borrow_mut().push(
|
||||||
|
ResizeWindowEvent(TypedSize2D(width as uint, height as uint)));
|
||||||
},
|
},
|
||||||
glfw::RefreshEvent => {
|
glfw::RefreshEvent => {
|
||||||
self.event_queue.borrow_mut().push(RefreshWindowEvent);
|
self.event_queue.borrow_mut().push(RefreshWindowEvent);
|
||||||
|
|
|
@ -144,9 +144,14 @@ impl WindowMethods<Application> for Window {
|
||||||
wrapped_window
|
wrapped_window
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the size of the window.
|
/// Returns the size of the window in hardware pixels.
|
||||||
fn size(&self) -> TypedSize2D<DevicePixel, f32> {
|
fn framebuffer_size(&self) -> TypedSize2D<DevicePixel, uint> {
|
||||||
TypedSize2D(glut::get(WindowWidth) as f32, glut::get(WindowHeight) as f32)
|
TypedSize2D(glut::get(WindowWidth) as uint, glut::get(WindowHeight) as uint)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the size of the window in density-independent "px" units.
|
||||||
|
fn size(&self) -> TypedSize2D<ScreenPx, f32> {
|
||||||
|
self.framebuffer_size().as_f32() / self.hidpi_factor()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Presents the window to the screen (perhaps by page flipping).
|
/// Presents the window to the screen (perhaps by page flipping).
|
||||||
|
|
|
@ -32,7 +32,7 @@ pub enum WindowEvent {
|
||||||
/// Sent when part of the window is marked dirty and needs to be redrawn.
|
/// Sent when part of the window is marked dirty and needs to be redrawn.
|
||||||
RefreshWindowEvent,
|
RefreshWindowEvent,
|
||||||
/// Sent when the window is resized.
|
/// Sent when the window is resized.
|
||||||
ResizeWindowEvent(uint, uint),
|
ResizeWindowEvent(TypedSize2D<DevicePixel, uint>),
|
||||||
/// Sent when a new URL is to be loaded.
|
/// Sent when a new URL is to be loaded.
|
||||||
LoadUrlWindowEvent(String),
|
LoadUrlWindowEvent(String),
|
||||||
/// Sent when a mouse hit test is to be performed.
|
/// Sent when a mouse hit test is to be performed.
|
||||||
|
@ -59,8 +59,10 @@ pub trait ApplicationMethods {
|
||||||
pub trait WindowMethods<A> {
|
pub trait WindowMethods<A> {
|
||||||
/// Creates a new window.
|
/// Creates a new window.
|
||||||
fn new(app: &A, is_foreground: bool) -> Rc<Self>;
|
fn new(app: &A, is_foreground: bool) -> Rc<Self>;
|
||||||
/// Returns the size of the window.
|
/// Returns the size of the window in hardware pixels.
|
||||||
fn size(&self) -> TypedSize2D<DevicePixel, f32>;
|
fn framebuffer_size(&self) -> TypedSize2D<DevicePixel, uint>;
|
||||||
|
/// Returns the size of the window in density-independent "px" units.
|
||||||
|
fn size(&self) -> TypedSize2D<ScreenPx, f32>;
|
||||||
/// Presents the window to the screen (perhaps by page flipping).
|
/// Presents the window to the screen (perhaps by page flipping).
|
||||||
fn present(&self);
|
fn present(&self);
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,8 @@
|
||||||
/// coupling between these two components
|
/// coupling between these two components
|
||||||
|
|
||||||
use geom::rect::Rect;
|
use geom::rect::Rect;
|
||||||
use geom::size::Size2D;
|
use geom::size::TypedSize2D;
|
||||||
|
use servo_util::geometry::PagePx;
|
||||||
use std::comm::{channel, Sender, Receiver};
|
use std::comm::{channel, Sender, Receiver};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
|
@ -44,7 +45,7 @@ pub enum Msg {
|
||||||
LoadIframeUrlMsg(Url, PipelineId, SubpageId, IFrameSandboxState),
|
LoadIframeUrlMsg(Url, PipelineId, SubpageId, IFrameSandboxState),
|
||||||
NavigateMsg(NavigationDirection),
|
NavigateMsg(NavigationDirection),
|
||||||
RendererReadyMsg(PipelineId),
|
RendererReadyMsg(PipelineId),
|
||||||
ResizedWindowMsg(Size2D<uint>),
|
ResizedWindowMsg(TypedSize2D<PagePx, f32>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents the two different ways to which a page can be navigated
|
/// Represents the two different ways to which a page can be navigated
|
||||||
|
|
|
@ -11,6 +11,7 @@ extern crate azure;
|
||||||
extern crate geom;
|
extern crate geom;
|
||||||
extern crate layers;
|
extern crate layers;
|
||||||
extern crate serialize;
|
extern crate serialize;
|
||||||
|
extern crate servo_util = "util";
|
||||||
extern crate std;
|
extern crate std;
|
||||||
extern crate url;
|
extern crate url;
|
||||||
|
|
||||||
|
|
|
@ -10,14 +10,16 @@ use dom::bindings::error::Fallible;
|
||||||
use dom::eventtarget::EventTarget;
|
use dom::eventtarget::EventTarget;
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
use servo_util::str::DOMString;
|
use servo_util::str::DOMString;
|
||||||
|
use servo_util::geometry::PagePx;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
|
||||||
use geom::point::Point2D;
|
use geom::point::Point2D;
|
||||||
|
use geom::size::TypedSize2D;
|
||||||
|
|
||||||
use time;
|
use time;
|
||||||
|
|
||||||
pub enum Event_ {
|
pub enum Event_ {
|
||||||
ResizeEvent(uint, uint),
|
ResizeEvent(TypedSize2D<PagePx, f32>),
|
||||||
ReflowEvent,
|
ReflowEvent,
|
||||||
ClickEvent(uint, Point2D<f32>),
|
ClickEvent(uint, Point2D<f32>),
|
||||||
MouseDownEvent(uint, Point2D<f32>),
|
MouseDownEvent(uint, Point2D<f32>),
|
||||||
|
|
|
@ -11,10 +11,10 @@ use dom::node::{Node, LayoutDataRef};
|
||||||
|
|
||||||
use geom::point::Point2D;
|
use geom::point::Point2D;
|
||||||
use geom::rect::Rect;
|
use geom::rect::Rect;
|
||||||
use geom::size::Size2D;
|
use geom::size::TypedSize2D;
|
||||||
use libc::c_void;
|
use libc::c_void;
|
||||||
use script_task::{ScriptChan};
|
use script_task::{ScriptChan};
|
||||||
use servo_util::geometry::Au;
|
use servo_util::geometry::{Au, PagePx};
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::comm::{channel, Receiver, Sender};
|
use std::comm::{channel, Receiver, Sender};
|
||||||
use style::Stylesheet;
|
use style::Stylesheet;
|
||||||
|
@ -137,7 +137,7 @@ pub struct Reflow {
|
||||||
/// The channel through which messages can be sent back to the script task.
|
/// The channel through which messages can be sent back to the script task.
|
||||||
pub script_chan: ScriptChan,
|
pub script_chan: ScriptChan,
|
||||||
/// The current window size.
|
/// The current window size.
|
||||||
pub window_size: Size2D<uint>,
|
pub window_size: TypedSize2D<PagePx, f32>,
|
||||||
/// The channel that we send a notification to.
|
/// The channel that we send a notification to.
|
||||||
pub script_join_chan: Sender<()>,
|
pub script_join_chan: Sender<()>,
|
||||||
/// Unique identifier
|
/// Unique identifier
|
||||||
|
|
|
@ -34,7 +34,7 @@ use layout_interface::UntrustedNodeAddress;
|
||||||
use layout_interface;
|
use layout_interface;
|
||||||
|
|
||||||
use geom::point::Point2D;
|
use geom::point::Point2D;
|
||||||
use geom::size::Size2D;
|
use geom::size::TypedSize2D;
|
||||||
use js::jsapi::JS_CallFunctionValue;
|
use js::jsapi::JS_CallFunctionValue;
|
||||||
use js::jsapi::{JS_SetWrapObjectCallbacks, JS_SetGCZeal, JS_DEFAULT_ZEAL_FREQ, JS_GC};
|
use js::jsapi::{JS_SetWrapObjectCallbacks, JS_SetGCZeal, JS_DEFAULT_ZEAL_FREQ, JS_GC};
|
||||||
use js::jsapi::{JSContext, JSRuntime};
|
use js::jsapi::{JSContext, JSRuntime};
|
||||||
|
@ -49,7 +49,7 @@ use servo_msg::constellation_msg::{PipelineId, SubpageId, Failure, FailureMsg};
|
||||||
use servo_msg::constellation_msg;
|
use servo_msg::constellation_msg;
|
||||||
use servo_net::image_cache_task::ImageCacheTask;
|
use servo_net::image_cache_task::ImageCacheTask;
|
||||||
use servo_net::resource_task::ResourceTask;
|
use servo_net::resource_task::ResourceTask;
|
||||||
use servo_util::geometry::to_frac_px;
|
use servo_util::geometry::{PagePx, to_frac_px};
|
||||||
use servo_util::task::send_on_failure;
|
use servo_util::task::send_on_failure;
|
||||||
use servo_util::namespace::Null;
|
use servo_util::namespace::Null;
|
||||||
use servo_util::str::DOMString;
|
use servo_util::str::DOMString;
|
||||||
|
@ -80,13 +80,13 @@ pub enum ScriptMsg {
|
||||||
/// Sends a DOM event.
|
/// Sends a DOM event.
|
||||||
SendEventMsg(PipelineId, Event_),
|
SendEventMsg(PipelineId, Event_),
|
||||||
/// Window resized. Sends a DOM event eventually, but first we combine events.
|
/// Window resized. Sends a DOM event eventually, but first we combine events.
|
||||||
ResizeMsg(PipelineId, Size2D<uint>),
|
ResizeMsg(PipelineId, TypedSize2D<PagePx, f32>),
|
||||||
/// Fires a JavaScript timeout.
|
/// Fires a JavaScript timeout.
|
||||||
FireTimerMsg(PipelineId, TimerId),
|
FireTimerMsg(PipelineId, TimerId),
|
||||||
/// Notifies script that reflow is finished.
|
/// Notifies script that reflow is finished.
|
||||||
ReflowCompleteMsg(PipelineId, uint),
|
ReflowCompleteMsg(PipelineId, uint),
|
||||||
/// Notifies script that window has been resized but to not take immediate action.
|
/// Notifies script that window has been resized but to not take immediate action.
|
||||||
ResizeInactiveMsg(PipelineId, Size2D<uint>),
|
ResizeInactiveMsg(PipelineId, TypedSize2D<PagePx, f32>),
|
||||||
/// Notifies the script that a pipeline should be closed.
|
/// Notifies the script that a pipeline should be closed.
|
||||||
ExitPipelineMsg(PipelineId),
|
ExitPipelineMsg(PipelineId),
|
||||||
/// Notifies the script that a window associated with a particular pipeline should be closed.
|
/// Notifies the script that a window associated with a particular pipeline should be closed.
|
||||||
|
@ -145,7 +145,7 @@ pub struct Page {
|
||||||
damage: Traceable<RefCell<Option<DocumentDamage>>>,
|
damage: Traceable<RefCell<Option<DocumentDamage>>>,
|
||||||
|
|
||||||
/// The current size of the window, in pixels.
|
/// The current size of the window, in pixels.
|
||||||
window_size: Untraceable<Cell<Size2D<uint>>>,
|
window_size: Untraceable<Cell<TypedSize2D<PagePx, f32>>>,
|
||||||
|
|
||||||
js_info: Traceable<RefCell<Option<JSPageInfo>>>,
|
js_info: Traceable<RefCell<Option<JSPageInfo>>>,
|
||||||
|
|
||||||
|
@ -158,7 +158,7 @@ pub struct Page {
|
||||||
next_subpage_id: Untraceable<Cell<SubpageId>>,
|
next_subpage_id: Untraceable<Cell<SubpageId>>,
|
||||||
|
|
||||||
/// Pending resize event, if any.
|
/// Pending resize event, if any.
|
||||||
resize_event: Untraceable<Cell<Option<Size2D<uint>>>>,
|
resize_event: Untraceable<Cell<Option<TypedSize2D<PagePx, f32>>>>,
|
||||||
|
|
||||||
/// Pending scroll to fragment event, if any
|
/// Pending scroll to fragment event, if any
|
||||||
fragment_node: Cell<Option<JS<Element>>>,
|
fragment_node: Cell<Option<JS<Element>>>,
|
||||||
|
@ -201,7 +201,7 @@ impl IterablePage for Rc<Page> {
|
||||||
impl Page {
|
impl Page {
|
||||||
fn new(id: PipelineId, subpage_id: Option<SubpageId>,
|
fn new(id: PipelineId, subpage_id: Option<SubpageId>,
|
||||||
layout_chan: LayoutChan,
|
layout_chan: LayoutChan,
|
||||||
window_size: Size2D<uint>, resource_task: ResourceTask,
|
window_size: TypedSize2D<PagePx, f32>, resource_task: ResourceTask,
|
||||||
constellation_chan: ConstellationChan,
|
constellation_chan: ConstellationChan,
|
||||||
js_context: Rc<Cx>) -> Page {
|
js_context: Rc<Cx>) -> Page {
|
||||||
let js_info = JSPageInfo {
|
let js_info = JSPageInfo {
|
||||||
|
@ -609,7 +609,7 @@ impl ScriptTask {
|
||||||
constellation_chan: ConstellationChan,
|
constellation_chan: ConstellationChan,
|
||||||
resource_task: ResourceTask,
|
resource_task: ResourceTask,
|
||||||
img_cache_task: ImageCacheTask,
|
img_cache_task: ImageCacheTask,
|
||||||
window_size: Size2D<uint>)
|
window_size: TypedSize2D<PagePx, f32>)
|
||||||
-> Rc<ScriptTask> {
|
-> Rc<ScriptTask> {
|
||||||
let (js_runtime, js_context) = ScriptTask::new_rt_and_cx();
|
let (js_runtime, js_context) = ScriptTask::new_rt_and_cx();
|
||||||
let page = Page::new(id, None, layout_chan, window_size,
|
let page = Page::new(id, None, layout_chan, window_size,
|
||||||
|
@ -690,7 +690,7 @@ impl ScriptTask {
|
||||||
failure_msg: Failure,
|
failure_msg: Failure,
|
||||||
resource_task: ResourceTask,
|
resource_task: ResourceTask,
|
||||||
image_cache_task: ImageCacheTask,
|
image_cache_task: ImageCacheTask,
|
||||||
window_size: Size2D<uint>) {
|
window_size: TypedSize2D<PagePx, f32>) {
|
||||||
let mut builder = TaskBuilder::new().named("ScriptTask");
|
let mut builder = TaskBuilder::new().named("ScriptTask");
|
||||||
let ConstellationChan(const_chan) = constellation_chan.clone();
|
let ConstellationChan(const_chan) = constellation_chan.clone();
|
||||||
send_on_failure(&mut builder, FailureMsg(failure_msg), const_chan);
|
send_on_failure(&mut builder, FailureMsg(failure_msg), const_chan);
|
||||||
|
@ -737,8 +737,8 @@ impl ScriptTask {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (id, Size2D { width, height }) in resizes.move_iter() {
|
for (id, size) in resizes.move_iter() {
|
||||||
self.handle_event(id, ResizeEvent(width, height));
|
self.handle_event(id, ResizeEvent(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store new resizes, and gather all other events.
|
// Store new resizes, and gather all other events.
|
||||||
|
@ -868,7 +868,7 @@ impl ScriptTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Window was resized, but this script was not active, so don't reflow yet
|
/// Window was resized, but this script was not active, so don't reflow yet
|
||||||
fn handle_resize_inactive_msg(&self, id: PipelineId, new_size: Size2D<uint>) {
|
fn handle_resize_inactive_msg(&self, id: PipelineId, new_size: TypedSize2D<PagePx, f32>) {
|
||||||
let mut page = self.page.borrow_mut();
|
let mut page = self.page.borrow_mut();
|
||||||
let page = page.find(id).expect("Received resize message for PipelineId not associated
|
let page = page.find(id).expect("Received resize message for PipelineId not associated
|
||||||
with a page in the page tree. This is a bug.");
|
with a page in the page tree. This is a bug.");
|
||||||
|
@ -1063,12 +1063,12 @@ impl ScriptTask {
|
||||||
/// TODO: Actually perform DOM event dispatch.
|
/// TODO: Actually perform DOM event dispatch.
|
||||||
fn handle_event(&self, pipeline_id: PipelineId, event: Event_) {
|
fn handle_event(&self, pipeline_id: PipelineId, event: Event_) {
|
||||||
match event {
|
match event {
|
||||||
ResizeEvent(new_width, new_height) => {
|
ResizeEvent(new_size) => {
|
||||||
debug!("script got resize event: {:u}, {:u}", new_width, new_height);
|
debug!("script got resize event: {:?}", new_size);
|
||||||
|
|
||||||
let window = {
|
let window = {
|
||||||
let page = get_page(&*self.page.borrow(), pipeline_id);
|
let page = get_page(&*self.page.borrow(), pipeline_id);
|
||||||
page.window_size.deref().set(Size2D(new_width, new_height));
|
page.window_size.deref().set(new_size);
|
||||||
|
|
||||||
let frame = page.frame();
|
let frame = page.frame();
|
||||||
if frame.is_some() {
|
if frame.is_some() {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use geom::length::Length;
|
||||||
use geom::point::Point2D;
|
use geom::point::Point2D;
|
||||||
use geom::rect::Rect;
|
use geom::rect::Rect;
|
||||||
use geom::size::Size2D;
|
use geom::size::Size2D;
|
||||||
|
@ -178,6 +179,11 @@ impl Au {
|
||||||
NumCast::from(px * 60).unwrap()
|
NumCast::from(px * 60).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn from_page_px(px: Length<PagePx, f32>) -> Au {
|
||||||
|
NumCast::from(px.get() * 60f32).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_nearest_px(&self) -> int {
|
pub fn to_nearest_px(&self) -> int {
|
||||||
let Au(s) = *self;
|
let Au(s) = *self;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue