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:
co-authored by
Conrad Irwin
Mikayla
parent
22dc88ed3d
commit
da281d6d8f
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user