Auto merge of #11314 - metajack:window-hi-dpi, r=mbrubeck

Make Servo DPI aware on Windows

Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data:
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy --faster` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).

Either:
- [ ] There are tests for these changes OR
- [x] These changes do not require tests because testing would be overly difficult

Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process.

This implements system level DPI awareness for Windows. It has three
parts:

1. Add a application manifest which is copied alongside servo.exe during
build that declares our DPI awareness level. This is needed otherwise
DPI queries will return 96dpi and our application will be upscaled on
high DPI displays.

2. Rename hidpi_factor to avoid confusion with Glutin's hidpi_factor
which does something else.

3. Correctly convert windows sizes on window creation for
Windows. Unlike OS X, Windows uses device pixels for window creation.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/11314)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-05-20 22:41:07 -07:00
commit 63bbc13fff
12 changed files with 111 additions and 46 deletions

3
ports/cef/Cargo.lock generated
View file

@ -760,6 +760,7 @@ dependencies = [
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"compositing 0.0.1",
"euclid 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.2.5 (git+https://github.com/servo/rust-layers)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -770,7 +771,9 @@ dependencies = [
"servo-glutin 0.4.22 (registry+https://github.com/rust-lang/crates.io-index)",
"style_traits 0.0.1",
"url 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"x11 2.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]

View file

@ -252,7 +252,7 @@ impl WindowMethods for Window {
}
}
fn hidpi_factor(&self) -> ScaleFactor<ScreenPx,DevicePixel,f32> {
fn scale_factor(&self) -> ScaleFactor<ScreenPx,DevicePixel,f32> {
if cfg!(target_os="macos") {
let browser = self.cef_browser.borrow();
match *browser {

View file

@ -58,7 +58,7 @@ dependencies = [
"dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -114,7 +114,7 @@ name = "dbghelp-sys"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -271,7 +271,7 @@ name = "kernel32-sys"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -517,7 +517,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -606,12 +606,12 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi"
version = "0.2.6"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]

View file

@ -27,3 +27,8 @@ x11 = "2.0.0"
[target.'cfg(target_os = "android")'.dependencies]
servo-egl = "0.2"
[target.'cfg(target_os = "windows")'.dependencies]
winapi = "0.2"
user32-sys = "0.2"
gdi32-sys = "0.2"

View file

@ -22,9 +22,11 @@ extern crate style_traits;
extern crate url;
extern crate util;
#[cfg(target_os = "linux")] extern crate x11;
#[cfg(target_os = "windows")] extern crate winapi;
#[cfg(target_os = "windows")] extern crate user32;
#[cfg(target_os = "windows")] extern crate gdi32;
use compositing::windowing::WindowEvent;
use euclid::scale_factor::ScaleFactor;
use std::rc::Rc;
use util::opts;
use window::Window;
@ -41,10 +43,7 @@ pub fn create_window(parent: Option<WindowID>) -> Rc<Window> {
// Read command-line options.
let opts = opts::get();
let foreground = opts.output_file.is_none() && !opts.headless;
let scale_factor = ScaleFactor::new(opts.device_pixels_per_px.unwrap_or(1.0));
let size_f32 = opts.initial_window_size.as_f32() * scale_factor;
let size_u32 = size_f32.as_uint().cast().expect("Window size should fit in a u32.");
// Open a window.
Window::new(foreground, size_u32, parent)
Window::new(foreground, opts.initial_window_size, parent)
}

View file

@ -11,6 +11,7 @@ use compositing::windowing::{WindowEvent, WindowMethods};
use euclid::scale_factor::ScaleFactor;
use euclid::size::TypedSize2D;
use euclid::{Size2D, Point2D};
#[cfg(target_os = "windows")] use gdi32;
use gleam::gl;
use glutin;
#[cfg(target_os = "macos")]
@ -30,12 +31,14 @@ use std::rc::Rc;
use std::sync::mpsc::{channel, Sender};
use style_traits::cursor::Cursor;
use url::Url;
#[cfg(target_os = "windows")] use user32;
use util::geometry::ScreenPx;
use util::opts;
#[cfg(not(target_os = "android"))]
use util::opts::RenderApi;
use util::prefs;
use util::resource_files;
#[cfg(target_os = "windows")] use winapi;
static mut g_nested_event_loop_listener: Option<*mut (NestedEventLoopListener + 'static)> = None;
@ -98,12 +101,28 @@ pub struct Window {
current_url: RefCell<Option<Url>>,
}
#[cfg(not(target_os = "windows"))]
fn window_creation_scale_factor() -> ScaleFactor<ScreenPx, DevicePixel, f32> {
ScaleFactor::new(1.0)
}
#[cfg(target_os = "windows")]
fn window_creation_scale_factor() -> ScaleFactor<ScreenPx, DevicePixel, f32> {
let hdc = unsafe { user32::GetDC(::std::ptr::null_mut()) };
let ppi = unsafe { gdi32::GetDeviceCaps(hdc, winapi::wingdi::LOGPIXELSY) };
ScaleFactor::new(ppi as f32 / 96.0)
}
impl Window {
pub fn new(is_foreground: bool,
window_size: TypedSize2D<DevicePixel, u32>,
window_size: TypedSize2D<ScreenPx, u32>,
parent: Option<glutin::WindowID>) -> Rc<Window> {
let width = window_size.to_untyped().width;
let height = window_size.to_untyped().height;
let win_size: TypedSize2D<DevicePixel, u32> =
(window_size.as_f32() * window_creation_scale_factor())
.as_uint().cast().expect("Window size should fit in u32");
let width = win_size.to_untyped().width;
let height = win_size.to_untyped().height;
// If there's no chrome, start off with the window invisible. It will be set to visible in
// `load_end()`. This avoids an ugly flash of unstyled content (especially important since
@ -644,10 +663,18 @@ impl WindowMethods for Window {
box receiver as Box<CompositorReceiver>)
}
fn hidpi_factor(&self) -> ScaleFactor<ScreenPx, DevicePixel, f32> {
#[cfg(not(target_os = "windows"))]
fn scale_factor(&self) -> ScaleFactor<ScreenPx, DevicePixel, f32> {
ScaleFactor::new(self.window.hidpi_factor())
}
#[cfg(target_os = "windows")]
fn scale_factor(&self) -> ScaleFactor<ScreenPx, DevicePixel, f32> {
let hdc = unsafe { user32::GetDC(::std::ptr::null_mut()) };
let ppi = unsafe { gdi32::GetDeviceCaps(hdc, winapi::wingdi::LOGPIXELSY) };
ScaleFactor::new(ppi as f32 / 96.0)
}
fn set_page_title(&self, title: Option<String>) {
let fallback_title: String = if let Some(ref current_url) = *self.current_url.borrow() {
current_url.to_string()