Fix circular locking in prompts
Sometimes Cocoa calls app delegate methods (notably the display link) while we're calling Cocoa methods. This causes a deadlock unless we are careful to run cocao methods while we're not holding our internal locks
This commit is contained in:
parent
6ed7cc7833
commit
249a6da54a
1 changed files with 62 additions and 52 deletions
|
@ -534,13 +534,15 @@ impl Platform for MacPlatform {
|
||||||
&self,
|
&self,
|
||||||
options: PathPromptOptions,
|
options: PathPromptOptions,
|
||||||
) -> oneshot::Receiver<Option<Vec<PathBuf>>> {
|
) -> oneshot::Receiver<Option<Vec<PathBuf>>> {
|
||||||
|
let (done_tx, done_rx) = oneshot::channel();
|
||||||
|
self.foreground_executor()
|
||||||
|
.spawn(async move {
|
||||||
unsafe {
|
unsafe {
|
||||||
let panel = NSOpenPanel::openPanel(nil);
|
let panel = NSOpenPanel::openPanel(nil);
|
||||||
panel.setCanChooseDirectories_(options.directories.to_objc());
|
panel.setCanChooseDirectories_(options.directories.to_objc());
|
||||||
panel.setCanChooseFiles_(options.files.to_objc());
|
panel.setCanChooseFiles_(options.files.to_objc());
|
||||||
panel.setAllowsMultipleSelection_(options.multiple.to_objc());
|
panel.setAllowsMultipleSelection_(options.multiple.to_objc());
|
||||||
panel.setResolvesAliases_(false.to_objc());
|
panel.setResolvesAliases_(false.to_objc());
|
||||||
let (done_tx, done_rx) = oneshot::channel();
|
|
||||||
let done_tx = Cell::new(Some(done_tx));
|
let done_tx = Cell::new(Some(done_tx));
|
||||||
let block = ConcreteBlock::new(move |response: NSModalResponse| {
|
let block = ConcreteBlock::new(move |response: NSModalResponse| {
|
||||||
let result = if response == NSModalResponse::NSModalResponseOk {
|
let result = if response == NSModalResponse::NSModalResponseOk {
|
||||||
|
@ -565,18 +567,23 @@ impl Platform for MacPlatform {
|
||||||
});
|
});
|
||||||
let block = block.copy();
|
let block = block.copy();
|
||||||
let _: () = msg_send![panel, beginWithCompletionHandler: block];
|
let _: () = msg_send![panel, beginWithCompletionHandler: block];
|
||||||
done_rx
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
.detach();
|
||||||
|
done_rx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prompt_for_new_path(&self, directory: &Path) -> oneshot::Receiver<Option<PathBuf>> {
|
fn prompt_for_new_path(&self, directory: &Path) -> oneshot::Receiver<Option<PathBuf>> {
|
||||||
|
let directory = directory.to_owned();
|
||||||
|
let (done_tx, done_rx) = oneshot::channel();
|
||||||
|
self.foreground_executor()
|
||||||
|
.spawn(async move {
|
||||||
unsafe {
|
unsafe {
|
||||||
let panel = NSSavePanel::savePanel(nil);
|
let panel = NSSavePanel::savePanel(nil);
|
||||||
let path = ns_string(directory.to_string_lossy().as_ref());
|
let path = ns_string(directory.to_string_lossy().as_ref());
|
||||||
let url = NSURL::fileURLWithPath_isDirectory_(nil, path, true.to_objc());
|
let url = NSURL::fileURLWithPath_isDirectory_(nil, path, true.to_objc());
|
||||||
panel.setDirectoryURL(url);
|
panel.setDirectoryURL(url);
|
||||||
|
|
||||||
let (done_tx, done_rx) = oneshot::channel();
|
|
||||||
let done_tx = Cell::new(Some(done_tx));
|
let done_tx = Cell::new(Some(done_tx));
|
||||||
let block = ConcreteBlock::new(move |response: NSModalResponse| {
|
let block = ConcreteBlock::new(move |response: NSModalResponse| {
|
||||||
let mut result = None;
|
let mut result = None;
|
||||||
|
@ -593,8 +600,11 @@ impl Platform for MacPlatform {
|
||||||
});
|
});
|
||||||
let block = block.copy();
|
let block = block.copy();
|
||||||
let _: () = msg_send![panel, beginWithCompletionHandler: block];
|
let _: () = msg_send![panel, beginWithCompletionHandler: block];
|
||||||
done_rx
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
.detach();
|
||||||
|
|
||||||
|
done_rx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reveal_path(&self, path: &Path) {
|
fn reveal_path(&self, path: &Path) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue