mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-08 07:35:01 +03:00
windows: Fix regression introduced by a prev PR (#13090)
Fix regression introduced by #12991 ### Before The re-position and re-size of a window is broken. https://github.com/zed-industries/zed/assets/14981363/d4fb9dce-707e-4ab1-9ff5-f355b7fdd8a8 ### After https://github.com/zed-industries/zed/assets/14981363/7fd232e6-ff6c-4b7f-ad32-c284acd4f6db Release Notes: - N/A
This commit is contained in:
parent
bb75d87285
commit
e19627d92f
@ -5,42 +5,55 @@ use util::ResultExt;
|
||||
use uuid::Uuid;
|
||||
use windows::{
|
||||
core::*,
|
||||
Win32::{Foundation::*, Graphics::Gdi::*},
|
||||
Win32::{
|
||||
Foundation::*,
|
||||
Graphics::Gdi::*,
|
||||
UI::{
|
||||
HiDpi::{GetDpiForMonitor, MDT_EFFECTIVE_DPI},
|
||||
WindowsAndMessaging::USER_DEFAULT_SCREEN_DPI,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
use crate::{px, Bounds, DisplayId, Pixels, PlatformDisplay, Point, Size};
|
||||
use crate::{logical_point, point, size, Bounds, DevicePixels, DisplayId, Pixels, PlatformDisplay};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub(crate) struct WindowsDisplay {
|
||||
pub handle: HMONITOR,
|
||||
pub display_id: DisplayId,
|
||||
scale_factor: f32,
|
||||
bounds: Bounds<Pixels>,
|
||||
physical_bounds: Bounds<DevicePixels>,
|
||||
uuid: Uuid,
|
||||
}
|
||||
|
||||
impl WindowsDisplay {
|
||||
pub(crate) fn new(display_id: DisplayId) -> Option<Self> {
|
||||
let Some(screen) = available_monitors().into_iter().nth(display_id.0 as _) else {
|
||||
return None;
|
||||
};
|
||||
let Ok(info) = get_monitor_info(screen).inspect_err(|e| log::error!("{}", e)) else {
|
||||
return None;
|
||||
};
|
||||
let size = info.monitorInfo.rcMonitor;
|
||||
let screen = available_monitors().into_iter().nth(display_id.0 as _)?;
|
||||
let info = get_monitor_info(screen).log_err()?;
|
||||
let monitor_size = info.monitorInfo.rcMonitor;
|
||||
let uuid = generate_uuid(&info.szDevice);
|
||||
let scale_factor = get_scale_factor_for_monitor(screen).log_err()?;
|
||||
let physical_size = size(
|
||||
(monitor_size.right - monitor_size.left).into(),
|
||||
(monitor_size.bottom - monitor_size.top).into(),
|
||||
);
|
||||
|
||||
Some(WindowsDisplay {
|
||||
handle: screen,
|
||||
display_id,
|
||||
scale_factor,
|
||||
bounds: Bounds {
|
||||
origin: Point {
|
||||
x: px(size.left as f32),
|
||||
y: px(size.top as f32),
|
||||
},
|
||||
size: Size {
|
||||
width: px((size.right - size.left) as f32),
|
||||
height: px((size.bottom - size.top) as f32),
|
||||
},
|
||||
origin: logical_point(
|
||||
monitor_size.left as f32,
|
||||
monitor_size.top as f32,
|
||||
scale_factor,
|
||||
),
|
||||
size: physical_size.to_pixels(scale_factor),
|
||||
},
|
||||
physical_bounds: Bounds {
|
||||
origin: point(monitor_size.left.into(), monitor_size.top.into()),
|
||||
size: physical_size,
|
||||
},
|
||||
uuid,
|
||||
})
|
||||
@ -48,25 +61,34 @@ impl WindowsDisplay {
|
||||
|
||||
pub fn new_with_handle(monitor: HMONITOR) -> Self {
|
||||
let info = get_monitor_info(monitor).expect("unable to get monitor info");
|
||||
let size = info.monitorInfo.rcMonitor;
|
||||
let monitor_size = info.monitorInfo.rcMonitor;
|
||||
let uuid = generate_uuid(&info.szDevice);
|
||||
let display_id = available_monitors()
|
||||
.iter()
|
||||
.position(|handle| handle.0 == monitor.0)
|
||||
.unwrap();
|
||||
let scale_factor =
|
||||
get_scale_factor_for_monitor(monitor).expect("unable to get scale factor for monitor");
|
||||
let physical_size = size(
|
||||
(monitor_size.right - monitor_size.left).into(),
|
||||
(monitor_size.bottom - monitor_size.top).into(),
|
||||
);
|
||||
|
||||
WindowsDisplay {
|
||||
handle: monitor,
|
||||
display_id: DisplayId(display_id as _),
|
||||
scale_factor,
|
||||
bounds: Bounds {
|
||||
origin: Point {
|
||||
x: px(size.left as f32),
|
||||
y: px(size.top as f32),
|
||||
},
|
||||
size: Size {
|
||||
width: px((size.right - size.left) as f32),
|
||||
height: px((size.bottom - size.top) as f32),
|
||||
},
|
||||
origin: logical_point(
|
||||
monitor_size.left as f32,
|
||||
monitor_size.top as f32,
|
||||
scale_factor,
|
||||
),
|
||||
size: physical_size.to_pixels(scale_factor),
|
||||
},
|
||||
physical_bounds: Bounds {
|
||||
origin: point(monitor_size.left.into(), monitor_size.top.into()),
|
||||
size: physical_size,
|
||||
},
|
||||
uuid,
|
||||
}
|
||||
@ -74,21 +96,30 @@ impl WindowsDisplay {
|
||||
|
||||
fn new_with_handle_and_id(handle: HMONITOR, display_id: DisplayId) -> Self {
|
||||
let info = get_monitor_info(handle).expect("unable to get monitor info");
|
||||
let size = info.monitorInfo.rcMonitor;
|
||||
let monitor_size = info.monitorInfo.rcMonitor;
|
||||
let uuid = generate_uuid(&info.szDevice);
|
||||
let scale_factor =
|
||||
get_scale_factor_for_monitor(handle).expect("unable to get scale factor for monitor");
|
||||
let physical_size = size(
|
||||
(monitor_size.right - monitor_size.left).into(),
|
||||
(monitor_size.bottom - monitor_size.top).into(),
|
||||
);
|
||||
|
||||
WindowsDisplay {
|
||||
handle,
|
||||
display_id,
|
||||
scale_factor,
|
||||
bounds: Bounds {
|
||||
origin: Point {
|
||||
x: px(size.left as f32),
|
||||
y: px(size.top as f32),
|
||||
},
|
||||
size: Size {
|
||||
width: px((size.right - size.left) as f32),
|
||||
height: px((size.bottom - size.top) as f32),
|
||||
},
|
||||
origin: logical_point(
|
||||
monitor_size.left as f32,
|
||||
monitor_size.top as f32,
|
||||
scale_factor,
|
||||
),
|
||||
size: physical_size.to_pixels(scale_factor),
|
||||
},
|
||||
physical_bounds: Bounds {
|
||||
origin: point(monitor_size.left.into(), monitor_size.top.into()),
|
||||
size: physical_size,
|
||||
},
|
||||
uuid,
|
||||
}
|
||||
@ -112,8 +143,8 @@ impl WindowsDisplay {
|
||||
pub fn check_given_bounds(&self, bounds: Bounds<Pixels>) -> bool {
|
||||
let center = bounds.center();
|
||||
let center = POINT {
|
||||
x: center.x.0 as i32,
|
||||
y: center.y.0 as i32,
|
||||
x: (center.x.0 * self.scale_factor) as i32,
|
||||
y: (center.y.0 * self.scale_factor) as i32,
|
||||
};
|
||||
let monitor = unsafe { MonitorFromPoint(center, MONITOR_DEFAULTTONULL) };
|
||||
if monitor.is_invalid() {
|
||||
@ -156,6 +187,10 @@ impl WindowsDisplay {
|
||||
pub fn is_connected(hmonitor: HMONITOR) -> bool {
|
||||
available_monitors().iter().contains(&hmonitor)
|
||||
}
|
||||
|
||||
pub fn physical_bounds(&self) -> Bounds<DevicePixels> {
|
||||
self.physical_bounds
|
||||
}
|
||||
}
|
||||
|
||||
impl PlatformDisplay for WindowsDisplay {
|
||||
@ -221,3 +256,11 @@ fn generate_uuid(device_name: &[u16]) -> Uuid {
|
||||
.collect_vec();
|
||||
Uuid::new_v5(&Uuid::NAMESPACE_DNS, &name)
|
||||
}
|
||||
|
||||
fn get_scale_factor_for_monitor(monitor: HMONITOR) -> Result<f32> {
|
||||
let mut dpi_x = 0;
|
||||
let mut dpi_y = 0;
|
||||
unsafe { GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &mut dpi_x, &mut dpi_y) }?;
|
||||
assert_eq!(dpi_x, dpi_y);
|
||||
Ok(dpi_x as f32 / USER_DEFAULT_SCREEN_DPI as f32)
|
||||
}
|
||||
|
@ -98,13 +98,16 @@ fn handle_move_msg(
|
||||
lparam: LPARAM,
|
||||
state_ptr: Rc<WindowsWindowStatePtr>,
|
||||
) -> Option<isize> {
|
||||
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(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 origin = logical_point(
|
||||
lparam.signed_loword() as f32,
|
||||
lparam.signed_hiword() as f32,
|
||||
lock.scale_factor,
|
||||
);
|
||||
lock.origin = origin;
|
||||
let size = lock.logical_size;
|
||||
let center_x = origin.x.0 + size.width.0 / 2.;
|
||||
let center_y = origin.y.0 + size.height.0 / 2.;
|
||||
let monitor_bounds = lock.display.bounds();
|
||||
if center_x < monitor_bounds.left().0
|
||||
|| center_x > monitor_bounds.right().0
|
||||
@ -135,8 +138,8 @@ fn handle_size_msg(lparam: LPARAM, state_ptr: Rc<WindowsWindowStatePtr>) -> Opti
|
||||
let new_size = size(DevicePixels(width), DevicePixels(height));
|
||||
let scale_factor = lock.scale_factor;
|
||||
lock.renderer.update_drawable_size(new_size);
|
||||
let new_size = new_size.to_pixels(lock.scale_factor);
|
||||
lock.physical_size = new_size;
|
||||
let new_size = new_size.to_pixels(scale_factor);
|
||||
lock.logical_size = new_size;
|
||||
if let Some(mut callback) = lock.callbacks.resize.take() {
|
||||
drop(lock);
|
||||
callback(new_size, scale_factor);
|
||||
|
@ -111,14 +111,6 @@ pub(crate) fn load_cursor(style: CursorStyle) -> HCURSOR {
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn logical_size(physical_size: Size<DevicePixels>, scale_factor: f32) -> Size<Pixels> {
|
||||
Size {
|
||||
width: px(physical_size.width.0 as f32 / scale_factor),
|
||||
height: px(physical_size.height.0 as f32 / scale_factor),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn logical_point(x: f32, y: f32, scale_factor: f32) -> Point<Pixels> {
|
||||
Point {
|
||||
|
@ -27,13 +27,13 @@ use windows::{
|
||||
};
|
||||
|
||||
use crate::platform::blade::BladeRenderer;
|
||||
use crate::{Pixels, *};
|
||||
use crate::*;
|
||||
|
||||
pub(crate) struct WindowsWindow(pub Rc<WindowsWindowStatePtr>);
|
||||
|
||||
pub struct WindowsWindowState {
|
||||
pub origin: Point<Pixels>,
|
||||
pub physical_size: Size<Pixels>,
|
||||
pub logical_size: Size<Pixels>,
|
||||
pub fullscreen_restore_bounds: Bounds<Pixels>,
|
||||
pub scale_factor: f32,
|
||||
|
||||
@ -68,16 +68,19 @@ impl WindowsWindowState {
|
||||
current_cursor: HCURSOR,
|
||||
display: WindowsDisplay,
|
||||
) -> Self {
|
||||
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,
|
||||
};
|
||||
let scale_factor = {
|
||||
let monitor_dpi = unsafe { GetDpiForWindow(hwnd) } as f32;
|
||||
monitor_dpi / USER_DEFAULT_SCREEN_DPI as f32
|
||||
};
|
||||
let origin = logical_point(cs.x as f32, cs.y as f32, scale_factor);
|
||||
let logical_size = {
|
||||
let physical_size = size(DevicePixels(cs.cx), DevicePixels(cs.cy));
|
||||
physical_size.to_pixels(scale_factor)
|
||||
};
|
||||
let fullscreen_restore_bounds = Bounds {
|
||||
origin,
|
||||
size: logical_size,
|
||||
};
|
||||
let renderer = windows_renderer::windows_renderer(hwnd, transparent);
|
||||
let callbacks = Callbacks::default();
|
||||
let input_handler = None;
|
||||
@ -88,7 +91,7 @@ impl WindowsWindowState {
|
||||
|
||||
Self {
|
||||
origin,
|
||||
physical_size,
|
||||
logical_size,
|
||||
fullscreen_restore_bounds,
|
||||
scale_factor,
|
||||
callbacks,
|
||||
@ -116,7 +119,7 @@ impl WindowsWindowState {
|
||||
fn bounds(&self) -> Bounds<Pixels> {
|
||||
Bounds {
|
||||
origin: self.origin,
|
||||
size: self.physical_size,
|
||||
size: self.logical_size,
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,15 +132,17 @@ impl WindowsWindowState {
|
||||
GetWindowPlacement(self.hwnd, &mut placement).log_err();
|
||||
placement
|
||||
};
|
||||
let physical_size = size(
|
||||
DevicePixels(placement.rcNormalPosition.right - placement.rcNormalPosition.left),
|
||||
DevicePixels(placement.rcNormalPosition.bottom - placement.rcNormalPosition.top),
|
||||
);
|
||||
let bounds = Bounds {
|
||||
origin: point(
|
||||
px(placement.rcNormalPosition.left as f32),
|
||||
px(placement.rcNormalPosition.top as f32),
|
||||
),
|
||||
size: size(
|
||||
px((placement.rcNormalPosition.right - placement.rcNormalPosition.left) as f32),
|
||||
px((placement.rcNormalPosition.bottom - placement.rcNormalPosition.top) as f32),
|
||||
origin: logical_point(
|
||||
placement.rcNormalPosition.left as f32,
|
||||
placement.rcNormalPosition.top as f32,
|
||||
self.scale_factor,
|
||||
),
|
||||
size: physical_size.to_pixels(self.scale_factor),
|
||||
};
|
||||
|
||||
if self.is_fullscreen() {
|
||||
@ -154,7 +159,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> {
|
||||
self.physical_size
|
||||
self.logical_size
|
||||
}
|
||||
|
||||
fn title_bar_padding(&self) -> Pixels {
|
||||
@ -538,7 +543,7 @@ impl PlatformWindow for WindowsWindow {
|
||||
let mut lock = state_ptr.state.borrow_mut();
|
||||
lock.fullscreen_restore_bounds = Bounds {
|
||||
origin: lock.origin,
|
||||
size: lock.physical_size,
|
||||
size: lock.logical_size,
|
||||
};
|
||||
let StyleAndBounds {
|
||||
style,
|
||||
@ -555,10 +560,10 @@ impl PlatformWindow for WindowsWindow {
|
||||
unsafe { GetWindowRect(state_ptr.hwnd, &mut rc) }.log_err();
|
||||
let _ = lock.fullscreen.insert(StyleAndBounds {
|
||||
style,
|
||||
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),
|
||||
x: rc.left,
|
||||
y: rc.top,
|
||||
cx: rc.right - rc.left,
|
||||
cy: rc.bottom - rc.top,
|
||||
});
|
||||
let style = style
|
||||
& !(WS_THICKFRAME
|
||||
@ -566,13 +571,13 @@ impl PlatformWindow for WindowsWindow {
|
||||
| WS_MAXIMIZEBOX
|
||||
| WS_MINIMIZEBOX
|
||||
| WS_CAPTION);
|
||||
let bounds = lock.display.bounds();
|
||||
let physical_bounds = lock.display.physical_bounds();
|
||||
StyleAndBounds {
|
||||
style,
|
||||
x: bounds.left(),
|
||||
y: bounds.top(),
|
||||
cx: bounds.size.width,
|
||||
cy: bounds.size.height,
|
||||
x: physical_bounds.left().0,
|
||||
y: physical_bounds.top().0,
|
||||
cx: physical_bounds.size.width.0,
|
||||
cy: physical_bounds.size.height.0,
|
||||
}
|
||||
};
|
||||
drop(lock);
|
||||
@ -581,10 +586,10 @@ impl PlatformWindow for WindowsWindow {
|
||||
SetWindowPos(
|
||||
state_ptr.hwnd,
|
||||
HWND::default(),
|
||||
x.0 as i32,
|
||||
y.0 as i32,
|
||||
cx.0 as i32,
|
||||
cy.0 as i32,
|
||||
x,
|
||||
y,
|
||||
cx,
|
||||
cy,
|
||||
SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOZORDER,
|
||||
)
|
||||
}
|
||||
@ -837,10 +842,10 @@ impl ClickState {
|
||||
|
||||
struct StyleAndBounds {
|
||||
style: WINDOW_STYLE,
|
||||
x: Pixels,
|
||||
y: Pixels,
|
||||
cx: Pixels,
|
||||
cy: Pixels,
|
||||
x: i32,
|
||||
y: i32,
|
||||
cx: i32,
|
||||
cy: i32,
|
||||
}
|
||||
|
||||
fn register_wnd_class(icon_handle: HICON) -> PCWSTR {
|
||||
|
Loading…
Reference in New Issue
Block a user