T13: push display scale factor into Servo's hidpi so Retina pages lay out at logical CSS dimensions
This commit is contained in:
@@ -81,6 +81,7 @@ impl ServoLiveClient {
|
||||
width: request.width,
|
||||
height: request.height,
|
||||
page_zoom_percent: request.page_zoom_percent,
|
||||
device_pixel_ratio: request.device_pixel_ratio,
|
||||
scroll_delta_x: request.scroll_delta_x,
|
||||
scroll_delta_y: request.scroll_delta_y,
|
||||
click_x: request.click_x,
|
||||
@@ -212,6 +213,11 @@ pub(crate) struct ServoLiveEnsureRequest {
|
||||
pub(crate) width: u32,
|
||||
pub(crate) height: u32,
|
||||
pub(crate) page_zoom_percent: u16,
|
||||
/// Display scale factor (1.0 standard, 2.0 Retina). Servo's
|
||||
/// WebView lays out CSS pixels = device pixels / hidpi factor;
|
||||
/// without this, a Retina viewport gets desktop-CSS-pixel layout
|
||||
/// and every visible element renders at half its expected size.
|
||||
pub(crate) device_pixel_ratio: f32,
|
||||
pub(crate) scroll_delta_x: i32,
|
||||
pub(crate) scroll_delta_y: i32,
|
||||
pub(crate) click_x: Option<u32>,
|
||||
@@ -401,6 +407,7 @@ enum LiveRequest {
|
||||
width: u32,
|
||||
height: u32,
|
||||
page_zoom_percent: u16,
|
||||
device_pixel_ratio: f32,
|
||||
scroll_delta_x: i32,
|
||||
scroll_delta_y: i32,
|
||||
click_x: Option<u32>,
|
||||
|
||||
@@ -4,6 +4,12 @@ use gpui::{Bounds, Pixels, Point};
|
||||
pub(super) struct WebSurfaceSize {
|
||||
pub(super) width: u32,
|
||||
pub(super) height: u32,
|
||||
/// Encoded as percent × 1 (e.g. 100 = 1.0 DPR, 200 = 2.0 DPR on
|
||||
/// Retina). u16 instead of f32 so the struct keeps `Eq` —
|
||||
/// `WebSurfaceSession::started_loading` compares sizes by value
|
||||
/// and a float wouldn't compose with that. Convert to/from f32
|
||||
/// at the wire boundary via `device_pixel_ratio_f32`.
|
||||
pub(super) device_pixel_ratio_percent: u16,
|
||||
}
|
||||
|
||||
impl WebSurfaceSize {
|
||||
@@ -11,8 +17,25 @@ impl WebSurfaceSize {
|
||||
Some(Self {
|
||||
width: viewport_dimension(bounds.size.width, scale_factor)?,
|
||||
height: viewport_dimension(bounds.size.height, scale_factor)?,
|
||||
device_pixel_ratio_percent: encode_scale_factor(scale_factor),
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn device_pixel_ratio_f32(&self) -> f32 {
|
||||
f32::from(self.device_pixel_ratio_percent) / 100.0
|
||||
}
|
||||
}
|
||||
|
||||
/// Round `scale_factor` to the nearest whole percent and clamp into a
|
||||
/// sane range. macOS reports 1.0 / 2.0 typically, fractional values
|
||||
/// (1.25 / 1.5 / 1.75) show up on Windows / mixed-DPI setups. The
|
||||
/// clamp guards against `inf`/`nan` from a misbehaving platform.
|
||||
fn encode_scale_factor(scale_factor: f32) -> u16 {
|
||||
if !scale_factor.is_finite() || scale_factor <= 0.0 {
|
||||
return 100;
|
||||
}
|
||||
let scaled = (scale_factor * 100.0).round();
|
||||
scaled.clamp(50.0, 500.0) as u16
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
|
||||
@@ -57,6 +57,7 @@ impl WebSurfaceRuntime {
|
||||
width: size.width,
|
||||
height: size.height,
|
||||
page_zoom_percent: zoom_percent,
|
||||
device_pixel_ratio: size.device_pixel_ratio_f32(),
|
||||
scroll_delta_x: input.scroll_delta.map_or(0, |delta| delta.x()),
|
||||
scroll_delta_y: input.scroll_delta.map_or(0, |delta| delta.y()),
|
||||
click_x: input.click_point.map(|point| point.x()),
|
||||
|
||||
Reference in New Issue
Block a user