mirror of
https://github.com/zed-industries/zed.git
synced 2024-09-18 18:08:07 +03:00
Update display
info when window moved to another monitor (#9360)
Release Notes: - N/A
This commit is contained in:
parent
c116a7ca5b
commit
64ebbb4afc
@ -11,6 +11,7 @@ use crate::{Bounds, DisplayId, GlobalPixels, PlatformDisplay, Point, Size};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct WindowsDisplay {
|
||||
pub handle: HMONITOR,
|
||||
pub display_id: DisplayId,
|
||||
bounds: Bounds<GlobalPixels>,
|
||||
uuid: Uuid,
|
||||
@ -28,6 +29,7 @@ impl WindowsDisplay {
|
||||
let uuid = generate_uuid(&info.szDevice);
|
||||
|
||||
Some(WindowsDisplay {
|
||||
handle: screen,
|
||||
display_id,
|
||||
bounds: Bounds {
|
||||
origin: Point {
|
||||
@ -43,12 +45,39 @@ 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 uuid = generate_uuid(&info.szDevice);
|
||||
let display_id = available_monitors()
|
||||
.iter()
|
||||
.position(|handle| handle.0 == monitor.0)
|
||||
.unwrap();
|
||||
|
||||
WindowsDisplay {
|
||||
handle: monitor,
|
||||
display_id: DisplayId(display_id as _),
|
||||
bounds: Bounds {
|
||||
origin: Point {
|
||||
x: GlobalPixels(size.left as f32),
|
||||
y: GlobalPixels(size.top as f32),
|
||||
},
|
||||
size: Size {
|
||||
width: GlobalPixels((size.right - size.left) as f32),
|
||||
height: GlobalPixels((size.bottom - size.top) as f32),
|
||||
},
|
||||
},
|
||||
uuid,
|
||||
}
|
||||
}
|
||||
|
||||
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 uuid = generate_uuid(&info.szDevice);
|
||||
|
||||
WindowsDisplay {
|
||||
handle,
|
||||
display_id,
|
||||
bounds: Bounds {
|
||||
origin: Point {
|
||||
@ -75,17 +104,7 @@ impl WindowsDisplay {
|
||||
);
|
||||
return None;
|
||||
}
|
||||
let Some(display_id) = available_monitors()
|
||||
.iter()
|
||||
.position(|handle| handle.0 == monitor.0)
|
||||
else {
|
||||
return None;
|
||||
};
|
||||
|
||||
Some(WindowsDisplay::new_with_handle_and_id(
|
||||
monitor,
|
||||
DisplayId(display_id as _),
|
||||
))
|
||||
Some(WindowsDisplay::new_with_handle(monitor))
|
||||
}
|
||||
|
||||
pub fn displays() -> Vec<Rc<dyn PlatformDisplay>> {
|
||||
|
@ -49,6 +49,7 @@ pub(crate) struct WindowsWindowInner {
|
||||
platform_inner: Rc<WindowsPlatformInner>,
|
||||
pub(crate) handle: AnyWindowHandle,
|
||||
scale_factor: f32,
|
||||
display: RefCell<Rc<WindowsDisplay>>,
|
||||
}
|
||||
|
||||
impl WindowsWindowInner {
|
||||
@ -57,6 +58,7 @@ impl WindowsWindowInner {
|
||||
cs: &CREATESTRUCTW,
|
||||
platform_inner: Rc<WindowsPlatformInner>,
|
||||
handle: AnyWindowHandle,
|
||||
display: Rc<WindowsDisplay>,
|
||||
) -> Self {
|
||||
let origin = Cell::new(Point::new((cs.x as f64).into(), (cs.y as f64).into()));
|
||||
let size = Cell::new(Size {
|
||||
@ -101,6 +103,7 @@ impl WindowsWindowInner {
|
||||
};
|
||||
let renderer = RefCell::new(BladeRenderer::new(gpu, extent));
|
||||
let callbacks = RefCell::new(Callbacks::default());
|
||||
let display = RefCell::new(display);
|
||||
Self {
|
||||
hwnd,
|
||||
origin,
|
||||
@ -112,6 +115,7 @@ impl WindowsWindowInner {
|
||||
platform_inner,
|
||||
handle,
|
||||
scale_factor: 1.0,
|
||||
display,
|
||||
}
|
||||
}
|
||||
|
||||
@ -251,6 +255,22 @@ impl WindowsWindowInner {
|
||||
let x = lparam.signed_loword() as f64;
|
||||
let y = lparam.signed_hiword() as f64;
|
||||
self.origin.set(Point::new(x.into(), y.into()));
|
||||
let size = self.size.get();
|
||||
let center_x = x as f32 + size.width.0 / 2.0;
|
||||
let center_y = y as f32 + size.height.0 / 2.0;
|
||||
let monitor_bounds = self.display.borrow().bounds();
|
||||
if center_x < monitor_bounds.left().0
|
||||
|| center_x > monitor_bounds.right().0
|
||||
|| center_y < monitor_bounds.top().0
|
||||
|| center_y > monitor_bounds.bottom().0
|
||||
{
|
||||
// center of the window may have moved to another monitor
|
||||
let monitor = unsafe { MonitorFromWindow(self.hwnd, MONITOR_DEFAULTTONULL) };
|
||||
if !monitor.is_invalid() && self.display.borrow().handle != monitor {
|
||||
// we will get the same monitor if we only have one
|
||||
(*self.display.borrow_mut()) = Rc::new(WindowsDisplay::new_with_handle(monitor));
|
||||
}
|
||||
}
|
||||
let mut callbacks = self.callbacks.borrow_mut();
|
||||
if let Some(callback) = callbacks.moved.as_mut() {
|
||||
callback()
|
||||
@ -1015,13 +1035,13 @@ struct Callbacks {
|
||||
pub(crate) struct WindowsWindow {
|
||||
inner: Rc<WindowsWindowInner>,
|
||||
drag_drop_handler: IDropTarget,
|
||||
display: Rc<WindowsDisplay>,
|
||||
}
|
||||
|
||||
struct WindowCreateContext {
|
||||
inner: Option<Rc<WindowsWindowInner>>,
|
||||
platform_inner: Rc<WindowsPlatformInner>,
|
||||
handle: AnyWindowHandle,
|
||||
display: Rc<WindowsDisplay>,
|
||||
}
|
||||
|
||||
impl WindowsWindow {
|
||||
@ -1051,6 +1071,9 @@ impl WindowsWindow {
|
||||
inner: None,
|
||||
platform_inner: platform_inner.clone(),
|
||||
handle,
|
||||
// todo(windows) move window to target monitor
|
||||
// options.display_id
|
||||
display: Rc::new(WindowsDisplay::primary_monitor().unwrap()),
|
||||
};
|
||||
let lpparam = Some(&context as *const _ as *const _);
|
||||
unsafe {
|
||||
@ -1079,12 +1102,9 @@ impl WindowsWindow {
|
||||
};
|
||||
drag_drop_handler
|
||||
};
|
||||
// todo(windows) move window to target monitor
|
||||
// options.display_id
|
||||
let wnd = Self {
|
||||
inner: context.inner.unwrap(),
|
||||
drag_drop_handler,
|
||||
display: Rc::new(WindowsDisplay::primary_monitor().unwrap()),
|
||||
};
|
||||
platform_inner
|
||||
.raw_window_handles
|
||||
@ -1161,7 +1181,7 @@ impl PlatformWindow for WindowsWindow {
|
||||
}
|
||||
|
||||
fn display(&self) -> Rc<dyn PlatformDisplay> {
|
||||
self.display.clone()
|
||||
self.inner.display.borrow().clone()
|
||||
}
|
||||
|
||||
fn mouse_position(&self) -> Point<Pixels> {
|
||||
@ -1504,6 +1524,7 @@ unsafe extern "system" fn wnd_proc(
|
||||
cs,
|
||||
ctx.platform_inner.clone(),
|
||||
ctx.handle,
|
||||
ctx.display.clone(),
|
||||
));
|
||||
let weak = Box::new(Rc::downgrade(&inner));
|
||||
unsafe { set_window_long(hwnd, GWLP_USERDATA, Box::into_raw(weak) as isize) };
|
||||
|
Loading…
Reference in New Issue
Block a user