Merge branch 'main' into auto-update
This commit is contained in:
commit
fb87bacc7e
341 changed files with 21713 additions and 5967 deletions
|
@ -3,7 +3,7 @@ use crate::{
|
|||
executor,
|
||||
keymap::Keystroke,
|
||||
platform::{self, CursorStyle},
|
||||
AnyAction, ClipboardItem, Event, Menu, MenuItem,
|
||||
Action, ClipboardItem, Event, Menu, MenuItem,
|
||||
};
|
||||
use anyhow::{anyhow, Result};
|
||||
use block::ConcreteBlock;
|
||||
|
@ -38,8 +38,8 @@ use ptr::null_mut;
|
|||
use std::{
|
||||
cell::{Cell, RefCell},
|
||||
convert::TryInto,
|
||||
ffi::{c_void, CStr},
|
||||
os::raw::c_char,
|
||||
ffi::{c_void, CStr, OsStr},
|
||||
os::{raw::c_char, unix::ffi::OsStrExt},
|
||||
path::{Path, PathBuf},
|
||||
ptr,
|
||||
rc::Rc,
|
||||
|
@ -91,8 +91,8 @@ unsafe fn build_classes() {
|
|||
handle_menu_item as extern "C" fn(&mut Object, Sel, id),
|
||||
);
|
||||
decl.add_method(
|
||||
sel!(application:openFiles:),
|
||||
open_files as extern "C" fn(&mut Object, Sel, id, id),
|
||||
sel!(application:openURLs:),
|
||||
open_urls as extern "C" fn(&mut Object, Sel, id, id),
|
||||
);
|
||||
decl.register()
|
||||
}
|
||||
|
@ -107,10 +107,10 @@ pub struct MacForegroundPlatformState {
|
|||
resign_active: Option<Box<dyn FnMut()>>,
|
||||
quit: Option<Box<dyn FnMut()>>,
|
||||
event: Option<Box<dyn FnMut(crate::Event) -> bool>>,
|
||||
menu_command: Option<Box<dyn FnMut(&dyn AnyAction)>>,
|
||||
open_files: Option<Box<dyn FnMut(Vec<PathBuf>)>>,
|
||||
menu_command: Option<Box<dyn FnMut(&dyn Action)>>,
|
||||
open_urls: Option<Box<dyn FnMut(Vec<String>)>>,
|
||||
finish_launching: Option<Box<dyn FnOnce() -> ()>>,
|
||||
menu_actions: Vec<Box<dyn AnyAction>>,
|
||||
menu_actions: Vec<Box<dyn Action>>,
|
||||
}
|
||||
|
||||
impl MacForegroundPlatform {
|
||||
|
@ -210,8 +210,8 @@ impl platform::ForegroundPlatform for MacForegroundPlatform {
|
|||
self.0.borrow_mut().event = Some(callback);
|
||||
}
|
||||
|
||||
fn on_open_files(&self, callback: Box<dyn FnMut(Vec<PathBuf>)>) {
|
||||
self.0.borrow_mut().open_files = Some(callback);
|
||||
fn on_open_urls(&self, callback: Box<dyn FnMut(Vec<String>)>) {
|
||||
self.0.borrow_mut().open_urls = Some(callback);
|
||||
}
|
||||
|
||||
fn run(&self, on_finish_launching: Box<dyn FnOnce() -> ()>) {
|
||||
|
@ -235,7 +235,7 @@ impl platform::ForegroundPlatform for MacForegroundPlatform {
|
|||
}
|
||||
}
|
||||
|
||||
fn on_menu_command(&self, callback: Box<dyn FnMut(&dyn AnyAction)>) {
|
||||
fn on_menu_command(&self, callback: Box<dyn FnMut(&dyn Action)>) {
|
||||
self.0.borrow_mut().menu_command = Some(callback);
|
||||
}
|
||||
|
||||
|
@ -265,10 +265,9 @@ impl platform::ForegroundPlatform for MacForegroundPlatform {
|
|||
for i in 0..urls.count() {
|
||||
let url = urls.objectAtIndex(i);
|
||||
if url.isFileURL() == YES {
|
||||
let path = std::ffi::CStr::from_ptr(url.path().UTF8String())
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
result.push(PathBuf::from(path));
|
||||
if let Ok(path) = ns_url_to_path(url) {
|
||||
result.push(path)
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(result)
|
||||
|
@ -296,19 +295,13 @@ impl platform::ForegroundPlatform for MacForegroundPlatform {
|
|||
let (done_tx, done_rx) = oneshot::channel();
|
||||
let done_tx = Cell::new(Some(done_tx));
|
||||
let block = ConcreteBlock::new(move |response: NSModalResponse| {
|
||||
let result = if response == NSModalResponse::NSModalResponseOk {
|
||||
let mut result = None;
|
||||
if response == NSModalResponse::NSModalResponseOk {
|
||||
let url = panel.URL();
|
||||
if url.isFileURL() == YES {
|
||||
let path = std::ffi::CStr::from_ptr(url.path().UTF8String())
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
Some(PathBuf::from(path))
|
||||
} else {
|
||||
None
|
||||
result = ns_url_to_path(panel.URL()).ok()
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
}
|
||||
|
||||
if let Some(mut done_tx) = done_tx.take() {
|
||||
let _ = postage::sink::Sink::try_send(&mut done_tx, result);
|
||||
|
@ -603,19 +596,18 @@ impl platform::Platform for MacPlatform {
|
|||
}
|
||||
}
|
||||
|
||||
fn path_for_resource(&self, name: Option<&str>, extension: Option<&str>) -> Result<PathBuf> {
|
||||
fn path_for_auxiliary_executable(&self, name: &str) -> Result<PathBuf> {
|
||||
unsafe {
|
||||
let bundle: id = NSBundle::mainBundle();
|
||||
if bundle.is_null() {
|
||||
Err(anyhow!("app is not running inside a bundle"))
|
||||
} else {
|
||||
let name = name.map_or(nil, |name| ns_string(name));
|
||||
let extension = extension.map_or(nil, |extension| ns_string(extension));
|
||||
let path: id = msg_send![bundle, pathForResource: name ofType: extension];
|
||||
if path.is_null() {
|
||||
Err(anyhow!("resource could not be found"))
|
||||
let name = ns_string(name);
|
||||
let url: id = msg_send![bundle, URLForAuxiliaryExecutable: name];
|
||||
if url.is_null() {
|
||||
Err(anyhow!("resource not found"))
|
||||
} else {
|
||||
Ok(path_from_objc(path))
|
||||
ns_url_to_path(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -710,14 +702,14 @@ extern "C" fn will_terminate(this: &mut Object, _: Sel, _: id) {
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" fn open_files(this: &mut Object, _: Sel, _: id, paths: id) {
|
||||
let paths = unsafe {
|
||||
(0..paths.count())
|
||||
extern "C" fn open_urls(this: &mut Object, _: Sel, _: id, urls: id) {
|
||||
let urls = unsafe {
|
||||
(0..urls.count())
|
||||
.into_iter()
|
||||
.filter_map(|i| {
|
||||
let path = paths.objectAtIndex(i);
|
||||
match CStr::from_ptr(path.UTF8String() as *mut c_char).to_str() {
|
||||
Ok(string) => Some(PathBuf::from(string)),
|
||||
let path = urls.objectAtIndex(i);
|
||||
match CStr::from_ptr(path.absoluteString().UTF8String() as *mut c_char).to_str() {
|
||||
Ok(string) => Some(string.to_string()),
|
||||
Err(err) => {
|
||||
log::error!("error converting path to string: {}", err);
|
||||
None
|
||||
|
@ -727,8 +719,8 @@ extern "C" fn open_files(this: &mut Object, _: Sel, _: id, paths: id) {
|
|||
.collect::<Vec<_>>()
|
||||
};
|
||||
let platform = unsafe { get_foreground_platform(this) };
|
||||
if let Some(callback) = platform.0.borrow_mut().open_files.as_mut() {
|
||||
callback(paths);
|
||||
if let Some(callback) = platform.0.borrow_mut().open_urls.as_mut() {
|
||||
callback(urls);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -751,6 +743,20 @@ unsafe fn ns_string(string: &str) -> id {
|
|||
NSString::alloc(nil).init_str(string).autorelease()
|
||||
}
|
||||
|
||||
unsafe fn ns_url_to_path(url: id) -> Result<PathBuf> {
|
||||
let path: *mut c_char = msg_send![url, fileSystemRepresentation];
|
||||
if path.is_null() {
|
||||
Err(anyhow!(
|
||||
"url is not a file path: {}",
|
||||
CStr::from_ptr(url.absoluteString().UTF8String()).to_string_lossy()
|
||||
))
|
||||
} else {
|
||||
Ok(PathBuf::from(OsStr::from_bytes(
|
||||
CStr::from_ptr(path).to_bytes(),
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
mod security {
|
||||
#![allow(non_upper_case_globals)]
|
||||
use super::*;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue