Clean up the Windows WindowState
This would leak before this change.
This commit is contained in:
parent
8e3e078220
commit
c10ca6b40f
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue