chore: remove native_mate (Part 3) (#20131)
* use gin converter in atom_api_menu * please only put necessary includes in header Having include in header means they have dependency relationship, putting arbitrary includes really really really really really makes refacoring much harder. * remove some simple uses of callback_converter_deprecated.h * use gin callback converter in file_dialog code * use gin in ErrorThrower * use gin in atom_bundle_mover * fix mistake in node stream * deprecate native_mate version of event_emitter_caller * use gin in node_bindings * remove usages of native_mate event_emitter_caller.h except for EventEmitter * fix compilation on Windows * gin::Arguments behaves differently on GetNext * just use StringToV8
This commit is contained in:
parent
7be1905023
commit
2c23e44ed9
61 changed files with 515 additions and 323 deletions
|
@ -5,27 +5,27 @@
|
|||
#ifndef SHELL_BROWSER_UI_COCOA_ATOM_BUNDLE_MOVER_H_
|
||||
#define SHELL_BROWSER_UI_COCOA_ATOM_BUNDLE_MOVER_H_
|
||||
|
||||
#include <string>
|
||||
#include "base/mac/foundation_util.h"
|
||||
#include "shell/common/gin_helper/error_thrower.h"
|
||||
|
||||
#include "native_mate/persistent_dictionary.h"
|
||||
namespace gin {
|
||||
class Arguments;
|
||||
}
|
||||
|
||||
namespace electron {
|
||||
|
||||
// Possible bundle movement conflicts
|
||||
enum class BundlerMoverConflictType { EXISTS, EXISTS_AND_RUNNING };
|
||||
|
||||
namespace ui {
|
||||
|
||||
namespace cocoa {
|
||||
|
||||
class AtomBundleMover {
|
||||
public:
|
||||
static bool Move(mate::Arguments* args);
|
||||
static bool Move(gin_helper::ErrorThrower thrower, gin::Arguments* args);
|
||||
static bool IsCurrentAppInApplicationsFolder();
|
||||
|
||||
private:
|
||||
static bool ShouldContinueMove(BundlerMoverConflictType type,
|
||||
mate::Arguments* args);
|
||||
static bool ShouldContinueMove(gin_helper::ErrorThrower thrower,
|
||||
BundlerMoverConflictType type,
|
||||
gin::Arguments* args);
|
||||
static bool IsInApplicationsFolder(NSString* bundlePath);
|
||||
static NSString* ContainingDiskImageDevice(NSString* bundlePath);
|
||||
static void Relaunch(NSString* destinationPath);
|
||||
|
@ -39,10 +39,6 @@ class AtomBundleMover {
|
|||
static bool Trash(NSString* path);
|
||||
};
|
||||
|
||||
} // namespace cocoa
|
||||
|
||||
} // namespace ui
|
||||
|
||||
} // namespace electron
|
||||
|
||||
#endif // SHELL_BROWSER_UI_COCOA_ATOM_BUNDLE_MOVER_H_
|
||||
|
|
|
@ -4,19 +4,17 @@
|
|||
|
||||
#import "shell/browser/ui/cocoa/atom_bundle_mover.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Security/Security.h>
|
||||
#import <dlfcn.h>
|
||||
#import <sys/mount.h>
|
||||
#import <sys/param.h>
|
||||
|
||||
#import "shell/browser/browser.h"
|
||||
#include "shell/common/native_mate_converters/once_callback.h"
|
||||
#include "gin/dictionary.h"
|
||||
#include "shell/browser/browser.h"
|
||||
#include "shell/common/gin_converters/callback_converter.h"
|
||||
|
||||
namespace mate {
|
||||
namespace gin {
|
||||
|
||||
template <>
|
||||
struct Converter<electron::BundlerMoverConflictType> {
|
||||
|
@ -24,26 +22,23 @@ struct Converter<electron::BundlerMoverConflictType> {
|
|||
electron::BundlerMoverConflictType value) {
|
||||
switch (value) {
|
||||
case electron::BundlerMoverConflictType::EXISTS:
|
||||
return mate::StringToV8(isolate, "exists");
|
||||
return gin::StringToV8(isolate, "exists");
|
||||
case electron::BundlerMoverConflictType::EXISTS_AND_RUNNING:
|
||||
return mate::StringToV8(isolate, "existsAndRunning");
|
||||
return gin::StringToV8(isolate, "existsAndRunning");
|
||||
default:
|
||||
return mate::StringToV8(isolate, "");
|
||||
return gin::StringToV8(isolate, "");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
} // namespace gin
|
||||
|
||||
namespace electron {
|
||||
|
||||
namespace ui {
|
||||
|
||||
namespace cocoa {
|
||||
|
||||
bool AtomBundleMover::ShouldContinueMove(BundlerMoverConflictType type,
|
||||
mate::Arguments* args) {
|
||||
mate::Dictionary options;
|
||||
bool AtomBundleMover::ShouldContinueMove(gin_helper::ErrorThrower thrower,
|
||||
BundlerMoverConflictType type,
|
||||
gin::Arguments* args) {
|
||||
gin::Dictionary options;
|
||||
bool hasOptions = args->GetNext(&options);
|
||||
base::OnceCallback<v8::Local<v8::Value>(BundlerMoverConflictType)>
|
||||
conflict_cb;
|
||||
|
@ -57,13 +52,14 @@ bool AtomBundleMover::ShouldContinueMove(BundlerMoverConflictType type,
|
|||
// we only want to throw an error if a user has returned a non-boolean
|
||||
// value; this allows for client-side error handling should something in
|
||||
// the handler throw
|
||||
args->ThrowError("Invalid conflict handler return type.");
|
||||
thrower.ThrowError("Invalid conflict handler return type.");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AtomBundleMover::Move(mate::Arguments* args) {
|
||||
bool AtomBundleMover::Move(gin_helper::ErrorThrower thrower,
|
||||
gin::Arguments* args) {
|
||||
// Path of the current bundle
|
||||
NSString* bundlePath = [[NSBundle mainBundle] bundlePath];
|
||||
|
||||
|
@ -103,10 +99,10 @@ bool AtomBundleMover::Move(mate::Arguments* args) {
|
|||
&authorizationCanceled)) {
|
||||
if (authorizationCanceled) {
|
||||
// User rejected the authorization request
|
||||
args->ThrowError("User rejected the authorization request");
|
||||
thrower.ThrowError("User rejected the authorization request");
|
||||
return false;
|
||||
} else {
|
||||
args->ThrowError(
|
||||
thrower.ThrowError(
|
||||
"Failed to copy to applications directory even with authorization");
|
||||
return false;
|
||||
}
|
||||
|
@ -117,8 +113,8 @@ bool AtomBundleMover::Move(mate::Arguments* args) {
|
|||
// But first, make sure that it's not running
|
||||
if (IsApplicationAtPathRunning(destinationPath)) {
|
||||
// Check for callback handler and get user choice for open/quit
|
||||
if (!ShouldContinueMove(BundlerMoverConflictType::EXISTS_AND_RUNNING,
|
||||
args))
|
||||
if (!ShouldContinueMove(
|
||||
thrower, BundlerMoverConflictType::EXISTS_AND_RUNNING, args))
|
||||
return false;
|
||||
|
||||
// Unless explicitly denied, give running app focus and terminate self
|
||||
|
@ -131,20 +127,21 @@ bool AtomBundleMover::Move(mate::Arguments* args) {
|
|||
return true;
|
||||
} else {
|
||||
// Check callback handler and get user choice for app trashing
|
||||
if (!ShouldContinueMove(BundlerMoverConflictType::EXISTS, args))
|
||||
if (!ShouldContinueMove(thrower, BundlerMoverConflictType::EXISTS,
|
||||
args))
|
||||
return false;
|
||||
|
||||
// Unless explicitly denied, attempt to trash old app
|
||||
if (!Trash([applicationsDirectory
|
||||
stringByAppendingPathComponent:bundleName])) {
|
||||
args->ThrowError("Failed to delete existing application");
|
||||
thrower.ThrowError("Failed to delete existing application");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!CopyBundle(bundlePath, destinationPath)) {
|
||||
args->ThrowError(
|
||||
thrower.ThrowError(
|
||||
"Failed to copy current bundle to the applications folder");
|
||||
return false;
|
||||
}
|
||||
|
@ -466,8 +463,4 @@ bool AtomBundleMover::DeleteOrTrash(NSString* path) {
|
|||
}
|
||||
}
|
||||
|
||||
} // namespace cocoa
|
||||
|
||||
} // namespace ui
|
||||
|
||||
} // namespace electron
|
||||
|
|
|
@ -10,8 +10,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "shell/common/native_mate_converters/file_path_converter.h"
|
||||
#include "gin/dictionary.h"
|
||||
#include "shell/common/promise_util.h"
|
||||
|
||||
namespace electron {
|
||||
|
@ -66,12 +65,12 @@ bool ShowOpenDialogSync(const DialogSettings& settings,
|
|||
std::vector<base::FilePath>* paths);
|
||||
|
||||
void ShowOpenDialog(const DialogSettings& settings,
|
||||
electron::util::Promise<mate::Dictionary> promise);
|
||||
electron::util::Promise<gin::Dictionary> promise);
|
||||
|
||||
bool ShowSaveDialogSync(const DialogSettings& settings, base::FilePath* path);
|
||||
|
||||
void ShowSaveDialog(const DialogSettings& settings,
|
||||
electron::util::Promise<mate::Dictionary> promise);
|
||||
electron::util::Promise<gin::Dictionary> promise);
|
||||
|
||||
} // namespace file_dialog
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "chrome/browser/ui/libgtkui/gtk_util.h"
|
||||
#include "shell/browser/native_window_views.h"
|
||||
#include "shell/browser/unresponsive_suppressor.h"
|
||||
#include "shell/common/gin_converters/file_path_converter.h"
|
||||
#include "ui/base/glib/glib_signal.h"
|
||||
#include "ui/views/widget/desktop_aura/x11_desktop_handler.h"
|
||||
|
||||
|
@ -137,15 +138,15 @@ class FileChooserDialog {
|
|||
gtk_window_present_with_time(GTK_WINDOW(dialog_), time);
|
||||
}
|
||||
|
||||
void RunSaveAsynchronous(electron::util::Promise<mate::Dictionary> promise) {
|
||||
void RunSaveAsynchronous(electron::util::Promise<gin::Dictionary> promise) {
|
||||
save_promise_.reset(
|
||||
new electron::util::Promise<mate::Dictionary>(std::move(promise)));
|
||||
new electron::util::Promise<gin::Dictionary>(std::move(promise)));
|
||||
RunAsynchronous();
|
||||
}
|
||||
|
||||
void RunOpenAsynchronous(electron::util::Promise<mate::Dictionary> promise) {
|
||||
void RunOpenAsynchronous(electron::util::Promise<gin::Dictionary> promise) {
|
||||
open_promise_.reset(
|
||||
new electron::util::Promise<mate::Dictionary>(std::move(promise)));
|
||||
new electron::util::Promise<gin::Dictionary>(std::move(promise)));
|
||||
RunAsynchronous();
|
||||
}
|
||||
|
||||
|
@ -186,8 +187,8 @@ class FileChooserDialog {
|
|||
GtkWidget* preview_;
|
||||
|
||||
Filters filters_;
|
||||
std::unique_ptr<electron::util::Promise<mate::Dictionary>> save_promise_;
|
||||
std::unique_ptr<electron::util::Promise<mate::Dictionary>> open_promise_;
|
||||
std::unique_ptr<electron::util::Promise<gin::Dictionary>> save_promise_;
|
||||
std::unique_ptr<electron::util::Promise<gin::Dictionary>> open_promise_;
|
||||
|
||||
// Callback for when we update the preview for the selection.
|
||||
CHROMEG_CALLBACK_0(FileChooserDialog, void, OnUpdatePreview, GtkWidget*);
|
||||
|
@ -198,8 +199,8 @@ class FileChooserDialog {
|
|||
void FileChooserDialog::OnFileDialogResponse(GtkWidget* widget, int response) {
|
||||
gtk_widget_hide(dialog_);
|
||||
if (save_promise_) {
|
||||
mate::Dictionary dict =
|
||||
mate::Dictionary::CreateEmpty(save_promise_->isolate());
|
||||
gin::Dictionary dict =
|
||||
gin::Dictionary::CreateEmpty(save_promise_->isolate());
|
||||
if (response == GTK_RESPONSE_ACCEPT) {
|
||||
dict.Set("canceled", false);
|
||||
dict.Set("filePath", GetFileName());
|
||||
|
@ -207,10 +208,10 @@ void FileChooserDialog::OnFileDialogResponse(GtkWidget* widget, int response) {
|
|||
dict.Set("canceled", true);
|
||||
dict.Set("filePath", base::FilePath());
|
||||
}
|
||||
save_promise_->Resolve(dict);
|
||||
save_promise_->ResolveWithGin(dict);
|
||||
} else if (open_promise_) {
|
||||
mate::Dictionary dict =
|
||||
mate::Dictionary::CreateEmpty(open_promise_->isolate());
|
||||
gin::Dictionary dict =
|
||||
gin::Dictionary::CreateEmpty(open_promise_->isolate());
|
||||
if (response == GTK_RESPONSE_ACCEPT) {
|
||||
dict.Set("canceled", false);
|
||||
dict.Set("filePaths", GetFileNames());
|
||||
|
@ -218,7 +219,7 @@ void FileChooserDialog::OnFileDialogResponse(GtkWidget* widget, int response) {
|
|||
dict.Set("canceled", true);
|
||||
dict.Set("filePaths", std::vector<base::FilePath>());
|
||||
}
|
||||
open_promise_->Resolve(dict);
|
||||
open_promise_->ResolveWithGin(dict);
|
||||
}
|
||||
delete this;
|
||||
}
|
||||
|
@ -294,7 +295,7 @@ bool ShowOpenDialogSync(const DialogSettings& settings,
|
|||
}
|
||||
|
||||
void ShowOpenDialog(const DialogSettings& settings,
|
||||
electron::util::Promise<mate::Dictionary> promise) {
|
||||
electron::util::Promise<gin::Dictionary> promise) {
|
||||
GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN;
|
||||
if (settings.properties & OPEN_DIALOG_OPEN_DIRECTORY)
|
||||
action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
|
||||
|
@ -317,7 +318,7 @@ bool ShowSaveDialogSync(const DialogSettings& settings, base::FilePath* path) {
|
|||
}
|
||||
|
||||
void ShowSaveDialog(const DialogSettings& settings,
|
||||
electron::util::Promise<mate::Dictionary> promise) {
|
||||
electron::util::Promise<gin::Dictionary> promise) {
|
||||
FileChooserDialog* save_dialog =
|
||||
new FileChooserDialog(GTK_FILE_CHOOSER_ACTION_SAVE, settings);
|
||||
save_dialog->RunSaveAsynchronous(std::move(promise));
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "base/mac/scoped_cftyperef.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "shell/browser/native_window.h"
|
||||
#include "shell/common/gin_converters/file_path_converter.h"
|
||||
|
||||
@interface PopUpButtonHandler : NSObject
|
||||
|
||||
|
@ -300,15 +301,15 @@ bool ShowOpenDialogSync(const DialogSettings& settings,
|
|||
void OpenDialogCompletion(int chosen,
|
||||
NSOpenPanel* dialog,
|
||||
bool security_scoped_bookmarks,
|
||||
electron::util::Promise<mate::Dictionary> promise) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(promise.isolate());
|
||||
electron::util::Promise<gin::Dictionary> promise) {
|
||||
gin::Dictionary dict = gin::Dictionary::CreateEmpty(promise.isolate());
|
||||
if (chosen == NSFileHandlingPanelCancelButton) {
|
||||
dict.Set("canceled", true);
|
||||
dict.Set("filePaths", std::vector<base::FilePath>());
|
||||
#if defined(MAS_BUILD)
|
||||
dict.Set("bookmarks", std::vector<std::string>());
|
||||
#endif
|
||||
promise.Resolve(dict);
|
||||
promise.ResolveWithGin(dict);
|
||||
} else {
|
||||
std::vector<base::FilePath> paths;
|
||||
dict.Set("canceled", false);
|
||||
|
@ -324,12 +325,12 @@ void OpenDialogCompletion(int chosen,
|
|||
ReadDialogPaths(dialog, &paths);
|
||||
dict.Set("filePaths", paths);
|
||||
#endif
|
||||
promise.Resolve(dict);
|
||||
promise.ResolveWithGin(dict);
|
||||
}
|
||||
}
|
||||
|
||||
void ShowOpenDialog(const DialogSettings& settings,
|
||||
electron::util::Promise<mate::Dictionary> promise) {
|
||||
electron::util::Promise<gin::Dictionary> promise) {
|
||||
NSOpenPanel* dialog = [NSOpenPanel openPanel];
|
||||
|
||||
SetupDialog(dialog, settings);
|
||||
|
@ -339,7 +340,7 @@ void ShowOpenDialog(const DialogSettings& settings,
|
|||
// and pass it to the completion handler.
|
||||
bool security_scoped_bookmarks = settings.security_scoped_bookmarks;
|
||||
|
||||
__block electron::util::Promise<mate::Dictionary> p = std::move(promise);
|
||||
__block electron::util::Promise<gin::Dictionary> p = std::move(promise);
|
||||
|
||||
if (!settings.parent_window || !settings.parent_window->GetNativeWindow() ||
|
||||
settings.force_detached) {
|
||||
|
@ -377,13 +378,13 @@ bool ShowSaveDialogSync(const DialogSettings& settings, base::FilePath* path) {
|
|||
void SaveDialogCompletion(int chosen,
|
||||
NSSavePanel* dialog,
|
||||
bool security_scoped_bookmarks,
|
||||
electron::util::Promise<mate::Dictionary> promise) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(promise.isolate());
|
||||
electron::util::Promise<gin::Dictionary> promise) {
|
||||
gin::Dictionary dict = gin::Dictionary::CreateEmpty(promise.isolate());
|
||||
if (chosen == NSFileHandlingPanelCancelButton) {
|
||||
dict.Set("canceled", true);
|
||||
dict.Set("filePath", base::FilePath());
|
||||
#if defined(MAS_BUILD)
|
||||
dict.Set("bookmark", "");
|
||||
dict.Set("bookmark", base::StringPiece());
|
||||
#endif
|
||||
} else {
|
||||
std::string path = base::SysNSStringToUTF8([[dialog URL] path]);
|
||||
|
@ -397,11 +398,11 @@ void SaveDialogCompletion(int chosen,
|
|||
}
|
||||
#endif
|
||||
}
|
||||
promise.Resolve(dict);
|
||||
promise.ResolveWithGin(dict);
|
||||
}
|
||||
|
||||
void ShowSaveDialog(const DialogSettings& settings,
|
||||
electron::util::Promise<mate::Dictionary> promise) {
|
||||
electron::util::Promise<gin::Dictionary> promise) {
|
||||
NSSavePanel* dialog = [NSSavePanel savePanel];
|
||||
|
||||
SetupDialog(dialog, settings);
|
||||
|
@ -412,7 +413,7 @@ void ShowSaveDialog(const DialogSettings& settings,
|
|||
// and pass it to the completion handler.
|
||||
bool security_scoped_bookmarks = settings.security_scoped_bookmarks;
|
||||
|
||||
__block electron::util::Promise<mate::Dictionary> p = std::move(promise);
|
||||
__block electron::util::Promise<gin::Dictionary> p = std::move(promise);
|
||||
|
||||
if (!settings.parent_window || !settings.parent_window->GetNativeWindow() ||
|
||||
settings.force_detached) {
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "base/win/registry.h"
|
||||
#include "shell/browser/native_window_views.h"
|
||||
#include "shell/browser/unresponsive_suppressor.h"
|
||||
#include "shell/common/gin_converters/file_path_converter.h"
|
||||
|
||||
namespace file_dialog {
|
||||
|
||||
|
@ -81,19 +82,19 @@ bool CreateDialogThread(RunState* run_state) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void OnDialogOpened(electron::util::Promise<mate::Dictionary> promise,
|
||||
void OnDialogOpened(electron::util::Promise<gin::Dictionary> promise,
|
||||
bool canceled,
|
||||
std::vector<base::FilePath> paths) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(promise.isolate());
|
||||
gin::Dictionary dict = gin::Dictionary::CreateEmpty(promise.isolate());
|
||||
dict.Set("canceled", canceled);
|
||||
dict.Set("filePaths", paths);
|
||||
promise.Resolve(dict);
|
||||
promise.ResolveWithGin(dict);
|
||||
}
|
||||
|
||||
void RunOpenDialogInNewThread(
|
||||
const RunState& run_state,
|
||||
const DialogSettings& settings,
|
||||
electron::util::Promise<mate::Dictionary> promise) {
|
||||
electron::util::Promise<gin::Dictionary> promise) {
|
||||
std::vector<base::FilePath> paths;
|
||||
bool result = ShowOpenDialogSync(settings, &paths);
|
||||
run_state.ui_task_runner->PostTask(
|
||||
|
@ -102,19 +103,19 @@ void RunOpenDialogInNewThread(
|
|||
run_state.ui_task_runner->DeleteSoon(FROM_HERE, run_state.dialog_thread);
|
||||
}
|
||||
|
||||
void OnSaveDialogDone(electron::util::Promise<mate::Dictionary> promise,
|
||||
void OnSaveDialogDone(electron::util::Promise<gin::Dictionary> promise,
|
||||
bool canceled,
|
||||
const base::FilePath path) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(promise.isolate());
|
||||
gin::Dictionary dict = gin::Dictionary::CreateEmpty(promise.isolate());
|
||||
dict.Set("canceled", canceled);
|
||||
dict.Set("filePath", path);
|
||||
promise.Resolve(dict);
|
||||
promise.ResolveWithGin(dict);
|
||||
}
|
||||
|
||||
void RunSaveDialogInNewThread(
|
||||
const RunState& run_state,
|
||||
const DialogSettings& settings,
|
||||
electron::util::Promise<mate::Dictionary> promise) {
|
||||
electron::util::Promise<gin::Dictionary> promise) {
|
||||
base::FilePath path;
|
||||
bool result = ShowSaveDialogSync(settings, &path);
|
||||
run_state.ui_task_runner->PostTask(
|
||||
|
@ -276,13 +277,13 @@ bool ShowOpenDialogSync(const DialogSettings& settings,
|
|||
}
|
||||
|
||||
void ShowOpenDialog(const DialogSettings& settings,
|
||||
electron::util::Promise<mate::Dictionary> promise) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(promise.isolate());
|
||||
electron::util::Promise<gin::Dictionary> promise) {
|
||||
gin::Dictionary dict = gin::Dictionary::CreateEmpty(promise.isolate());
|
||||
RunState run_state;
|
||||
if (!CreateDialogThread(&run_state)) {
|
||||
dict.Set("canceled", true);
|
||||
dict.Set("filePaths", std::vector<base::FilePath>());
|
||||
promise.Resolve(dict);
|
||||
promise.ResolveWithGin(dict);
|
||||
} else {
|
||||
run_state.dialog_thread->task_runner()->PostTask(
|
||||
FROM_HERE, base::BindOnce(&RunOpenDialogInNewThread, run_state,
|
||||
|
@ -326,13 +327,13 @@ bool ShowSaveDialogSync(const DialogSettings& settings, base::FilePath* path) {
|
|||
}
|
||||
|
||||
void ShowSaveDialog(const DialogSettings& settings,
|
||||
electron::util::Promise<mate::Dictionary> promise) {
|
||||
electron::util::Promise<gin::Dictionary> promise) {
|
||||
RunState run_state;
|
||||
if (!CreateDialogThread(&run_state)) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(promise.isolate());
|
||||
gin::Dictionary dict = gin::Dictionary::CreateEmpty(promise.isolate());
|
||||
dict.Set("canceled", true);
|
||||
dict.Set("filePath", base::FilePath());
|
||||
promise.Resolve(dict);
|
||||
promise.ResolveWithGin(dict);
|
||||
} else {
|
||||
run_state.dialog_thread->task_runner()->PostTask(
|
||||
FROM_HERE, base::BindOnce(&RunSaveDialogInNewThread, run_state,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue