windows: Fix main thread blocking when resizing or moving window (#10758)

Connection: Fix #10703 


https://github.com/zed-industries/zed/assets/14981363/59abfab7-ebb2-4da7-ad13-0a9e42f9c1d3




Release Notes:

- N/A
This commit is contained in:
张小白 2024-04-20 05:40:21 +08:00 committed by GitHub
parent c3bcfb374c
commit fee2065b64
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 42 additions and 4 deletions

View File

@ -78,6 +78,13 @@ impl WindowsPlatformInner {
.find(|entry| *entry == &hwnd) .find(|entry| *entry == &hwnd)
.and_then(|hwnd| try_get_window_inner(*hwnd)) .and_then(|hwnd| try_get_window_inner(*hwnd))
} }
#[inline]
pub fn run_foreground_tasks(&self) {
for runnable in self.main_receiver.drain() {
runnable.run();
}
}
} }
#[derive(Default)] #[derive(Default)]
@ -182,10 +189,9 @@ impl WindowsPlatform {
Self { inner } Self { inner }
} }
#[inline]
fn run_foreground_tasks(&self) { fn run_foreground_tasks(&self) {
for runnable in self.inner.main_receiver.drain() { self.inner.run_foreground_tasks();
runnable.run();
}
} }
fn redraw_all(&self) { fn redraw_all(&self) {

View File

@ -253,6 +253,9 @@ impl WindowsWindowInner {
WM_CREATE => self.handle_create_msg(lparam), WM_CREATE => self.handle_create_msg(lparam),
WM_MOVE => self.handle_move_msg(lparam), WM_MOVE => self.handle_move_msg(lparam),
WM_SIZE => self.handle_size_msg(lparam), WM_SIZE => self.handle_size_msg(lparam),
WM_ENTERSIZEMOVE | WM_ENTERMENULOOP => self.handle_size_move_loop(),
WM_EXITSIZEMOVE | WM_EXITMENULOOP => self.handle_size_move_loop_exit(),
WM_TIMER => self.handle_timer_msg(wparam),
WM_NCCALCSIZE => self.handle_calc_client_size(wparam, lparam), WM_NCCALCSIZE => self.handle_calc_client_size(wparam, lparam),
WM_DPICHANGED => self.handle_dpi_changed_msg(wparam, lparam), WM_DPICHANGED => self.handle_dpi_changed_msg(wparam, lparam),
WM_NCHITTEST => self.handle_hit_test_msg(msg, wparam, lparam), WM_NCHITTEST => self.handle_hit_test_msg(msg, wparam, lparam),
@ -342,10 +345,38 @@ impl WindowsWindowInner {
let logical_size = logical_size(new_physical_size, scale_factor); let logical_size = logical_size(new_physical_size, scale_factor);
callback(logical_size, scale_factor); callback(logical_size, scale_factor);
} }
self.invalidate_client_area();
Some(0) Some(0)
} }
fn handle_size_move_loop(&self) -> Option<isize> {
unsafe {
let ret = SetTimer(self.hwnd, SIZE_MOVE_LOOP_TIMER_ID, USER_TIMER_MINIMUM, None);
if ret == 0 {
log::error!(
"unable to create timer: {}",
std::io::Error::last_os_error()
);
}
}
None
}
fn handle_size_move_loop_exit(&self) -> Option<isize> {
unsafe {
KillTimer(self.hwnd, SIZE_MOVE_LOOP_TIMER_ID).log_err();
}
None
}
fn handle_timer_msg(&self, wparam: WPARAM) -> Option<isize> {
if wparam.0 == SIZE_MOVE_LOOP_TIMER_ID {
self.platform_inner.run_foreground_tasks();
self.handle_paint_msg();
return Some(0);
}
None
}
fn handle_paint_msg(&self) -> Option<isize> { fn handle_paint_msg(&self) -> Option<isize> {
let mut paint_struct = PAINTSTRUCT::default(); let mut paint_struct = PAINTSTRUCT::default();
let _hdc = unsafe { BeginPaint(self.hwnd, &mut paint_struct) }; let _hdc = unsafe { BeginPaint(self.hwnd, &mut paint_struct) };
@ -1883,6 +1914,7 @@ const DRAGDROP_GET_FILES_COUNT: u32 = 0xFFFFFFFF;
const DOUBLE_CLICK_INTERVAL: Duration = Duration::from_millis(500); const DOUBLE_CLICK_INTERVAL: Duration = Duration::from_millis(500);
// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsystemmetrics // https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsystemmetrics
const DOUBLE_CLICK_SPATIAL_TOLERANCE: i32 = 4; const DOUBLE_CLICK_SPATIAL_TOLERANCE: i32 = 4;
const SIZE_MOVE_LOOP_TIMER_ID: usize = 1;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {