diff --git a/crates/gpui/src/platform/windows/events.rs b/crates/gpui/src/platform/windows/events.rs index f5313a39b07fd4c307c275b84227c141a4ea4e52..efaf7a148acef67849482cfb05b33042b08678fa 100644 --- a/crates/gpui/src/platform/windows/events.rs +++ b/crates/gpui/src/platform/windows/events.rs @@ -47,6 +47,7 @@ pub(crate) fn handle_msg( WM_MOUSEMOVE => handle_mouse_move_msg(handle, lparam, wparam, state_ptr), WM_MOUSELEAVE => handle_mouse_leave_msg(state_ptr), WM_NCMOUSEMOVE => handle_nc_mouse_move_msg(handle, lparam, state_ptr), + WM_NCMOUSELEAVE => handle_nc_mouse_leave_msg(state_ptr), WM_NCLBUTTONDOWN => { handle_nc_mouse_down_msg(handle, MouseButton::Left, wparam, lparam, state_ptr) } @@ -314,6 +315,18 @@ fn handle_mouse_move_msg( Some(1) } +fn handle_nc_mouse_leave_msg(state_ptr: Rc) -> Option { + 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) -> Option { let mut lock = state_ptr.state.borrow_mut(); lock.hovered = false; @@ -971,6 +984,27 @@ fn handle_nc_mouse_move_msg( 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::() 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(); if let Some(mut callback) = lock.callbacks.input.take() { let scale_factor = lock.scale_factor;