Walk back the previous restructuring a bit
We were leaking the DropTarget, so WindowState holds a reference to DropTarget again, so it can be dropped when the window is destroyed. Also, DropTarget now holds a Weak reference to WindowState and that's taken into account in callbacks.
This commit is contained in:
parent
9028321012
commit
b33398703f
|
@ -3,11 +3,10 @@ use winapi::shared::guiddef::{GUID, REFIID, IsEqualIID};
|
||||||
use winapi::shared::minwindef::{ATOM, FALSE, LPARAM, LRESULT, UINT, WPARAM, DWORD};
|
use winapi::shared::minwindef::{ATOM, FALSE, LPARAM, LRESULT, UINT, WPARAM, DWORD};
|
||||||
use winapi::shared::ntdef::{HRESULT, ULONG};
|
use winapi::shared::ntdef::{HRESULT, ULONG};
|
||||||
use winapi::shared::windef::{HWND, RECT, POINTL};
|
use winapi::shared::windef::{HWND, RECT, POINTL};
|
||||||
use winapi::shared::winerror::{S_OK, E_NOINTERFACE};
|
use winapi::shared::winerror::{S_OK, E_NOINTERFACE, E_UNEXPECTED};
|
||||||
use winapi::shared::wtypes::DVASPECT_CONTENT;
|
use winapi::shared::wtypes::DVASPECT_CONTENT;
|
||||||
use winapi::um::combaseapi::CoCreateGuid;
|
use winapi::um::combaseapi::CoCreateGuid;
|
||||||
use winapi::um::objidl::{IDataObject, STGMEDIUM, FORMATETC, TYMED_HGLOBAL};
|
use winapi::um::objidl::{IDataObject, STGMEDIUM, FORMATETC, TYMED_HGLOBAL};
|
||||||
use winapi::um::ole2::{RegisterDragDrop, OleInitialize};
|
|
||||||
use winapi::um::ole2::{RegisterDragDrop, OleInitialize, RevokeDragDrop};
|
use winapi::um::ole2::{RegisterDragDrop, OleInitialize, RevokeDragDrop};
|
||||||
use winapi::um::oleidl::{IDropTarget, IDropTargetVtbl, LPDROPTARGET, DROPEFFECT_COPY, DROPEFFECT_NONE, DROPEFFECT_MOVE, DROPEFFECT_LINK, DROPEFFECT_SCROLL};
|
use winapi::um::oleidl::{IDropTarget, IDropTargetVtbl, LPDROPTARGET, DROPEFFECT_COPY, DROPEFFECT_NONE, DROPEFFECT_MOVE, DROPEFFECT_LINK, DROPEFFECT_SCROLL};
|
||||||
use winapi::um::shellapi::DragQueryFileW;
|
use winapi::um::shellapi::DragQueryFileW;
|
||||||
|
@ -34,7 +33,7 @@ use std::mem::transmute;
|
||||||
use std::os::windows::ffi::OsStrExt;
|
use std::os::windows::ffi::OsStrExt;
|
||||||
use std::os::windows::prelude::OsStringExt;
|
use std::os::windows::prelude::OsStringExt;
|
||||||
use std::ptr::null_mut;
|
use std::ptr::null_mut;
|
||||||
use std::rc::Rc;
|
use std::rc::{Rc, Weak};
|
||||||
|
|
||||||
use raw_window_handle::{HasRawWindowHandle, RawWindowHandle, Win32Handle};
|
use raw_window_handle::{HasRawWindowHandle, RawWindowHandle, Win32Handle};
|
||||||
|
|
||||||
|
@ -471,6 +470,7 @@ struct WindowState {
|
||||||
mouse_button_counter: Cell<usize>,
|
mouse_button_counter: Cell<usize>,
|
||||||
// Initialized late so the `Window` can hold a reference to this `WindowState`
|
// Initialized late so the `Window` can hold a reference to this `WindowState`
|
||||||
handler: RefCell<Option<Box<dyn WindowHandler>>>,
|
handler: RefCell<Option<Box<dyn WindowHandler>>>,
|
||||||
|
_drop_target: RefCell<Option<Rc<DropTarget>>>,
|
||||||
scale_policy: WindowScalePolicy,
|
scale_policy: WindowScalePolicy,
|
||||||
dw_style: u32,
|
dw_style: u32,
|
||||||
|
|
||||||
|
@ -677,6 +677,7 @@ impl Window<'_> {
|
||||||
// The Window refers to this `WindowState`, so this `handler` needs to be
|
// The Window refers to this `WindowState`, so this `handler` needs to be
|
||||||
// initialized later
|
// initialized later
|
||||||
handler: RefCell::new(None),
|
handler: RefCell::new(None),
|
||||||
|
_drop_target: RefCell::new(None),
|
||||||
scale_policy: options.scale,
|
scale_policy: options.scale,
|
||||||
dw_style: flags,
|
dw_style: flags,
|
||||||
|
|
||||||
|
@ -724,10 +725,11 @@ impl Window<'_> {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let drop_target = Rc::new(DropTarget::new(window_state.clone()));
|
let drop_target = Rc::new(DropTarget::new(Rc::downgrade(&window_state)));
|
||||||
|
*window_state._drop_target.borrow_mut() = Some(drop_target.clone());
|
||||||
|
|
||||||
OleInitialize(null_mut());
|
OleInitialize(null_mut());
|
||||||
RegisterDragDrop(hwnd, Rc::into_raw(drop_target) as LPDROPTARGET);
|
RegisterDragDrop(hwnd, Rc::as_ptr(&drop_target) as LPDROPTARGET);
|
||||||
|
|
||||||
SetWindowLongPtrW(hwnd, GWLP_USERDATA, Rc::into_raw(window_state) as *const _ as _);
|
SetWindowLongPtrW(hwnd, GWLP_USERDATA, Rc::into_raw(window_state) as *const _ as _);
|
||||||
SetTimer(hwnd, WIN_FRAME_TIMER, 15, None);
|
SetTimer(hwnd, WIN_FRAME_TIMER, 15, None);
|
||||||
|
@ -806,7 +808,7 @@ const DROP_TARGET_VTBL: IDropTargetVtbl = IDropTargetVtbl {
|
||||||
pub struct DropTarget {
|
pub struct DropTarget {
|
||||||
base: IDropTarget,
|
base: IDropTarget,
|
||||||
|
|
||||||
window_state: Rc<WindowState>,
|
window_state: Weak<WindowState>,
|
||||||
|
|
||||||
// These are cached since DragOver and DragLeave callbacks don't provide them,
|
// These are cached since DragOver and DragLeave callbacks don't provide them,
|
||||||
// and handling drag move events gets awkward on the client end otherwise
|
// and handling drag move events gets awkward on the client end otherwise
|
||||||
|
@ -815,7 +817,7 @@ pub struct DropTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DropTarget {
|
impl DropTarget {
|
||||||
fn new(window_state: Rc<WindowState>) -> Self {
|
fn new(window_state: Weak<WindowState>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
base: IDropTarget { lpVtbl: &DROP_TARGET_VTBL },
|
base: IDropTarget { lpVtbl: &DROP_TARGET_VTBL },
|
||||||
|
|
||||||
|
@ -827,8 +829,11 @@ impl DropTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_event(&self, pdwEffect: Option<*mut DWORD>, event: MouseEvent) {
|
fn on_event(&self, pdwEffect: Option<*mut DWORD>, event: MouseEvent) {
|
||||||
|
let Some(window_state) = self.window_state.upgrade() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let window_state = &*self.window_state;
|
|
||||||
let mut window = window_state.create_window();
|
let mut window = window_state.create_window();
|
||||||
let mut window = crate::Window::new(&mut window);
|
let mut window = crate::Window::new(&mut window);
|
||||||
|
|
||||||
|
@ -848,10 +853,12 @@ impl DropTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_coordinates(&mut self, pt: POINTL) {
|
fn parse_coordinates(&mut self, pt: POINTL) {
|
||||||
let window_state = unsafe { &*self.window_state };
|
let Some(window_state) = self.window_state.upgrade() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
let phy_point = PhyPoint::new(pt.x, pt.y);
|
let phy_point = PhyPoint::new(pt.x, pt.y);
|
||||||
self.drag_position = phy_point.to_logical(&window_state.window_info.borrow())
|
self.drag_position = phy_point.to_logical(&window_state.window_info.borrow());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_drop_data(&mut self, data_object: &IDataObject) {
|
fn parse_drop_data(&mut self, data_object: &IDataObject) {
|
||||||
|
@ -945,7 +952,11 @@ impl DropTarget {
|
||||||
) -> HRESULT
|
) -> HRESULT
|
||||||
{
|
{
|
||||||
let drop_target = &mut *(this as *mut DropTarget);
|
let drop_target = &mut *(this as *mut DropTarget);
|
||||||
let modifiers = drop_target.window_state.keyboard_state.borrow().get_modifiers_from_mouse_wparam(grfKeyState as WPARAM);
|
let Some(window_state) = drop_target.window_state.upgrade() else {
|
||||||
|
return E_UNEXPECTED;
|
||||||
|
};
|
||||||
|
|
||||||
|
let modifiers = 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);
|
||||||
|
@ -968,7 +979,11 @@ impl DropTarget {
|
||||||
) -> HRESULT
|
) -> HRESULT
|
||||||
{
|
{
|
||||||
let drop_target = &mut *(this as *mut DropTarget);
|
let drop_target = &mut *(this as *mut DropTarget);
|
||||||
let modifiers = drop_target.window_state.keyboard_state.borrow().get_modifiers_from_mouse_wparam(grfKeyState as WPARAM);
|
let Some(window_state) = drop_target.window_state.upgrade() else {
|
||||||
|
return E_UNEXPECTED;
|
||||||
|
};
|
||||||
|
|
||||||
|
let modifiers = window_state.keyboard_state.borrow().get_modifiers_from_mouse_wparam(grfKeyState as WPARAM);
|
||||||
|
|
||||||
drop_target.parse_coordinates(pt);
|
drop_target.parse_coordinates(pt);
|
||||||
|
|
||||||
|
@ -997,7 +1012,11 @@ impl DropTarget {
|
||||||
) -> HRESULT
|
) -> HRESULT
|
||||||
{
|
{
|
||||||
let drop_target = &mut *(this as *mut DropTarget);
|
let drop_target = &mut *(this as *mut DropTarget);
|
||||||
let modifiers = drop_target.window_state.keyboard_state.borrow().get_modifiers_from_mouse_wparam(grfKeyState as WPARAM);
|
let Some(window_state) = drop_target.window_state.upgrade() else {
|
||||||
|
return E_UNEXPECTED;
|
||||||
|
};
|
||||||
|
|
||||||
|
let modifiers = 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);
|
||||||
|
|
Loading…
Reference in a new issue