Fix issues where screen and window sizes contained Pixels, but were declared as DevicePixels (#12991)

On most platforms, things were working correctly, but had the wrong
type. On X11, there were some problems with window and display size
calculations.

Release Notes:

- Fixed issues with window positioning on X11

---------

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Co-authored-by: Mikayla <mikayla@zed.dev>
This commit is contained in:
Max Brunsfeld
2024-06-13 10:48:37 -07:00
committed by GitHub
co-authored by Conrad Irwin Mikayla
parent 22dc88ed3d
commit da281d6d8f
25 changed files with 331 additions and 367 deletions
+18 -18
View File
@@ -8,13 +8,13 @@ use windows::{
Win32::{Foundation::*, Graphics::Gdi::*},
};
use crate::{Bounds, DevicePixels, DisplayId, PlatformDisplay, Point, Size};
use crate::{px, Bounds, DisplayId, Pixels, PlatformDisplay, Point, Size};
#[derive(Debug, Clone, Copy)]
pub(crate) struct WindowsDisplay {
pub handle: HMONITOR,
pub display_id: DisplayId,
bounds: Bounds<DevicePixels>,
bounds: Bounds<Pixels>,
uuid: Uuid,
}
@@ -34,12 +34,12 @@ impl WindowsDisplay {
display_id,
bounds: Bounds {
origin: Point {
x: DevicePixels(size.left),
y: DevicePixels(size.top),
x: px(size.left as f32),
y: px(size.top as f32),
},
size: Size {
width: DevicePixels(size.right - size.left),
height: DevicePixels(size.bottom - size.top),
width: px((size.right - size.left) as f32),
height: px((size.bottom - size.top) as f32),
},
},
uuid,
@@ -60,12 +60,12 @@ impl WindowsDisplay {
display_id: DisplayId(display_id as _),
bounds: Bounds {
origin: Point {
x: DevicePixels(size.left as i32),
y: DevicePixels(size.top as i32),
x: px(size.left as f32),
y: px(size.top as f32),
},
size: Size {
width: DevicePixels((size.right - size.left) as i32),
height: DevicePixels((size.bottom - size.top) as i32),
width: px((size.right - size.left) as f32),
height: px((size.bottom - size.top) as f32),
},
},
uuid,
@@ -82,12 +82,12 @@ impl WindowsDisplay {
display_id,
bounds: Bounds {
origin: Point {
x: DevicePixels(size.left as i32),
y: DevicePixels(size.top as i32),
x: px(size.left as f32),
y: px(size.top as f32),
},
size: Size {
width: DevicePixels((size.right - size.left) as i32),
height: DevicePixels((size.bottom - size.top) as i32),
width: px((size.right - size.left) as f32),
height: px((size.bottom - size.top) as f32),
},
},
uuid,
@@ -109,11 +109,11 @@ impl WindowsDisplay {
}
/// Check if the center point of given bounds is inside this monitor
pub fn check_given_bounds(&self, bounds: Bounds<DevicePixels>) -> bool {
pub fn check_given_bounds(&self, bounds: Bounds<Pixels>) -> bool {
let center = bounds.center();
let center = POINT {
x: center.x.0,
y: center.y.0,
x: center.x.0 as i32,
y: center.y.0 as i32,
};
let monitor = unsafe { MonitorFromPoint(center, MONITOR_DEFAULTTONULL) };
if monitor.is_invalid() {
@@ -167,7 +167,7 @@ impl PlatformDisplay for WindowsDisplay {
Ok(self.uuid)
}
fn bounds(&self) -> Bounds<DevicePixels> {
fn bounds(&self) -> Bounds<Pixels> {
self.bounds
}
}
+10 -13
View File
@@ -98,13 +98,13 @@ fn handle_move_msg(
lparam: LPARAM,
state_ptr: Rc<WindowsWindowStatePtr>,
) -> Option<isize> {
let x = lparam.signed_loword() as i32;
let y = lparam.signed_hiword() as i32;
let x = lparam.signed_loword() as f32;
let y = lparam.signed_hiword() as f32;
let mut lock = state_ptr.state.borrow_mut();
lock.origin = point(x.into(), y.into());
lock.origin = point(px(x), px(y));
let size = lock.physical_size;
let center_x = x + size.width.0 / 2;
let center_y = y + size.height.0 / 2;
let center_x = x + size.width.0 / 2.;
let center_y = y + size.height.0 / 2.;
let monitor_bounds = lock.display.bounds();
if center_x < monitor_bounds.left().0
|| center_x > monitor_bounds.right().0
@@ -131,18 +131,15 @@ fn handle_move_msg(
fn handle_size_msg(lparam: LPARAM, state_ptr: Rc<WindowsWindowStatePtr>) -> Option<isize> {
let width = lparam.loword().max(1) as i32;
let height = lparam.hiword().max(1) as i32;
let new_physical_size = size(width.into(), height.into());
let mut lock = state_ptr.state.borrow_mut();
let new_size = size(DevicePixels(width), DevicePixels(height));
let scale_factor = lock.scale_factor;
lock.physical_size = new_physical_size;
lock.renderer.update_drawable_size(Size {
width: width as f64,
height: height as f64,
});
lock.renderer.update_drawable_size(new_size);
let new_size = new_size.to_pixels(lock.scale_factor);
lock.physical_size = new_size;
if let Some(mut callback) = lock.callbacks.resize.take() {
drop(lock);
let logical_size = logical_size(new_physical_size, scale_factor);
callback(logical_size, scale_factor);
callback(new_size, scale_factor);
state_ptr.state.borrow_mut().callbacks.resize = Some(callback);
}
Some(0)
+30 -29
View File
@@ -27,14 +27,14 @@ use windows::{
};
use crate::platform::blade::BladeRenderer;
use crate::*;
use crate::{Pixels, *};
pub(crate) struct WindowsWindow(pub Rc<WindowsWindowStatePtr>);
pub struct WindowsWindowState {
pub origin: Point<DevicePixels>,
pub physical_size: Size<DevicePixels>,
pub fullscreen_restore_bounds: Bounds<DevicePixels>,
pub origin: Point<Pixels>,
pub physical_size: Size<Pixels>,
pub fullscreen_restore_bounds: Bounds<Pixels>,
pub scale_factor: f32,
pub callbacks: Callbacks,
@@ -68,8 +68,8 @@ impl WindowsWindowState {
current_cursor: HCURSOR,
display: WindowsDisplay,
) -> Self {
let origin = point(cs.x.into(), cs.y.into());
let physical_size = size(cs.cx.into(), cs.cy.into());
let origin = point(px(cs.x as f32), px(cs.y as f32));
let physical_size = size(px(cs.cx as f32), px(cs.cy as f32));
let fullscreen_restore_bounds = Bounds {
origin,
size: physical_size,
@@ -113,7 +113,7 @@ impl WindowsWindowState {
!self.is_fullscreen() && unsafe { IsZoomed(self.hwnd) }.as_bool()
}
fn bounds(&self) -> Bounds<DevicePixels> {
fn bounds(&self) -> Bounds<Pixels> {
Bounds {
origin: self.origin,
size: self.physical_size,
@@ -131,12 +131,12 @@ impl WindowsWindowState {
};
let bounds = Bounds {
origin: point(
DevicePixels(placement.rcNormalPosition.left),
DevicePixels(placement.rcNormalPosition.top),
px(placement.rcNormalPosition.left as f32),
px(placement.rcNormalPosition.top as f32),
),
size: size(
DevicePixels(placement.rcNormalPosition.right - placement.rcNormalPosition.left),
DevicePixels(placement.rcNormalPosition.bottom - placement.rcNormalPosition.top),
px((placement.rcNormalPosition.right - placement.rcNormalPosition.left) as f32),
px((placement.rcNormalPosition.bottom - placement.rcNormalPosition.top) as f32),
),
};
@@ -154,7 +154,7 @@ impl WindowsWindowState {
/// Currently, GPUI uses logical size of the app to handle mouse interactions (such as
/// whether the mouse collides with other elements of GPUI).
fn content_size(&self) -> Size<Pixels> {
logical_size(self.physical_size, self.scale_factor)
self.physical_size
}
fn title_bar_padding(&self) -> Pixels {
@@ -306,6 +306,7 @@ impl WindowsWindow {
} else {
display.default_bounds()
};
let bounds = bounds.to_device_pixels(wnd.0.state.borrow().scale_factor);
placement.rcNormalPosition.left = bounds.left().0;
placement.rcNormalPosition.right = bounds.right().0;
placement.rcNormalPosition.top = bounds.top().0;
@@ -353,7 +354,7 @@ impl Drop for WindowsWindow {
}
impl PlatformWindow for WindowsWindow {
fn bounds(&self) -> Bounds<DevicePixels> {
fn bounds(&self) -> Bounds<Pixels> {
self.0.state.borrow().bounds()
}
@@ -554,10 +555,10 @@ impl PlatformWindow for WindowsWindow {
unsafe { GetWindowRect(state_ptr.hwnd, &mut rc) }.log_err();
let _ = lock.fullscreen.insert(StyleAndBounds {
style,
x: rc.left,
y: rc.top,
cx: rc.right - rc.left,
cy: rc.bottom - rc.top,
x: px(rc.left as f32),
y: px(rc.top as f32),
cx: px((rc.right - rc.left) as f32),
cy: px((rc.bottom - rc.top) as f32),
});
let style = style
& !(WS_THICKFRAME
@@ -568,10 +569,10 @@ impl PlatformWindow for WindowsWindow {
let bounds = lock.display.bounds();
StyleAndBounds {
style,
x: bounds.left().0,
y: bounds.top().0,
cx: bounds.size.width.0,
cy: bounds.size.height.0,
x: bounds.left(),
y: bounds.top(),
cx: bounds.size.width,
cy: bounds.size.height,
}
};
drop(lock);
@@ -580,10 +581,10 @@ impl PlatformWindow for WindowsWindow {
SetWindowPos(
state_ptr.hwnd,
HWND::default(),
x,
y,
cx,
cy,
x.0 as i32,
y.0 as i32,
cx.0 as i32,
cy.0 as i32,
SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOZORDER,
)
}
@@ -836,10 +837,10 @@ impl ClickState {
struct StyleAndBounds {
style: WINDOW_STYLE,
x: i32,
y: i32,
cx: i32,
cy: i32,
x: Pixels,
y: Pixels,
cx: Pixels,
cy: Pixels,
}
fn register_wnd_class(icon_handle: HICON) -> PCWSTR {