From 253bacdf1d9c4eb925971859faafe4d5b8a21c51 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 16 Dec 2014 11:27:38 -0800 Subject: [PATCH] win: Run async open dialog in new thread --- atom/browser/ui/file_dialog_win.cc | 46 ++++++++++++++++++++++++------ common.gypi | 1 + 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/atom/browser/ui/file_dialog_win.cc b/atom/browser/ui/file_dialog_win.cc index 0bd0c521af8..804c0b27913 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,26 @@ class FileDialog { DISALLOW_COPY_AND_ASSIGN(FileDialog); }; +struct RunState { + base::Thread* dialog_thread; + base::MessageLoop* ui_message_loop; +}; + +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); +} + } // namespace bool ShowOpenDialog(atom::NativeWindow* parent_window, @@ -162,20 +183,27 @@ 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); + base::Thread* thread = new base::Thread("AtomShell_FileDialogThread"); + thread->init_com_with_mta(false); + if (!thread->Start()) + return; + + if (parent) + EnableWindow( + static_cast(parent)->GetAcceleratedWidget(), + FALSE); + + RunState state = { thread, base::MessageLoop::current() }; + thread->message_loop()->PostTask( + FROM_HERE, + base::Bind(&RunOpenDialogInNewThread, state, parent, title, default_path, + filters, properties, callback)); } bool ShowSaveDialog(atom::NativeWindow* parent_window, diff --git a/common.gypi b/common.gypi index 7ee6d494a4d..68d9418f23e 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