@@ -62,14 +62,16 @@ pub(crate) fn handle_msg(
WM_NCMBUTTONUP => {
handle_nc_mouse_up_msg(handle, MouseButton::Middle, wparam, lparam, state_ptr)
}
- WM_LBUTTONDOWN => handle_mouse_down_msg(MouseButton::Left, lparam, state_ptr),
- WM_RBUTTONDOWN => handle_mouse_down_msg(MouseButton::Right, lparam, state_ptr),
- WM_MBUTTONDOWN => handle_mouse_down_msg(MouseButton::Middle, lparam, state_ptr),
- WM_XBUTTONDOWN => handle_xbutton_msg(wparam, lparam, handle_mouse_down_msg, state_ptr),
- WM_LBUTTONUP => handle_mouse_up_msg(MouseButton::Left, lparam, state_ptr),
- WM_RBUTTONUP => handle_mouse_up_msg(MouseButton::Right, lparam, state_ptr),
- WM_MBUTTONUP => handle_mouse_up_msg(MouseButton::Middle, lparam, state_ptr),
- WM_XBUTTONUP => handle_xbutton_msg(wparam, lparam, handle_mouse_up_msg, state_ptr),
+ WM_LBUTTONDOWN => handle_mouse_down_msg(handle, MouseButton::Left, lparam, state_ptr),
+ WM_RBUTTONDOWN => handle_mouse_down_msg(handle, MouseButton::Right, lparam, state_ptr),
+ WM_MBUTTONDOWN => handle_mouse_down_msg(handle, MouseButton::Middle, lparam, state_ptr),
+ WM_XBUTTONDOWN => {
+ handle_xbutton_msg(handle, wparam, lparam, handle_mouse_down_msg, state_ptr)
+ }
+ WM_LBUTTONUP => handle_mouse_up_msg(handle, MouseButton::Left, lparam, state_ptr),
+ WM_RBUTTONUP => handle_mouse_up_msg(handle, MouseButton::Right, lparam, state_ptr),
+ WM_MBUTTONUP => handle_mouse_up_msg(handle, MouseButton::Middle, lparam, state_ptr),
+ WM_XBUTTONUP => handle_xbutton_msg(handle, wparam, lparam, handle_mouse_up_msg, state_ptr),
WM_MOUSEWHEEL => handle_mouse_wheel_msg(handle, wparam, lparam, state_ptr),
WM_MOUSEHWHEEL => handle_mouse_horizontal_wheel_msg(handle, wparam, lparam, state_ptr),
WM_SYSKEYDOWN => handle_syskeydown_msg(wparam, lparam, state_ptr),
@@ -409,10 +411,12 @@ fn handle_char_msg(
}
fn handle_mouse_down_msg(
+ handle: HWND,
button: MouseButton,
lparam: LPARAM,
state_ptr: Rc<WindowsWindowStatePtr>,
) -> Option<isize> {
+ unsafe { SetCapture(handle) };
let mut lock = state_ptr.state.borrow_mut();
if let Some(mut callback) = lock.callbacks.input.take() {
let x = lparam.signed_loword() as f32;
@@ -443,10 +447,12 @@ fn handle_mouse_down_msg(
}
fn handle_mouse_up_msg(
+ _handle: HWND,
button: MouseButton,
lparam: LPARAM,
state_ptr: Rc<WindowsWindowStatePtr>,
) -> Option<isize> {
+ unsafe { ReleaseCapture().log_err() };
let mut lock = state_ptr.state.borrow_mut();
if let Some(mut callback) = lock.callbacks.input.take() {
let x = lparam.signed_loword() as f32;
@@ -475,9 +481,10 @@ fn handle_mouse_up_msg(
}
fn handle_xbutton_msg(
+ handle: HWND,
wparam: WPARAM,
lparam: LPARAM,
- handler: impl Fn(MouseButton, LPARAM, Rc<WindowsWindowStatePtr>) -> Option<isize>,
+ handler: impl Fn(HWND, MouseButton, LPARAM, Rc<WindowsWindowStatePtr>) -> Option<isize>,
state_ptr: Rc<WindowsWindowStatePtr>,
) -> Option<isize> {
let nav_dir = match wparam.hiword() {
@@ -485,7 +492,7 @@ fn handle_xbutton_msg(
XBUTTON2 => NavigationDirection::Forward,
_ => return Some(1),
};
- handler(MouseButton::Navigate(nav_dir), lparam, state_ptr)
+ handler(handle, MouseButton::Navigate(nav_dir), lparam, state_ptr)
}
fn handle_mouse_wheel_msg(
@@ -919,7 +926,7 @@ fn handle_nc_mouse_down_msg(
}
let mut lock = state_ptr.state.borrow_mut();
- let result = if let Some(mut callback) = lock.callbacks.input.take() {
+ if let Some(mut callback) = lock.callbacks.input.take() {
let scale_factor = lock.scale_factor;
let mut cursor_point = POINT {
x: lparam.signed_loword().into(),
@@ -943,13 +950,25 @@ fn handle_nc_mouse_down_msg(
};
state_ptr.state.borrow_mut().callbacks.input = Some(callback);
- result
+ if result.is_some() {
+ return result;
+ }
} else {
- None
+ drop(lock);
};
// Since these are handled in handle_nc_mouse_up_msg we must prevent the default window proc
- result.or_else(|| matches!(wparam.0 as u32, HTMINBUTTON | HTMAXBUTTON | HTCLOSE).then_some(0))
+ if button == MouseButton::Left {
+ match wparam.0 as u32 {
+ HTMINBUTTON => state_ptr.state.borrow_mut().nc_button_pressed = Some(HTMINBUTTON),
+ HTMAXBUTTON => state_ptr.state.borrow_mut().nc_button_pressed = Some(HTMAXBUTTON),
+ HTCLOSE => state_ptr.state.borrow_mut().nc_button_pressed = Some(HTCLOSE),
+ _ => return None,
+ };
+ Some(0)
+ } else {
+ None
+ }
}
fn handle_nc_mouse_up_msg(
@@ -991,24 +1010,41 @@ fn handle_nc_mouse_up_msg(
drop(lock);
}
- if button == MouseButton::Left {
+ let last_pressed = state_ptr.state.borrow_mut().nc_button_pressed.take();
+ if button == MouseButton::Left && last_pressed.is_some() {
+ let last_button = last_pressed.unwrap();
+ let mut handled = false;
match wparam.0 as u32 {
- HTMINBUTTON => unsafe {
- ShowWindowAsync(handle, SW_MINIMIZE).ok().log_err();
- },
- HTMAXBUTTON => unsafe {
- if state_ptr.state.borrow().is_maximized() {
- ShowWindowAsync(handle, SW_NORMAL).ok().log_err();
- } else {
- ShowWindowAsync(handle, SW_MAXIMIZE).ok().log_err();
+ HTMINBUTTON => {
+ if last_button == HTMINBUTTON {
+ unsafe { ShowWindowAsync(handle, SW_MINIMIZE).ok().log_err() };
+ handled = true;
}
- },
- HTCLOSE => unsafe {
- PostMessageW(handle, WM_CLOSE, WPARAM::default(), LPARAM::default()).log_err();
- },
- _ => return None,
+ }
+ HTMAXBUTTON => {
+ if last_button == HTMAXBUTTON {
+ if state_ptr.state.borrow().is_maximized() {
+ unsafe { ShowWindowAsync(handle, SW_NORMAL).ok().log_err() };
+ } else {
+ unsafe { ShowWindowAsync(handle, SW_MAXIMIZE).ok().log_err() };
+ }
+ handled = true;
+ }
+ }
+ HTCLOSE => {
+ if last_button == HTCLOSE {
+ unsafe {
+ PostMessageW(handle, WM_CLOSE, WPARAM::default(), LPARAM::default())
+ .log_err()
+ };
+ handled = true;
+ }
+ }
+ _ => {}
};
- return Some(0);
+ if handled {
+ return Some(0);
+ }
}
None