1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-23 05:12:40 +03:00

windows: avoid recursing and borrowing inner twice

Querying the window can call into windowproc so we need to avoid
it when we hold `inner`.  Adjust the flow so that we can get
the info about the window state purely from an HWND.

refs: #2257
This commit is contained in:
Wez Furlong 2022-07-13 11:37:04 -07:00
parent 8dcfbc6718
commit 8ef70d1e31

View File

@ -271,7 +271,7 @@ impl WindowInner {
self.events.dispatch(WindowEvent::Resized {
dimensions: current_dims,
window_state: self.get_window_state(),
window_state: get_window_state(self.hwnd.0),
live_resizing: self.in_size_move,
});
}
@ -279,18 +279,6 @@ impl WindowInner {
!same
}
fn get_window_state(&self) -> WindowState {
if self.saved_placement.is_some() {
WindowState::FULL_SCREEN
} else {
match get_window_state(self.hwnd.0) {
SW_SHOWMAXIMIZED => WindowState::MAXIMIZED,
SW_SHOWMINIMIZED => WindowState::HIDDEN,
_ => WindowState::default(),
}
}
}
fn apply_decoration(&mut self) {
let hwnd = self.hwnd.0;
schedule_apply_decoration(hwnd, self.config.window_decorations);
@ -768,15 +756,16 @@ impl WindowOps for Window {
fn set_inner_size(&self, width: usize, height: usize) {
Connection::with_window_inner(self.0, move |inner| {
let hwnd = inner.hwnd;
let decorations = inner.config.window_decorations;
promise::spawn::spawn(async move {
log::trace!("set_inner_size called with {width}x{height}");
let (width, height) = adjust_client_to_window_dimensions(
decorations_to_style(inner.config.window_decorations),
decorations_to_style(decorations),
width,
height,
);
let hwnd = inner.hwnd;
Connection::with_window_inner(hwnd, move |inner| {
let window_state = inner.get_window_state();
let window_state = get_window_state(hwnd.0);
if window_state.can_resize() {
log::trace!("set_inner_size now calling SetWindowPos with {width}x{height}");
unsafe {
@ -797,8 +786,8 @@ impl WindowOps for Window {
because window_state is {window_state:?}"
);
}
Ok(())
});
})
.detach();
Ok(())
});
}
@ -996,7 +985,7 @@ unsafe fn wm_nccalcsize(hwnd: HWND, _msg: UINT, wparam: WPARAM, lparam: LPARAM)
requested_client_rect.right -= frame_x + padding;
requested_client_rect.left += frame_x + padding;
let is_maximized = get_window_state(hwnd) == SW_SHOWMAXIMIZED;
let is_maximized = get_window_state(hwnd) == WindowState::MAXIMIZED;
// Handle bugged top window border on Windows 10
if *IS_WIN10 {
@ -1055,7 +1044,7 @@ unsafe fn wm_nchittest(hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM) ->
let coords = mouse_coords(lparam);
let screen_point = ScreenPoint::new(coords.x, coords.y);
let cursor_point = screen_to_client(hwnd, screen_point);
let is_maximized = get_window_state(hwnd) == SW_SHOWMAXIMIZED;
let is_maximized = get_window_state(hwnd) == WindowState::MAXIMIZED;
// check if mouse is in any of the resize areas (HTTOP, HTBOTTOM, etc)
@ -1098,16 +1087,40 @@ unsafe fn wm_nchittest(hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM) ->
Some(HTCLIENT)
}
fn get_window_state(hwnd: HWND) -> i32 {
fn get_window_state(hwnd: HWND) -> WindowState {
let mut placement = WINDOWPLACEMENT {
length: std::mem::size_of::<WINDOWPLACEMENT>() as _,
..Default::default()
};
let placement =
if unsafe { GetWindowPlacement(hwnd, &mut placement) } == winapi::shared::minwindef::TRUE {
placement.showCmd as i32
} else {
0
};
match placement {
SW_SHOWMAXIMIZED => WindowState::MAXIMIZED,
SW_SHOWMINIMIZED => WindowState::HIDDEN,
_ => unsafe {
let mut rect = std::mem::zeroed();
GetWindowRect(hwnd, &mut rect);
let mut mi: MONITORINFO = std::mem::zeroed();
mi.cbSize = std::mem::size_of::<MONITORINFO>() as u32;
GetMonitorInfoW(MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST), &mut mi);
if mi.rcMonitor.left == rect.left
&& mi.rcMonitor.top == rect.top
&& mi.rcMonitor.right == rect.right
&& mi.rcMonitor.bottom == rect.bottom
{
WindowState::FULL_SCREEN
} else {
WindowState::default()
}
},
}
}