diff --git a/atom/browser/ui/file_dialog_win.cc b/atom/browser/ui/file_dialog_win.cc index 0bd0c521af..47e2c72a6d 100644 --- a/atom/browser/ui/file_dialog_win.cc +++ b/atom/browser/ui/file_dialog_win.cc @@ -15,6 +15,7 @@ #include "base/strings/string_util.h" #include "base/strings/string_split.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread.h" #include "base/win/registry.h" #include "third_party/wtl/include/atlapp.h" #include "third_party/wtl/include/atldlgs.h" @@ -113,6 +114,50 @@ class 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 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 bool ShowOpenDialog(atom::NativeWindow* parent_window, @@ -162,20 +207,22 @@ bool ShowOpenDialog(atom::NativeWindow* parent_window, return true; } -void ShowOpenDialog(atom::NativeWindow* parent_window, +void ShowOpenDialog(atom::NativeWindow* parent, const std::string& title, const base::FilePath& default_path, const Filters& filters, int properties, const OpenDialogCallback& callback) { - std::vector paths; - bool result = ShowOpenDialog(parent_window, - title, - default_path, - filters, - properties, - &paths); - callback.Run(result, paths); + RunState run_state; + if (!CreateDialogThread(&run_state)) { + callback.Run(false, std::vector()); + return; + } + + run_state.dialog_thread->message_loop()->PostTask( + FROM_HERE, + base::Bind(&RunOpenDialogInNewThread, run_state, parent, title, + default_path, filters, properties, callback)); } bool ShowSaveDialog(atom::NativeWindow* parent_window, @@ -218,15 +265,21 @@ bool ShowSaveDialog(atom::NativeWindow* parent_window, return true; } -void ShowSaveDialog(atom::NativeWindow* parent_window, +void ShowSaveDialog(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_window, title, default_path, filters, - &path); - callback.Run(result, path); + RunState run_state; + if (!CreateDialogThread(&run_state)) { + callback.Run(false, base::FilePath()); + return; + } + + run_state.dialog_thread->message_loop()->PostTask( + FROM_HERE, + base::Bind(&RunSaveDialogInNewThread, run_state, parent, title, + default_path, filters, callback)); } } // namespace file_dialog diff --git a/common.gypi b/common.gypi index 7ee6d494a4..68d9418f23 100644 --- a/common.gypi +++ b/common.gypi @@ -136,6 +136,7 @@ 4005, # (node.h) macro redefinition 4189, # local variable is initialized but not referenced 4201, # (uv.h) nameless struct/union + 4503, # decorated name length exceeded, name was truncated 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 4996, # (atlapp.h) 'GetVersionExW': was declared deprecated