mirror of https://github.com/tauri-apps/tauri
parent
c40f640ddc
commit
07d1584cf0
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
"tauri-runtime": minor
|
||||
"tauri-runtime-wry": minor
|
||||
---
|
||||
|
||||
The file drop event is now part of the `WindowEvent` enum instead of a having a dedicated handler.
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"tauri-runtime": patch
|
||||
---
|
||||
|
||||
**Breaking change:** Move the `FileDropEvent` struct to the `window` module.
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
"tauri": patch
|
||||
"tauri-runtime": minor
|
||||
"tauri-runtime-wry": minor
|
||||
---
|
||||
|
||||
Added the `WindowEvent::FileDrop` variant.
|
|
@ -11,10 +11,10 @@ use tauri_runtime::{
|
|||
},
|
||||
menu::{CustomMenuItem, Menu, MenuEntry, MenuHash, MenuId, MenuItem, MenuUpdate},
|
||||
monitor::Monitor,
|
||||
webview::{FileDropEvent, FileDropHandler, WebviewIpcHandler, WindowBuilder, WindowBuilderBase},
|
||||
webview::{WebviewIpcHandler, WindowBuilder, WindowBuilderBase},
|
||||
window::{
|
||||
dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Position, Size},
|
||||
DetachedWindow, JsEventListenerKey, PendingWindow, WindowEvent,
|
||||
DetachedWindow, FileDropEvent, JsEventListenerKey, PendingWindow, WindowEvent,
|
||||
},
|
||||
ClipboardManager, Dispatch, Error, ExitRequestedEventAction, GlobalShortcutManager, Result,
|
||||
RunEvent, RunIteration, Runtime, RuntimeHandle, UserAttentionType, WindowIcon,
|
||||
|
@ -2624,7 +2624,6 @@ fn create_webview(
|
|||
uri_scheme_protocols,
|
||||
mut window_builder,
|
||||
ipc_handler,
|
||||
file_drop_handler,
|
||||
label,
|
||||
url,
|
||||
menu_ids,
|
||||
|
@ -2663,17 +2662,11 @@ fn create_webview(
|
|||
.with_url(&url)
|
||||
.unwrap() // safe to unwrap because we validate the URL beforehand
|
||||
.with_transparent(is_window_transparent);
|
||||
if webview_attributes.file_drop_handler_enabled {
|
||||
webview_builder = webview_builder.with_file_drop_handler(create_file_drop_handler(&context));
|
||||
}
|
||||
if let Some(handler) = ipc_handler {
|
||||
webview_builder = webview_builder.with_ipc_handler(create_ipc_handler(
|
||||
context.clone(),
|
||||
label.clone(),
|
||||
menu_ids.clone(),
|
||||
js_event_listeners.clone(),
|
||||
handler,
|
||||
));
|
||||
}
|
||||
if let Some(handler) = file_drop_handler {
|
||||
webview_builder = webview_builder.with_file_drop_handler(create_file_drop_handler(
|
||||
context,
|
||||
label.clone(),
|
||||
menu_ids,
|
||||
|
@ -2763,26 +2756,25 @@ fn create_ipc_handler(
|
|||
})
|
||||
}
|
||||
|
||||
/// Create a wry file drop handler from a tauri file drop handler.
|
||||
/// Create a wry file drop handler.
|
||||
fn create_file_drop_handler(
|
||||
context: Context,
|
||||
label: String,
|
||||
menu_ids: Arc<Mutex<HashMap<MenuHash, MenuId>>>,
|
||||
js_event_listeners: Arc<Mutex<HashMap<JsEventListenerKey, HashSet<u64>>>>,
|
||||
handler: FileDropHandler<Wry>,
|
||||
context: &Context,
|
||||
) -> Box<dyn Fn(&Window, WryFileDropEvent) -> bool + 'static> {
|
||||
let window_event_listeners = context.window_event_listeners.clone();
|
||||
Box::new(move |window, event| {
|
||||
handler(
|
||||
FileDropEventWrapper(event).into(),
|
||||
DetachedWindow {
|
||||
dispatcher: WryDispatcher {
|
||||
window_id: window.id(),
|
||||
context: context.clone(),
|
||||
},
|
||||
label: label.clone(),
|
||||
menu_ids: menu_ids.clone(),
|
||||
js_event_listeners: js_event_listeners.clone(),
|
||||
},
|
||||
)
|
||||
let event: FileDropEvent = FileDropEventWrapper(event).into();
|
||||
let window_event = WindowEvent::FileDrop(event);
|
||||
let listeners = window_event_listeners.lock().unwrap();
|
||||
if let Some(window_listeners) = listeners.get(&window.id()) {
|
||||
let listeners_map = window_listeners.lock().unwrap();
|
||||
let has_listener = !listeners_map.is_empty();
|
||||
for listener in listeners_map.values() {
|
||||
listener(&window_event);
|
||||
}
|
||||
// block the default OS action on file drop if we had a listener
|
||||
has_listener
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -184,21 +184,5 @@ pub trait WindowBuilder: WindowBuilderBase {
|
|||
fn get_menu(&self) -> Option<&Menu>;
|
||||
}
|
||||
|
||||
/// The file drop event payload.
|
||||
#[derive(Debug, Clone)]
|
||||
#[non_exhaustive]
|
||||
pub enum FileDropEvent {
|
||||
/// The file(s) have been dragged onto the window, but have not been dropped yet.
|
||||
Hovered(Vec<PathBuf>),
|
||||
/// The file(s) have been dropped onto the window.
|
||||
Dropped(Vec<PathBuf>),
|
||||
/// The file drop was aborted.
|
||||
Cancelled,
|
||||
}
|
||||
|
||||
/// IPC handler.
|
||||
pub type WebviewIpcHandler<R> = Box<dyn Fn(DetachedWindow<R>, String) + Send>;
|
||||
|
||||
/// File drop handler callback
|
||||
/// Return `true` in the callback to block the OS' default behavior of handling a file drop.
|
||||
pub type FileDropHandler<R> = Box<dyn Fn(FileDropEvent, DetachedWindow<R>) -> bool + Send>;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
use crate::{
|
||||
http::{Request as HttpRequest, Response as HttpResponse},
|
||||
menu::{Menu, MenuEntry, MenuHash, MenuId},
|
||||
webview::{FileDropHandler, WebviewAttributes, WebviewIpcHandler},
|
||||
webview::{WebviewAttributes, WebviewIpcHandler},
|
||||
Dispatch, Runtime, WindowBuilder,
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
@ -16,6 +16,7 @@ use tauri_utils::config::WindowConfig;
|
|||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
hash::{Hash, Hasher},
|
||||
path::PathBuf,
|
||||
sync::{mpsc::Sender, Arc, Mutex},
|
||||
};
|
||||
|
||||
|
@ -59,6 +60,20 @@ pub enum WindowEvent {
|
|||
/// The window inner size.
|
||||
new_inner_size: dpi::PhysicalSize<u32>,
|
||||
},
|
||||
/// An event associated with the file drop action.
|
||||
FileDrop(FileDropEvent),
|
||||
}
|
||||
|
||||
/// The file drop event payload.
|
||||
#[derive(Debug, Clone)]
|
||||
#[non_exhaustive]
|
||||
pub enum FileDropEvent {
|
||||
/// The file(s) have been dragged onto the window, but have not been dropped yet.
|
||||
Hovered(Vec<PathBuf>),
|
||||
/// The file(s) have been dropped onto the window.
|
||||
Dropped(Vec<PathBuf>),
|
||||
/// The file drop was aborted.
|
||||
Cancelled,
|
||||
}
|
||||
|
||||
/// A menu event.
|
||||
|
@ -96,9 +111,6 @@ pub struct PendingWindow<R: Runtime> {
|
|||
/// How to handle IPC calls on the webview window.
|
||||
pub ipc_handler: Option<WebviewIpcHandler<R>>,
|
||||
|
||||
/// How to handle a file dropping onto the webview window.
|
||||
pub file_drop_handler: Option<FileDropHandler<R>>,
|
||||
|
||||
/// The resolved URL to load on the webview.
|
||||
pub url: String,
|
||||
|
||||
|
@ -143,7 +155,6 @@ impl<R: Runtime> PendingWindow<R> {
|
|||
uri_scheme_protocols: Default::default(),
|
||||
label,
|
||||
ipc_handler: None,
|
||||
file_drop_handler: None,
|
||||
url: "tauri://localhost".to_string(),
|
||||
menu_ids: Arc::new(Mutex::new(menu_ids)),
|
||||
js_event_listeners: Default::default(),
|
||||
|
@ -172,7 +183,6 @@ impl<R: Runtime> PendingWindow<R> {
|
|||
uri_scheme_protocols: Default::default(),
|
||||
label,
|
||||
ipc_handler: None,
|
||||
file_drop_handler: None,
|
||||
url: "tauri://localhost".to_string(),
|
||||
menu_ids: Arc::new(Mutex::new(menu_ids)),
|
||||
js_event_listeners: Default::default(),
|
||||
|
|
|
@ -213,7 +213,7 @@ pub use {
|
|||
webview::{WebviewAttributes, WindowBuilder},
|
||||
window::{
|
||||
dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Pixel, Position, Size},
|
||||
WindowEvent,
|
||||
FileDropEvent, WindowEvent,
|
||||
},
|
||||
ClipboardManager, GlobalShortcutManager, RunIteration, Runtime, TrayIcon, UserAttentionType,
|
||||
},
|
||||
|
|
|
@ -39,8 +39,8 @@ use crate::{
|
|||
MimeType, Request as HttpRequest, Response as HttpResponse,
|
||||
ResponseBuilder as HttpResponseBuilder,
|
||||
},
|
||||
webview::{FileDropEvent, FileDropHandler, WebviewIpcHandler, WindowBuilder},
|
||||
window::{dpi::PhysicalSize, DetachedWindow, PendingWindow, WindowEvent},
|
||||
webview::{WebviewIpcHandler, WindowBuilder},
|
||||
window::{dpi::PhysicalSize, DetachedWindow, FileDropEvent, PendingWindow, WindowEvent},
|
||||
Runtime,
|
||||
},
|
||||
utils::{
|
||||
|
@ -838,30 +838,6 @@ impl<R: Runtime> WindowManager<R> {
|
|||
})
|
||||
}
|
||||
|
||||
fn prepare_file_drop(&self, app_handle: AppHandle<R>) -> FileDropHandler<R> {
|
||||
let manager = self.clone();
|
||||
Box::new(move |event, window| {
|
||||
let window = Window::new(manager.clone(), window, app_handle.clone());
|
||||
let _ = match event {
|
||||
FileDropEvent::Hovered(paths) => window.emit_and_trigger("tauri://file-drop-hover", paths),
|
||||
FileDropEvent::Dropped(paths) => {
|
||||
let scopes = window.state::<Scopes>();
|
||||
for path in &paths {
|
||||
if path.is_file() {
|
||||
let _ = scopes.allow_file(path);
|
||||
} else {
|
||||
let _ = scopes.allow_directory(path, false);
|
||||
}
|
||||
}
|
||||
window.emit_and_trigger("tauri://file-drop", paths)
|
||||
}
|
||||
FileDropEvent::Cancelled => window.emit_and_trigger("tauri://file-drop-cancelled", ()),
|
||||
_ => unimplemented!(),
|
||||
};
|
||||
true
|
||||
})
|
||||
}
|
||||
|
||||
fn initialization_script(
|
||||
&self,
|
||||
ipc_script: &str,
|
||||
|
@ -1082,11 +1058,7 @@ impl<R: Runtime> WindowManager<R> {
|
|||
app_handle.clone(),
|
||||
web_resource_request_handler,
|
||||
)?;
|
||||
pending.ipc_handler = Some(self.prepare_ipc_handler(app_handle.clone()));
|
||||
}
|
||||
|
||||
if pending.webview_attributes.file_drop_handler_enabled {
|
||||
pending.file_drop_handler = Some(self.prepare_file_drop(app_handle));
|
||||
pending.ipc_handler = Some(self.prepare_ipc_handler(app_handle));
|
||||
}
|
||||
|
||||
// in `Windows`, we need to force a data_directory
|
||||
|
@ -1291,6 +1263,22 @@ fn on_window_event<R: Runtime>(
|
|||
size: *new_inner_size,
|
||||
},
|
||||
)?,
|
||||
WindowEvent::FileDrop(event) => match event {
|
||||
FileDropEvent::Hovered(paths) => window.emit_and_trigger("tauri://file-drop-hover", paths)?,
|
||||
FileDropEvent::Dropped(paths) => {
|
||||
let scopes = window.state::<Scopes>();
|
||||
for path in paths {
|
||||
if path.is_file() {
|
||||
let _ = scopes.allow_file(path);
|
||||
} else {
|
||||
let _ = scopes.allow_directory(path, false);
|
||||
}
|
||||
}
|
||||
window.emit_and_trigger("tauri://file-drop", paths)?
|
||||
}
|
||||
FileDropEvent::Cancelled => window.emit_and_trigger("tauri://file-drop-cancelled", ())?,
|
||||
_ => unimplemented!(),
|
||||
},
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
Ok(())
|
||||
|
|
Loading…
Reference in New Issue