Multiply input coords by window scale_factor so Retina clicks land
GPUI delivers logical (CSS) pixels but Servo expects device pixels. On a 2x Retina display the page rendered at half resolution and every click landed in roughly the upper-left quadrant of the page — the second independent root cause that surfaces immediately after T1's show()/focus() lets input reach Servo at all. Single conversion boundary inside web_surface_geometry.rs: viewport_dimension, scroll_dimension, and click_coordinate each multiply once by window.scale_factor() before truncating to integer device pixels. positive_scale_or_one() guards against a zero/negative/ NaN scale_factor reaching the arithmetic — falling back to 1.0 keeps coordinates valid even if the platform reports nonsense (system boundary validation per CLAUDE.md, not internal trust). scale_factor is plumbed through controller and view layer, sourced from window.scale_factor() at every record_* boundary so all four inputs (click, scroll, hover, viewport) stay in sync. Existing tests pin the 1.0 path; new retina_scale_factor_doubles_every_input_coordinate locks the 2.0 path against a future regression. cargo test ely_app --bin ely_app: 104 passed (was 103 + new test).
This commit is contained in:
@@ -102,8 +102,9 @@ impl WebSurfaceStore {
|
||||
tab_id: &TabId,
|
||||
requested_url: &str,
|
||||
delta: Point<Pixels>,
|
||||
scale_factor: f32,
|
||||
) -> bool {
|
||||
let Some(delta) = WebSurfaceScrollDelta::from_point(delta) else {
|
||||
let Some(delta) = WebSurfaceScrollDelta::from_point(delta, scale_factor) else {
|
||||
return false;
|
||||
};
|
||||
|
||||
@@ -130,8 +131,13 @@ impl WebSurfaceStore {
|
||||
true
|
||||
}
|
||||
|
||||
pub(super) fn record_viewport_size(&mut self, tab_id: &TabId, bounds: Bounds<Pixels>) -> bool {
|
||||
let Some(size) = WebSurfaceSize::from_bounds(bounds) else {
|
||||
pub(super) fn record_viewport_size(
|
||||
&mut self,
|
||||
tab_id: &TabId,
|
||||
bounds: Bounds<Pixels>,
|
||||
scale_factor: f32,
|
||||
) -> bool {
|
||||
let Some(size) = WebSurfaceSize::from_bounds(bounds, scale_factor) else {
|
||||
return false;
|
||||
};
|
||||
let surface = self.surface_mut(tab_id);
|
||||
@@ -162,13 +168,15 @@ impl WebSurfaceStore {
|
||||
&mut self,
|
||||
tab_id: &TabId,
|
||||
position: Point<Pixels>,
|
||||
scale_factor: f32,
|
||||
) -> bool {
|
||||
let surface = self.surfaces.get_mut(tab_id).filter(|surface| surface.viewport_bounds.is_some());
|
||||
let Some(surface) = surface else {
|
||||
return false;
|
||||
};
|
||||
let bounds = surface.viewport_bounds.expect("viewport_bounds checked above");
|
||||
let Some(point) = WebSurfaceClickPoint::from_window_position(bounds, position) else {
|
||||
let Some(point) = WebSurfaceClickPoint::from_window_position(bounds, position, scale_factor)
|
||||
else {
|
||||
return false;
|
||||
};
|
||||
surface.hover_point = Some(point);
|
||||
@@ -180,13 +188,15 @@ impl WebSurfaceStore {
|
||||
tab_id: &TabId,
|
||||
requested_url: &str,
|
||||
position: Point<Pixels>,
|
||||
scale_factor: f32,
|
||||
) -> bool {
|
||||
let Some(bounds) =
|
||||
self.surfaces.get(tab_id).and_then(|surface| surface.viewport_bounds)
|
||||
else {
|
||||
return false;
|
||||
};
|
||||
let Some(point) = WebSurfaceClickPoint::from_window_position(bounds, position) else {
|
||||
let Some(point) = WebSurfaceClickPoint::from_window_position(bounds, position, scale_factor)
|
||||
else {
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user