windows: Fix cursor style not changing when hovering over items in the title bar (#22580)
Closes #22578 Currently, the `hovered` boolean in the window state is only updated by the `WM_MOUSELEAVE` event, which fires when the mouse cursor leaves the window's working area. This means that when the user moves the cursor from the window to the title bar, `hovered` is set to `false`. Later in the code, this flag is used to determine the cursor style and check if the cursor is over the correct window. The `hovered` boolean should remain active even when the mouse is over non-client items, such as the title bar or window borders. This PR fixes that by using `WM_NCMOUSELEAVE` event, which is triggered when the mouse leaves non-client items. This event is used to update the `hovered` boolean accordingly. Now, `hovered` is `true` when the mouse is over the window's working area, as well as non-client areas like the title bar. More context: - Existing: `dwFlags: TME_LEAVE` tracks window area mouse leaves, which is used in `handle_mouse_move_msg` func. - New: `dwFlags: TME_LEAVE | TME_NONCLIENT` tracks non-client mouse leaves, which is used in `handle_nc_mouse_move_msg` func. Preview: https://github.com/user-attachments/assets/b319303f-81b9-45cb-bf0c-535a59b96561 Release Notes: - Fix cursor style not changing on hover over items in the title bar on Windows
This commit is contained in:
parent
dd75f85ecf
commit
71a0eb3b13
1 changed files with 34 additions and 0 deletions
|
@ -47,6 +47,7 @@ pub(crate) fn handle_msg(
|
||||||
WM_MOUSEMOVE => handle_mouse_move_msg(handle, lparam, wparam, state_ptr),
|
WM_MOUSEMOVE => handle_mouse_move_msg(handle, lparam, wparam, state_ptr),
|
||||||
WM_MOUSELEAVE => handle_mouse_leave_msg(state_ptr),
|
WM_MOUSELEAVE => handle_mouse_leave_msg(state_ptr),
|
||||||
WM_NCMOUSEMOVE => handle_nc_mouse_move_msg(handle, lparam, state_ptr),
|
WM_NCMOUSEMOVE => handle_nc_mouse_move_msg(handle, lparam, state_ptr),
|
||||||
|
WM_NCMOUSELEAVE => handle_nc_mouse_leave_msg(state_ptr),
|
||||||
WM_NCLBUTTONDOWN => {
|
WM_NCLBUTTONDOWN => {
|
||||||
handle_nc_mouse_down_msg(handle, MouseButton::Left, wparam, lparam, state_ptr)
|
handle_nc_mouse_down_msg(handle, MouseButton::Left, wparam, lparam, state_ptr)
|
||||||
}
|
}
|
||||||
|
@ -314,6 +315,18 @@ fn handle_mouse_move_msg(
|
||||||
Some(1)
|
Some(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_nc_mouse_leave_msg(state_ptr: Rc<WindowsWindowStatePtr>) -> Option<isize> {
|
||||||
|
let mut lock = state_ptr.state.borrow_mut();
|
||||||
|
lock.hovered = false;
|
||||||
|
if let Some(mut callback) = lock.callbacks.hovered_status_change.take() {
|
||||||
|
drop(lock);
|
||||||
|
callback(false);
|
||||||
|
state_ptr.state.borrow_mut().callbacks.hovered_status_change = Some(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(0)
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_mouse_leave_msg(state_ptr: Rc<WindowsWindowStatePtr>) -> Option<isize> {
|
fn handle_mouse_leave_msg(state_ptr: Rc<WindowsWindowStatePtr>) -> Option<isize> {
|
||||||
let mut lock = state_ptr.state.borrow_mut();
|
let mut lock = state_ptr.state.borrow_mut();
|
||||||
lock.hovered = false;
|
lock.hovered = false;
|
||||||
|
@ -971,6 +984,27 @@ fn handle_nc_mouse_move_msg(
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut lock = state_ptr.state.borrow_mut();
|
||||||
|
if !lock.hovered {
|
||||||
|
lock.hovered = true;
|
||||||
|
unsafe {
|
||||||
|
TrackMouseEvent(&mut TRACKMOUSEEVENT {
|
||||||
|
cbSize: std::mem::size_of::<TRACKMOUSEEVENT>() as u32,
|
||||||
|
dwFlags: TME_LEAVE | TME_NONCLIENT,
|
||||||
|
hwndTrack: handle,
|
||||||
|
dwHoverTime: HOVER_DEFAULT,
|
||||||
|
})
|
||||||
|
.log_err()
|
||||||
|
};
|
||||||
|
if let Some(mut callback) = lock.callbacks.hovered_status_change.take() {
|
||||||
|
drop(lock);
|
||||||
|
callback(true);
|
||||||
|
state_ptr.state.borrow_mut().callbacks.hovered_status_change = Some(callback);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
drop(lock);
|
||||||
|
}
|
||||||
|
|
||||||
let mut lock = state_ptr.state.borrow_mut();
|
let mut lock = state_ptr.state.borrow_mut();
|
||||||
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 scale_factor = lock.scale_factor;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue