1
0
Fork 0

Clean up the Windows WindowState

This would leak before this change.
This commit is contained in:
Robbert van der Helm 2023-01-01 23:04:27 +01:00
parent 8e3e078220
commit c10ca6b40f

View file

@ -126,11 +126,9 @@ unsafe extern "system" fn wnd_proc(
return 0; return 0;
} }
let window_state_ptr = GetWindowLongPtrW(hwnd, GWLP_USERDATA) as *const WindowState; let window_state_ptr = GetWindowLongPtrW(hwnd, GWLP_USERDATA) as *mut WindowState;
if !window_state_ptr.is_null() { if !window_state_ptr.is_null() {
let window_state = &*window_state_ptr; let result = wnd_proc_inner(hwnd, msg, wparam, lparam, &*window_state_ptr);
let result = wnd_proc_inner(hwnd, msg, wparam, lparam, window_state);
// If any of the above event handlers caused tasks to be pushed to the deferred tasks list, // If any of the above event handlers caused tasks to be pushed to the deferred tasks list,
// then we'll try to handle them now // then we'll try to handle them now
@ -139,12 +137,19 @@ unsafe extern "system" fn wnd_proc(
// the borrow of `window_state.deferred_tasks` into the call of // the borrow of `window_state.deferred_tasks` into the call of
// `window_state.handle_deferred_task()` since that may also generate additional // `window_state.handle_deferred_task()` since that may also generate additional
// messages. // messages.
let task = match window_state.deferred_tasks.borrow_mut().pop_front() { let task = match (*window_state_ptr).deferred_tasks.borrow_mut().pop_front() {
Some(task) => task, Some(task) => task,
None => break, None => break,
}; };
window_state.handle_deferred_task(task); (*window_state_ptr).handle_deferred_task(task);
}
// NOTE: This is not handled in `wnd_proc_inner` because of the deferred task loop above
if msg == WM_NCDESTROY {
unregister_wnd_class((*window_state_ptr).window_class);
SetWindowLongPtrW(hwnd, GWLP_USERDATA, 0);
drop(Box::from_raw(window_state_ptr));
} }
// The actual custom window proc has been moved to another function so we can always handle // The actual custom window proc has been moved to another function so we can always handle
@ -182,7 +187,7 @@ unsafe fn wnd_proc_inner(
window_state.handler.borrow_mut().on_event(&mut window, event); window_state.handler.borrow_mut().on_event(&mut window, event);
return Some(0); Some(0)
} }
WM_MOUSEWHEEL | WM_MOUSEHWHEEL => { WM_MOUSEWHEEL | WM_MOUSEHWHEEL => {
let mut window = window_state.create_window(hwnd); let mut window = window_state.create_window(hwnd);
@ -206,7 +211,7 @@ unsafe fn wnd_proc_inner(
window_state.handler.borrow_mut().on_event(&mut window, event); window_state.handler.borrow_mut().on_event(&mut window, event);
return Some(0); Some(0)
} }
WM_LBUTTONDOWN | WM_LBUTTONUP | WM_MBUTTONDOWN | WM_MBUTTONUP | WM_RBUTTONDOWN WM_LBUTTONDOWN | WM_LBUTTONUP | WM_MBUTTONDOWN | WM_MBUTTONUP | WM_RBUTTONDOWN
| WM_RBUTTONUP | WM_XBUTTONDOWN | WM_XBUTTONUP => { | WM_RBUTTONUP | WM_XBUTTONDOWN | WM_XBUTTONUP => {
@ -265,6 +270,8 @@ unsafe fn wnd_proc_inner(
window_state.handler.borrow_mut().on_event(&mut window, Event::Mouse(event)); window_state.handler.borrow_mut().on_event(&mut window, Event::Mouse(event));
} }
None
} }
WM_TIMER => { WM_TIMER => {
let mut window = window_state.create_window(hwnd); let mut window = window_state.create_window(hwnd);
@ -273,7 +280,8 @@ unsafe fn wnd_proc_inner(
if wparam == WIN_FRAME_TIMER { if wparam == WIN_FRAME_TIMER {
window_state.handler.borrow_mut().on_frame(&mut window); window_state.handler.borrow_mut().on_frame(&mut window);
} }
return Some(0);
Some(0)
} }
WM_CLOSE => { WM_CLOSE => {
// Make sure to release the borrow before the DefWindowProc call // Make sure to release the borrow before the DefWindowProc call
@ -288,8 +296,8 @@ unsafe fn wnd_proc_inner(
} }
// DestroyWindow(hwnd); // DestroyWindow(hwnd);
// return Some(0); // Some(0)
return Some(DefWindowProcW(hwnd, msg, wparam, lparam)); Some(DefWindowProcW(hwnd, msg, wparam, lparam))
} }
WM_CHAR | WM_SYSCHAR | WM_KEYDOWN | WM_SYSKEYDOWN | WM_KEYUP | WM_SYSKEYUP WM_CHAR | WM_SYSCHAR | WM_KEYDOWN | WM_SYSKEYDOWN | WM_KEYUP | WM_SYSKEYUP
| WM_INPUTLANGCHANGE => { | WM_INPUTLANGCHANGE => {
@ -304,7 +312,9 @@ unsafe fn wnd_proc_inner(
} }
if msg != WM_SYSKEYDOWN { if msg != WM_SYSKEYDOWN {
return Some(0); Some(0)
} else {
None
} }
} }
WM_SIZE => { WM_SIZE => {
@ -333,6 +343,8 @@ unsafe fn wnd_proc_inner(
.handler .handler
.borrow_mut() .borrow_mut()
.on_event(&mut window, Event::Window(WindowEvent::Resized(new_window_info))); .on_event(&mut window, Event::Window(WindowEvent::Resized(new_window_info)));
None
} }
WM_DPICHANGED => { WM_DPICHANGED => {
// To avoid weirdness with the realtime borrow checker. // To avoid weirdness with the realtime borrow checker.
@ -376,21 +388,18 @@ unsafe fn wnd_proc_inner(
SWP_NOZORDER | SWP_NOMOVE, SWP_NOZORDER | SWP_NOMOVE,
); );
} }
}
WM_NCDESTROY => {
unregister_wnd_class(window_state.window_class);
SetWindowLongPtrW(hwnd, GWLP_USERDATA, 0);
}
_ => {
if msg == BV_WINDOW_MUST_CLOSE {
DestroyWindow(hwnd);
return Some(0);
}
}
}
None None
} }
// NOTE: `WM_NCDESTROY` is handled in the outer function because this deallocates the window
// state
BV_WINDOW_MUST_CLOSE => {
DestroyWindow(hwnd);
Some(0)
}
_ => None,
}
}
unsafe fn register_wnd_class() -> ATOM { unsafe fn register_wnd_class() -> ATOM {
// We generate a unique name for the new window class to prevent name collisions // We generate a unique name for the new window class to prevent name collisions