diff --git a/.changes/dnd-position.md b/.changes/dnd-position.md new file mode 100644 index 000000000..cc35c0c4e --- /dev/null +++ b/.changes/dnd-position.md @@ -0,0 +1,7 @@ +--- +'tauri': 'minor:feat' +'tauri-runtime': 'minor' +'tauri-runtime-wry': 'minor' +--- + +Changed `FileDropEvent` to include drop and hover position. diff --git a/core/tauri-runtime-wry/src/lib.rs b/core/tauri-runtime-wry/src/lib.rs index 0e48f05a7..f19c7435a 100644 --- a/core/tauri-runtime-wry/src/lib.rs +++ b/core/tauri-runtime-wry/src/lib.rs @@ -881,12 +881,14 @@ fn decode_path(path: PathBuf) -> PathBuf { impl From for FileDropEvent { fn from(event: FileDropEventWrapper) -> Self { match event.0 { - WryFileDropEvent::Hovered { paths, position: _ } => { - FileDropEvent::Hovered(paths.into_iter().map(decode_path).collect()) - } - WryFileDropEvent::Dropped { paths, position: _ } => { - FileDropEvent::Dropped(paths.into_iter().map(decode_path).collect()) - } + WryFileDropEvent::Hovered { paths, position } => FileDropEvent::Hovered { + paths: paths.into_iter().map(decode_path).collect(), + position: PhysicalPositionWrapper(position).into(), + }, + WryFileDropEvent::Dropped { paths, position } => FileDropEvent::Dropped { + paths: paths.into_iter().map(decode_path).collect(), + position: PhysicalPositionWrapper(position).into(), + }, // default to cancelled // FIXME(maybe): Add `FileDropEvent::Unknown` event? _ => FileDropEvent::Cancelled, diff --git a/core/tauri-runtime/src/window.rs b/core/tauri-runtime/src/window.rs index d2dfcb8a4..5f06b6219 100644 --- a/core/tauri-runtime/src/window.rs +++ b/core/tauri-runtime/src/window.rs @@ -22,6 +22,8 @@ use std::{ sync::mpsc::Sender, }; +use self::dpi::PhysicalPosition; + type UriSchemeProtocol = dyn Fn(&HttpRequest) -> Result> + Send + Sync + 'static; @@ -76,9 +78,17 @@ pub enum WindowEvent { #[non_exhaustive] pub enum FileDropEvent { /// The file(s) have been dragged onto the window, but have not been dropped yet. - Hovered(Vec), + Hovered { + paths: Vec, + /// The position of the mouse cursor. + position: PhysicalPosition, + }, /// The file(s) have been dropped onto the window. - Dropped(Vec), + Dropped { + paths: Vec, + /// The position of the mouse cursor. + position: PhysicalPosition, + }, /// The file drop was aborted. Cancelled, } diff --git a/core/tauri/src/manager.rs b/core/tauri/src/manager.rs index bba3a8cef..b5cccd324 100644 --- a/core/tauri/src/manager.rs +++ b/core/tauri/src/manager.rs @@ -7,6 +7,7 @@ use std::{ collections::{HashMap, HashSet}, fmt, fs::create_dir_all, + path::PathBuf, sync::{Arc, Mutex, MutexGuard}, }; @@ -38,7 +39,10 @@ use crate::{ ResponseBuilder as HttpResponseBuilder, }, webview::WindowBuilder, - window::{dpi::PhysicalSize, DetachedWindow, FileDropEvent, PendingWindow}, + window::{ + dpi::{PhysicalPosition, PhysicalSize}, + DetachedWindow, FileDropEvent, PendingWindow, + }, }, utils::{ assets::Assets, @@ -1399,6 +1403,12 @@ impl WindowManager { } } +#[derive(Serialize, Clone)] +struct FileDropPayload<'a> { + paths: &'a Vec, + position: &'a PhysicalPosition, +} + fn on_window_event( window: &Window, manager: &WindowManager, @@ -1444,8 +1454,11 @@ fn on_window_event( }, )?, WindowEvent::FileDrop(event) => match event { - FileDropEvent::Hovered(paths) => window.emit(WINDOW_FILE_DROP_HOVER_EVENT, paths)?, - FileDropEvent::Dropped(paths) => { + FileDropEvent::Hovered { paths, position } => { + let payload = FileDropPayload { paths, position }; + window.emit(WINDOW_FILE_DROP_HOVER_EVENT, payload)? + } + FileDropEvent::Dropped { paths, position } => { let scopes = window.state::(); for path in paths { if path.is_file() { @@ -1454,7 +1467,8 @@ fn on_window_event( let _ = scopes.allow_directory(path, false); } } - window.emit(WINDOW_FILE_DROP_EVENT, paths)? + let payload = FileDropPayload { paths, position }; + window.emit(WINDOW_FILE_DROP_EVENT, payload)? } FileDropEvent::Cancelled => window.emit(WINDOW_FILE_DROP_CANCELLED_EVENT, ())?, _ => unimplemented!(),