diff --git a/.changes/support-open-file.md b/.changes/support-open-file.md index 9f6eac0d9..72039d652 100644 --- a/.changes/support-open-file.md +++ b/.changes/support-open-file.md @@ -2,4 +2,4 @@ "tao": minor --- -Support OpenFile on macOS. +Support OpenURLs on macOS. diff --git a/src/event.rs b/src/event.rs index 8b0834a17..5d19c4a2d 100644 --- a/src/event.rs +++ b/src/event.rs @@ -105,7 +105,7 @@ pub enum Event<'a, T: 'static> { /// ## Platform-specific /// /// - **Windows / Android / Linux:** Unsupported. - OpenFile(PathBuf), + OpenURLs(Vec), /// Emitted when a global shortcut is triggered. /// @@ -210,7 +210,7 @@ impl Clone for Event<'static, T> { position: *position, }, GlobalShortcutEvent(accelerator_id) => GlobalShortcutEvent(*accelerator_id), - OpenFile(file_path) => OpenFile(file_path.clone()), + OpenURLs(urls) => OpenURLs(urls.clone()), } } } @@ -248,7 +248,7 @@ impl<'a, T> Event<'a, T> { position, }), GlobalShortcutEvent(accelerator_id) => Ok(GlobalShortcutEvent(accelerator_id)), - OpenFile(file_path) => Ok(OpenFile(file_path)), + OpenURLs(urls) => Ok(OpenURLs(urls)), } } @@ -288,7 +288,7 @@ impl<'a, T> Event<'a, T> { position, }), GlobalShortcutEvent(accelerator_id) => Some(GlobalShortcutEvent(accelerator_id)), - OpenFile(file_path) => Some(OpenFile(file_path)), + OpenURLs(urls) => Some(OpenURLs(urls)), } } } diff --git a/src/platform_impl/macos/app_delegate.rs b/src/platform_impl/macos/app_delegate.rs index 7b9bbe509..e0b325ed1 100644 --- a/src/platform_impl/macos/app_delegate.rs +++ b/src/platform_impl/macos/app_delegate.rs @@ -4,8 +4,8 @@ use crate::{platform::macos::ActivationPolicy, platform_impl::platform::app_state::AppState}; use cocoa::{ - base::{id, YES, BOOL}, - foundation::NSString, + base::id, + foundation::{NSArray, NSString, NSURL}, }; use objc::{ declare::ClassDecl, @@ -15,7 +15,6 @@ use std::{ cell::{RefCell, RefMut}, ffi::CStr, os::raw::c_void, - path::PathBuf, }; static AUX_DELEGATE_STATE_NAME: &str = "auxState"; @@ -50,8 +49,8 @@ lazy_static! { application_will_terminate as extern "C" fn(&Object, Sel, id), ); decl.add_method( - sel!(application:openFile:), - application_open_file as extern "C" fn(&Object, Sel, id, id) -> BOOL, + sel!(application:openURLs:), + application_open_urls as extern "C" fn(&Object, Sel, id, id), ); decl.add_ivar::<*mut c_void>(AUX_DELEGATE_STATE_NAME); @@ -102,16 +101,19 @@ extern "C" fn application_will_terminate(_: &Object, _: Sel, _: id) { trace!("Completed `applicationWillTerminate`"); } -extern "C" fn application_open_file(_: &Object, _: Sel, _: id, file: id) -> BOOL { - let path_string = unsafe { CStr::from_ptr(file.UTF8String()).to_string_lossy() }; - - let path = PathBuf::from(path_string.as_ref()); - trace!("Trigger `application:openFile:` with path: {}", path_string); - AppState::open_file(path); - trace!( - "Completed `application:openFile:` with path: {}", - &path_string - ); - - return YES; +extern "C" fn application_open_urls(_: &Object, _: Sel, _: id, urls: id) -> () { + trace!("Trigger `application:openURLs:`"); + + let url_strings = unsafe { + (0..urls.count()) + .map(|i| { + CStr::from_ptr(urls.objectAtIndex(i).absoluteString().UTF8String()) + .to_string_lossy() + .into_owned() + }) + .collect::>() + }; + trace!("Get `application:openURLs:` URLs: {:?}", url_strings); + AppState::open_urls(url_strings); + trace!("Completed `application:openURLs:`"); } diff --git a/src/platform_impl/macos/app_state.rs b/src/platform_impl/macos/app_state.rs index 0080917c1..b3c05e73a 100644 --- a/src/platform_impl/macos/app_state.rs +++ b/src/platform_impl/macos/app_state.rs @@ -7,7 +7,6 @@ use std::{ fmt::{self, Debug}, hint::unreachable_unchecked, mem, - path::PathBuf, rc::{Rc, Weak}, sync::{ atomic::{AtomicBool, Ordering}, @@ -298,8 +297,8 @@ impl AppState { HANDLER.set_in_callback(false); } - pub fn open_file(path: PathBuf) { - HANDLER.handle_nonuser_event(EventWrapper::StaticEvent(Event::OpenFile(path))); + pub fn open_urls(urls: Vec) { + HANDLER.handle_nonuser_event(EventWrapper::StaticEvent(Event::OpenURLs(urls))); } pub fn wakeup(panic_info: Weak) {