Merge pull request #922 from atom/dialog-thread

Run asynchronous file dialog in new thread on Windows
This commit is contained in:
Cheng Zhao 2014-12-16 14:01:05 -08:00
commit 5bed184014
2 changed files with 68 additions and 14 deletions

View file

@ -15,6 +15,7 @@
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/strings/string_split.h" #include "base/strings/string_split.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/threading/thread.h"
#include "base/win/registry.h" #include "base/win/registry.h"
#include "third_party/wtl/include/atlapp.h" #include "third_party/wtl/include/atlapp.h"
#include "third_party/wtl/include/atldlgs.h" #include "third_party/wtl/include/atldlgs.h"
@ -113,6 +114,50 @@ class FileDialog {
DISALLOW_COPY_AND_ASSIGN(FileDialog); DISALLOW_COPY_AND_ASSIGN(FileDialog);
}; };
struct RunState {
base::Thread* dialog_thread;
base::MessageLoop* ui_message_loop;
};
bool CreateDialogThread(RunState* run_state) {
base::Thread* thread = new base::Thread("AtomShell_FileDialogThread");
thread->init_com_with_mta(false);
if (!thread->Start())
return false;
run_state->dialog_thread = thread;
run_state->ui_message_loop = base::MessageLoop::current();
return true;
}
void RunOpenDialogInNewThread(const RunState& run_state,
atom::NativeWindow* parent,
const std::string& title,
const base::FilePath& default_path,
const Filters& filters,
int properties,
const OpenDialogCallback& callback) {
std::vector<base::FilePath> paths;
bool result = ShowOpenDialog(parent, title, default_path, filters, properties,
&paths);
run_state.ui_message_loop->PostTask(FROM_HERE,
base::Bind(callback, result, paths));
run_state.ui_message_loop->DeleteSoon(FROM_HERE, run_state.dialog_thread);
}
void RunSaveDialogInNewThread(const RunState& run_state,
atom::NativeWindow* parent,
const std::string& title,
const base::FilePath& default_path,
const Filters& filters,
const SaveDialogCallback& callback) {
base::FilePath path;
bool result = ShowSaveDialog(parent, title, default_path, filters, &path);
run_state.ui_message_loop->PostTask(FROM_HERE,
base::Bind(callback, result, path));
run_state.ui_message_loop->DeleteSoon(FROM_HERE, run_state.dialog_thread);
}
} // namespace } // namespace
bool ShowOpenDialog(atom::NativeWindow* parent_window, bool ShowOpenDialog(atom::NativeWindow* parent_window,
@ -162,20 +207,22 @@ bool ShowOpenDialog(atom::NativeWindow* parent_window,
return true; return true;
} }
void ShowOpenDialog(atom::NativeWindow* parent_window, void ShowOpenDialog(atom::NativeWindow* parent,
const std::string& title, const std::string& title,
const base::FilePath& default_path, const base::FilePath& default_path,
const Filters& filters, const Filters& filters,
int properties, int properties,
const OpenDialogCallback& callback) { const OpenDialogCallback& callback) {
std::vector<base::FilePath> paths; RunState run_state;
bool result = ShowOpenDialog(parent_window, if (!CreateDialogThread(&run_state)) {
title, callback.Run(false, std::vector<base::FilePath>());
default_path, return;
filters, }
properties,
&paths); run_state.dialog_thread->message_loop()->PostTask(
callback.Run(result, paths); FROM_HERE,
base::Bind(&RunOpenDialogInNewThread, run_state, parent, title,
default_path, filters, properties, callback));
} }
bool ShowSaveDialog(atom::NativeWindow* parent_window, bool ShowSaveDialog(atom::NativeWindow* parent_window,
@ -218,15 +265,21 @@ bool ShowSaveDialog(atom::NativeWindow* parent_window,
return true; return true;
} }
void ShowSaveDialog(atom::NativeWindow* parent_window, void ShowSaveDialog(atom::NativeWindow* parent,
const std::string& title, const std::string& title,
const base::FilePath& default_path, const base::FilePath& default_path,
const Filters& filters, const Filters& filters,
const SaveDialogCallback& callback) { const SaveDialogCallback& callback) {
base::FilePath path; RunState run_state;
bool result = ShowSaveDialog(parent_window, title, default_path, filters, if (!CreateDialogThread(&run_state)) {
&path); callback.Run(false, base::FilePath());
callback.Run(result, path); return;
}
run_state.dialog_thread->message_loop()->PostTask(
FROM_HERE,
base::Bind(&RunSaveDialogInNewThread, run_state, parent, title,
default_path, filters, callback));
} }
} // namespace file_dialog } // namespace file_dialog

View file

@ -136,6 +136,7 @@
4005, # (node.h) macro redefinition 4005, # (node.h) macro redefinition
4189, # local variable is initialized but not referenced 4189, # local variable is initialized but not referenced
4201, # (uv.h) nameless struct/union 4201, # (uv.h) nameless struct/union
4503, # decorated name length exceeded, name was truncated
4800, # (v8.h) forcing value to bool 'true' or 'false' 4800, # (v8.h) forcing value to bool 'true' or 'false'
4819, # The file contains a character that cannot be represented in the current code page 4819, # The file contains a character that cannot be represented in the current code page
4996, # (atlapp.h) 'GetVersionExW': was declared deprecated 4996, # (atlapp.h) 'GetVersionExW': was declared deprecated