Clean up ownership around WindowState and DropTarget
- WindowState no longer holds a reference to DropTarget - DropTarget is passed to RegisterDragDrop() with Rc::into_raw() instead of Rc::as_ptr() so it keeps the reference - WindowState is created with Rc instead of Box so DropTarget can hold a Rc to it
This commit is contained in:
parent
eb3a02115a
commit
481bf73293
|
@ -160,7 +160,7 @@ unsafe extern "system" fn wnd_proc(
|
||||||
if msg == WM_NCDESTROY {
|
if msg == WM_NCDESTROY {
|
||||||
unregister_wnd_class((*window_state_ptr).window_class);
|
unregister_wnd_class((*window_state_ptr).window_class);
|
||||||
SetWindowLongPtrW(hwnd, GWLP_USERDATA, 0);
|
SetWindowLongPtrW(hwnd, GWLP_USERDATA, 0);
|
||||||
drop(Box::from_raw(window_state_ptr));
|
drop(Rc::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
|
||||||
|
@ -471,7 +471,6 @@ struct WindowState {
|
||||||
handler: RefCell<Option<Box<dyn WindowHandler>>>,
|
handler: RefCell<Option<Box<dyn WindowHandler>>>,
|
||||||
scale_policy: WindowScalePolicy,
|
scale_policy: WindowScalePolicy,
|
||||||
dw_style: u32,
|
dw_style: u32,
|
||||||
_drop_target: Option<Rc<DropTarget>>,
|
|
||||||
|
|
||||||
/// Tasks that should be executed at the end of `wnd_proc`. This is needed to avoid mutably
|
/// Tasks that should be executed at the end of `wnd_proc`. This is needed to avoid mutably
|
||||||
/// borrowing the fields from `WindowState` more than once. For instance, when the window
|
/// borrowing the fields from `WindowState` more than once. For instance, when the window
|
||||||
|
@ -666,7 +665,7 @@ impl Window<'_> {
|
||||||
let (parent_handle, window_handle) = ParentHandle::new(hwnd);
|
let (parent_handle, window_handle) = ParentHandle::new(hwnd);
|
||||||
let parent_handle = if parented { Some(parent_handle) } else { None };
|
let parent_handle = if parented { Some(parent_handle) } else { None };
|
||||||
|
|
||||||
let window_state = Box::new(WindowState {
|
let window_state = Rc::new(WindowState {
|
||||||
hwnd,
|
hwnd,
|
||||||
window_class,
|
window_class,
|
||||||
window_info: RefCell::new(window_info),
|
window_info: RefCell::new(window_info),
|
||||||
|
@ -678,7 +677,6 @@ impl Window<'_> {
|
||||||
handler: RefCell::new(None),
|
handler: RefCell::new(None),
|
||||||
scale_policy: options.scale,
|
scale_policy: options.scale,
|
||||||
dw_style: flags,
|
dw_style: flags,
|
||||||
_drop_target: None,
|
|
||||||
|
|
||||||
deferred_tasks: RefCell::new(VecDeque::with_capacity(4)),
|
deferred_tasks: RefCell::new(VecDeque::with_capacity(4)),
|
||||||
|
|
||||||
|
@ -724,15 +722,12 @@ impl Window<'_> {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let window_state_ptr = Box::into_raw(window_state);
|
let drop_target = Rc::new(DropTarget::new(window_state.clone()));
|
||||||
let drop_target = Rc::new(DropTarget::new(window_state_ptr));
|
|
||||||
|
|
||||||
OleInitialize(null_mut());
|
OleInitialize(null_mut());
|
||||||
RegisterDragDrop(hwnd, Rc::as_ptr(&drop_target) as LPDROPTARGET);
|
RegisterDragDrop(hwnd, Rc::into_raw(drop_target) as LPDROPTARGET);
|
||||||
|
|
||||||
(*window_state_ptr)._drop_target = Some(drop_target);
|
SetWindowLongPtrW(hwnd, GWLP_USERDATA, Rc::into_raw(window_state) as *const _ as _);
|
||||||
|
|
||||||
SetWindowLongPtrW(hwnd, GWLP_USERDATA, window_state_ptr as *const _ as _);
|
|
||||||
SetTimer(hwnd, WIN_FRAME_TIMER, 15, None);
|
SetTimer(hwnd, WIN_FRAME_TIMER, 15, None);
|
||||||
|
|
||||||
if let Some(mut new_rect) = new_rect {
|
if let Some(mut new_rect) = new_rect {
|
||||||
|
@ -789,18 +784,6 @@ pub fn copy_to_clipboard(data: &str) {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct DropTarget {
|
|
||||||
base: IDropTarget,
|
|
||||||
|
|
||||||
window_state: *mut WindowState,
|
|
||||||
|
|
||||||
// These are cached since DragOver and DragLeave callbacks don't provide them,
|
|
||||||
// and handling drag move events gets awkward on the client end otherwise
|
|
||||||
drag_position: Point,
|
|
||||||
drop_data: DropData,
|
|
||||||
}
|
|
||||||
|
|
||||||
// These function pointers have to be stored in a (const) variable before they can be transmuted
|
// These function pointers have to be stored in a (const) variable before they can be transmuted
|
||||||
const DRAG_ENTER_PTR: unsafe extern "system" fn(this: *mut IDropTarget, pDataObj: *const IDataObject, grfKeyState: DWORD, pt: POINTL, pdwEffect: *mut DWORD) -> HRESULT = DropTarget::drag_enter;
|
const DRAG_ENTER_PTR: unsafe extern "system" fn(this: *mut IDropTarget, pDataObj: *const IDataObject, grfKeyState: DWORD, pt: POINTL, pdwEffect: *mut DWORD) -> HRESULT = DropTarget::drag_enter;
|
||||||
const DRAG_OVER_PTR: unsafe extern "system" fn(this: *mut IDropTarget, grfKeyState: DWORD, pt: POINTL, pdwEffect: *mut DWORD) -> HRESULT = DropTarget::drag_over;
|
const DRAG_OVER_PTR: unsafe extern "system" fn(this: *mut IDropTarget, grfKeyState: DWORD, pt: POINTL, pdwEffect: *mut DWORD) -> HRESULT = DropTarget::drag_over;
|
||||||
|
@ -817,8 +800,20 @@ const DROP_TARGET_VTBL: IDropTargetVtbl = IDropTargetVtbl {
|
||||||
Drop: unsafe { transmute(DROP_PTR) },
|
Drop: unsafe { transmute(DROP_PTR) },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct DropTarget {
|
||||||
|
base: IDropTarget,
|
||||||
|
|
||||||
|
window_state: Rc<WindowState>,
|
||||||
|
|
||||||
|
// These are cached since DragOver and DragLeave callbacks don't provide them,
|
||||||
|
// and handling drag move events gets awkward on the client end otherwise
|
||||||
|
drag_position: Point,
|
||||||
|
drop_data: DropData,
|
||||||
|
}
|
||||||
|
|
||||||
impl DropTarget {
|
impl DropTarget {
|
||||||
fn new(window_state: *mut WindowState) -> Self {
|
fn new(window_state: Rc<WindowState>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
base: IDropTarget { lpVtbl: &DROP_TARGET_VTBL },
|
base: IDropTarget { lpVtbl: &DROP_TARGET_VTBL },
|
||||||
|
|
||||||
|
@ -948,17 +943,14 @@ impl DropTarget {
|
||||||
) -> HRESULT
|
) -> HRESULT
|
||||||
{
|
{
|
||||||
let drop_target = &mut *(this as *mut DropTarget);
|
let drop_target = &mut *(this as *mut DropTarget);
|
||||||
let window_state = unsafe { &*drop_target.window_state };
|
let modifiers = drop_target.window_state.keyboard_state.borrow().get_modifiers_from_mouse_wparam(grfKeyState as WPARAM);
|
||||||
|
|
||||||
drop_target.parse_coordinates(pt);
|
drop_target.parse_coordinates(pt);
|
||||||
drop_target.parse_drop_data(&*pDataObj);
|
drop_target.parse_drop_data(&*pDataObj);
|
||||||
|
|
||||||
let event = MouseEvent::DragEntered {
|
let event = MouseEvent::DragEntered {
|
||||||
position: drop_target.drag_position,
|
position: drop_target.drag_position,
|
||||||
modifiers: window_state
|
modifiers,
|
||||||
.keyboard_state
|
|
||||||
.borrow()
|
|
||||||
.get_modifiers_from_mouse_wparam(grfKeyState as WPARAM),
|
|
||||||
data: drop_target.drop_data.clone(),
|
data: drop_target.drop_data.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -974,16 +966,13 @@ impl DropTarget {
|
||||||
) -> HRESULT
|
) -> HRESULT
|
||||||
{
|
{
|
||||||
let drop_target = &mut *(this as *mut DropTarget);
|
let drop_target = &mut *(this as *mut DropTarget);
|
||||||
let window_state = unsafe { &*drop_target.window_state };
|
let modifiers = drop_target.window_state.keyboard_state.borrow().get_modifiers_from_mouse_wparam(grfKeyState as WPARAM);
|
||||||
|
|
||||||
drop_target.parse_coordinates(pt);
|
drop_target.parse_coordinates(pt);
|
||||||
|
|
||||||
let event = MouseEvent::DragMoved {
|
let event = MouseEvent::DragMoved {
|
||||||
position: drop_target.drag_position,
|
position: drop_target.drag_position,
|
||||||
modifiers: window_state
|
modifiers,
|
||||||
.keyboard_state
|
|
||||||
.borrow()
|
|
||||||
.get_modifiers_from_mouse_wparam(grfKeyState as WPARAM),
|
|
||||||
data: drop_target.drop_data.clone(),
|
data: drop_target.drop_data.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1006,17 +995,14 @@ impl DropTarget {
|
||||||
) -> HRESULT
|
) -> HRESULT
|
||||||
{
|
{
|
||||||
let drop_target = &mut *(this as *mut DropTarget);
|
let drop_target = &mut *(this as *mut DropTarget);
|
||||||
let window_state = unsafe { &*drop_target.window_state };
|
let modifiers = drop_target.window_state.keyboard_state.borrow().get_modifiers_from_mouse_wparam(grfKeyState as WPARAM);
|
||||||
|
|
||||||
drop_target.parse_coordinates(pt);
|
drop_target.parse_coordinates(pt);
|
||||||
drop_target.parse_drop_data(&*pDataObj);
|
drop_target.parse_drop_data(&*pDataObj);
|
||||||
|
|
||||||
let event = MouseEvent::DragDropped {
|
let event = MouseEvent::DragDropped {
|
||||||
position: drop_target.drag_position,
|
position: drop_target.drag_position,
|
||||||
modifiers: window_state
|
modifiers,
|
||||||
.keyboard_state
|
|
||||||
.borrow()
|
|
||||||
.get_modifiers_from_mouse_wparam(grfKeyState as WPARAM),
|
|
||||||
data: drop_target.drop_data.clone(),
|
data: drop_target.drop_data.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue