use super::*;
use windows::Win32::Foundation::POINTL;
use windows::Win32::System::Com::IDataObject;
use windows::Win32::System::Ole::{
DROPEFFECT, IDropTarget, IDropTarget_Impl, RegisterDragDrop, RevokeDragDrop,
};
use windows::Win32::System::SystemServices::MODIFIERKEYS_FLAGS;
use windows::core::{Ref, implement};
#[implement(IDropTarget)]
struct SurfaceDropTarget {
hwnd: HWND,
controller: ICoreWebView2CompositionController3,
}
impl SurfaceDropTarget {
fn client_point(&self, pt: &POINTL) -> windows::Win32::Foundation::POINT {
let mut point = windows::Win32::Foundation::POINT { x: pt.x, y: pt.y };
unsafe {
let _ = windows::Win32::Graphics::Gdi::ScreenToClient(self.hwnd, &mut point);
}
point
}
}
impl IDropTarget_Impl for SurfaceDropTarget_Impl {
fn DragEnter(
&self,
pdataobj: Ref<IDataObject>,
grfkeystate: MODIFIERKEYS_FLAGS,
pt: &POINTL,
pdweffect: *mut DROPEFFECT,
) -> WinResult<()> {
unsafe {
self.controller.DragEnter(
pdataobj.as_ref(),
grfkeystate.0,
self.client_point(pt),
pdweffect as *mut u32,
)
}
}
fn DragOver(
&self,
grfkeystate: MODIFIERKEYS_FLAGS,
pt: &POINTL,
pdweffect: *mut DROPEFFECT,
) -> WinResult<()> {
unsafe {
self.controller
.DragOver(grfkeystate.0, self.client_point(pt), pdweffect as *mut u32)
}
}
fn DragLeave(&self) -> WinResult<()> {
unsafe { self.controller.DragLeave() }
}
fn Drop(
&self,
pdataobj: Ref<IDataObject>,
grfkeystate: MODIFIERKEYS_FLAGS,
pt: &POINTL,
pdweffect: *mut DROPEFFECT,
) -> WinResult<()> {
unsafe {
self.controller.Drop(
pdataobj.as_ref(),
grfkeystate.0,
self.client_point(pt),
pdweffect as *mut u32,
)
}
}
}
pub(crate) fn register_drop_target(hwnd: HWND, controller: &ICoreWebView2CompositionController) {
let controller3: ICoreWebView2CompositionController3 = match controller.cast() {
Ok(controller3) => controller3,
Err(err) => {
log::warn!("drag-drop unavailable (no CompositionController3): {err}");
return;
}
};
let target: IDropTarget = SurfaceDropTarget {
hwnd,
controller: controller3,
}
.into();
unsafe {
if let Err(err) = RegisterDragDrop(hwnd, &target) {
log::warn!("RegisterDragDrop failed: {err}");
}
}
}
pub(crate) fn revoke_drop_target(hwnd: HWND) {
unsafe {
let _ = RevokeDragDrop(hwnd);
}
}