windows: Use drop target helper (#33203)

It now utilises the
[`IDropTargetHelper`](https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/nn-shobjidl_core-idroptargethelper)
in drag and drop events to render the proper item drop cursor icon which
includes the thumbnail when available and action text. Also swaps the
drop effect from `DROPEFFECT_LINK` to `DROPEFFECT_COPY` to match other
Windows application behaviour.

Example of drop icon

![example_drop](https://github.com/user-attachments/assets/4f8ea86c-929a-4813-9f8e-b3553ecf4d6e)

Release Notes:

- N/A

---------

Co-authored-by: 张小白 <364772080@qq.com>
This commit is contained in:
Matin Aniss 2025-06-23 23:30:21 +10:00 committed by GitHub
parent 1a6c1b2159
commit a067c16c82
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 37 additions and 5 deletions

View file

@ -42,6 +42,7 @@ pub(crate) struct WindowsPlatform {
text_system: Arc<DirectWriteTextSystem>,
windows_version: WindowsVersion,
bitmap_factory: ManuallyDrop<IWICImagingFactory>,
drop_target_helper: IDropTargetHelper,
validation_number: usize,
main_thread_id_win32: u32,
}
@ -103,6 +104,10 @@ impl WindowsPlatform {
DirectWriteTextSystem::new(&bitmap_factory)
.context("Error creating DirectWriteTextSystem")?,
);
let drop_target_helper: IDropTargetHelper = unsafe {
CoCreateInstance(&CLSID_DragDropHelper, None, CLSCTX_INPROC_SERVER)
.context("Error creating drop target helper.")?
};
let icon = load_icon().unwrap_or_default();
let state = RefCell::new(WindowsPlatformState::new());
let raw_window_handles = RwLock::new(SmallVec::new());
@ -120,6 +125,7 @@ impl WindowsPlatform {
text_system,
windows_version,
bitmap_factory,
drop_target_helper,
validation_number,
main_thread_id_win32,
})
@ -177,6 +183,7 @@ impl WindowsPlatform {
executor: self.foreground_executor.clone(),
current_cursor: self.state.borrow().current_cursor,
windows_version: self.windows_version,
drop_target_helper: self.drop_target_helper.clone(),
validation_number: self.validation_number,
main_receiver: self.main_receiver.clone(),
main_thread_id_win32: self.main_thread_id_win32,
@ -728,6 +735,7 @@ pub(crate) struct WindowCreationInfo {
pub(crate) executor: ForegroundExecutor,
pub(crate) current_cursor: Option<HCURSOR>,
pub(crate) windows_version: WindowsVersion,
pub(crate) drop_target_helper: IDropTargetHelper,
pub(crate) validation_number: usize,
pub(crate) main_receiver: flume::Receiver<Runnable>,
pub(crate) main_thread_id_win32: u32,