Merge remote-tracking branch 'origin/master' into roller/chromium-ad1b791122c04bd91b825fbfbdf1ff4da82a0edb-1558011686736
This commit is contained in:
commit
ca283c74c9
64 changed files with 2026 additions and 3216 deletions
|
@ -142,7 +142,10 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
|||
#if defined(DEBUG)
|
||||
// Print logging to debug.log on Windows
|
||||
settings.logging_dest = logging::LOG_TO_ALL;
|
||||
settings.log_file = L"debug.log";
|
||||
base::FilePath log_filename;
|
||||
base::PathService::Get(base::DIR_EXE, &log_filename);
|
||||
log_filename = log_filename.AppendASCII("debug.log");
|
||||
settings.log_file = log_filename.value().c_str();
|
||||
settings.lock_log = logging::LOCK_LOG_FILE;
|
||||
settings.delete_old = logging::DELETE_OLD_LOG_FILE;
|
||||
#else
|
||||
|
|
|
@ -773,6 +773,10 @@ void App::SelectClientCertificate(
|
|||
}
|
||||
}
|
||||
|
||||
void App::OnGpuInfoUpdate() {
|
||||
Emit("gpu-info-update");
|
||||
}
|
||||
|
||||
void App::OnGpuProcessCrashed(base::TerminationStatus status) {
|
||||
Emit("gpu-process-crashed",
|
||||
status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED);
|
||||
|
|
|
@ -157,6 +157,7 @@ class App : public AtomBrowserClient::Delegate,
|
|||
bool* no_javascript_access) override;
|
||||
|
||||
// content::GpuDataManagerObserver:
|
||||
void OnGpuInfoUpdate() override;
|
||||
void OnGpuProcessCrashed(base::TerminationStatus status) override;
|
||||
|
||||
// content::BrowserChildProcessObserver:
|
||||
|
|
|
@ -68,7 +68,7 @@ void BrowserView::Init(v8::Isolate* isolate,
|
|||
const mate::Dictionary& options) {
|
||||
mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
|
||||
options.Get(options::kWebPreferences, &web_preferences);
|
||||
web_preferences.Set("isBrowserView", true);
|
||||
web_preferences.Set("type", "browserView");
|
||||
mate::Handle<class WebContents> web_contents =
|
||||
WebContents::Create(isolate, web_preferences);
|
||||
|
||||
|
|
|
@ -297,20 +297,12 @@ WebContents::WebContents(v8::Isolate* isolate,
|
|||
// Read options.
|
||||
options.Get("backgroundThrottling", &background_throttling_);
|
||||
|
||||
// FIXME(zcbenz): We should read "type" parameter for better design, but
|
||||
// on Windows we have encountered a compiler bug that if we read "type"
|
||||
// from |options| and then set |type_|, a memory corruption will happen
|
||||
// and Electron will soon crash.
|
||||
// Remvoe this after we upgraded to use VS 2015 Update 3.
|
||||
// Get type
|
||||
options.Get("type", &type_);
|
||||
|
||||
bool b = false;
|
||||
if (options.Get("isGuest", &b) && b)
|
||||
type_ = Type::WEB_VIEW;
|
||||
else if (options.Get("isBackgroundPage", &b) && b)
|
||||
type_ = Type::BACKGROUND_PAGE;
|
||||
else if (options.Get("isBrowserView", &b) && b)
|
||||
type_ = Type::BROWSER_VIEW;
|
||||
#if BUILDFLAG(ENABLE_OSR)
|
||||
else if (options.Get(options::kOffscreen, &b) && b)
|
||||
if (options.Get(options::kOffscreen, &b) && b)
|
||||
type_ = Type::OFF_SCREEN;
|
||||
#endif
|
||||
|
||||
|
@ -2266,7 +2258,6 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
|
|||
.SetMethod("beginFrameSubscription", &WebContents::BeginFrameSubscription)
|
||||
.SetMethod("endFrameSubscription", &WebContents::EndFrameSubscription)
|
||||
.SetMethod("startDrag", &WebContents::StartDrag)
|
||||
.SetMethod("isGuest", &WebContents::IsGuest)
|
||||
.SetMethod("attachToIframe", &WebContents::AttachToIframe)
|
||||
.SetMethod("detachFromOuterFrame", &WebContents::DetachFromOuterFrame)
|
||||
.SetMethod("isOffscreen", &WebContents::IsOffScreen)
|
||||
|
|
|
@ -28,19 +28,23 @@ enum {
|
|||
|
||||
#if defined(OS_LINUX)
|
||||
DIR_APP_DATA, // Application Data directory under the user profile.
|
||||
#else
|
||||
#endif
|
||||
|
||||
PATH_END, // End of new paths. Those that follow redirect to base::DIR_*
|
||||
|
||||
#if !defined(OS_LINUX)
|
||||
DIR_APP_DATA = base::DIR_APP_DATA,
|
||||
#endif
|
||||
|
||||
#if defined(OS_POSIX)
|
||||
DIR_CACHE = base::DIR_CACHE, // Directory where to put cache data.
|
||||
DIR_CACHE = base::DIR_CACHE // Directory where to put cache data.
|
||||
#else
|
||||
DIR_CACHE = base::DIR_APP_DATA,
|
||||
DIR_CACHE = base::DIR_APP_DATA
|
||||
#endif
|
||||
|
||||
PATH_END
|
||||
};
|
||||
|
||||
static_assert(PATH_START < PATH_END, "invalid PATH boundaries");
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_ATOM_PATHS_H_
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include "atom/browser/native_window_views.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include <objbase.h>
|
||||
#include <wrl/client.h>
|
||||
#endif
|
||||
|
||||
|
@ -62,7 +61,6 @@
|
|||
#include "atom/browser/ui/win/atom_desktop_window_tree_host_win.h"
|
||||
#include "skia/ext/skia_utils_win.h"
|
||||
#include "ui/base/win/shell.h"
|
||||
#include "ui/display/display.h"
|
||||
#include "ui/display/screen.h"
|
||||
#include "ui/display/win/screen_win.h"
|
||||
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
|
||||
|
@ -473,24 +471,15 @@ void NativeWindowViews::SetEnabledInternal(bool enable) {
|
|||
#endif
|
||||
}
|
||||
|
||||
#if defined(USE_X11)
|
||||
void NativeWindowViews::Maximize() {
|
||||
#if defined(OS_WIN)
|
||||
// For window without WS_THICKFRAME style, we can not call Maximize().
|
||||
if (!(::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_THICKFRAME)) {
|
||||
restore_bounds_ = GetBounds();
|
||||
auto display =
|
||||
display::Screen::GetScreen()->GetDisplayNearestPoint(GetPosition());
|
||||
SetBounds(display.work_area(), false);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (IsVisible())
|
||||
widget()->Maximize();
|
||||
else
|
||||
widget()->native_widget_private()->Show(ui::SHOW_STATE_MAXIMIZED,
|
||||
gfx::Rect());
|
||||
}
|
||||
#endif
|
||||
|
||||
void NativeWindowViews::Unmaximize() {
|
||||
#if defined(OS_WIN)
|
||||
|
|
|
@ -2,14 +2,19 @@
|
|||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <dwmapi.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/native_window_views.h"
|
||||
#include "atom/browser/ui/views/root_view.h"
|
||||
#include "atom/common/atom_constants.h"
|
||||
#include "content/public/browser/browser_accessibility_state.h"
|
||||
#include "ui/base/win/accessibility_misc_utils.h"
|
||||
#include "ui/display/display.h"
|
||||
#include "ui/display/win/screen_win.h"
|
||||
#include "ui/gfx/geometry/insets.h"
|
||||
#include "ui/views/widget/native_widget_private.h"
|
||||
|
||||
// Must be included after other Windows headers.
|
||||
#include <UIAutomationCoreApi.h>
|
||||
|
@ -138,11 +143,155 @@ bool IsScreenReaderActive() {
|
|||
return screenReader && UiaClientsAreListening();
|
||||
}
|
||||
|
||||
// We use "enum" instead of "enum class" because we need to do bitwise compare.
|
||||
enum AppbarAutohideEdge {
|
||||
TOP = 1 << 0,
|
||||
LEFT = 1 << 1,
|
||||
BOTTOM = 1 << 2,
|
||||
RIGHT = 1 << 3,
|
||||
};
|
||||
|
||||
// The thickness of an auto-hide taskbar in pixel.
|
||||
constexpr int kAutoHideTaskbarThicknessPx = 2;
|
||||
|
||||
// Code is copied from chrome_views_delegate_win.cc.
|
||||
bool MonitorHasAutohideTaskbarForEdge(UINT edge, HMONITOR monitor) {
|
||||
APPBARDATA taskbar_data = {sizeof(APPBARDATA), NULL, 0, edge};
|
||||
taskbar_data.hWnd = ::GetForegroundWindow();
|
||||
|
||||
// MSDN documents an ABM_GETAUTOHIDEBAREX, which supposedly takes a monitor
|
||||
// rect and returns autohide bars on that monitor. This sounds like a good
|
||||
// idea for multi-monitor systems. Unfortunately, it appears to not work at
|
||||
// least some of the time (erroneously returning NULL) and there's almost no
|
||||
// online documentation or other sample code using it that suggests ways to
|
||||
// address this problem. We do the following:-
|
||||
// 1. Use the ABM_GETAUTOHIDEBAR message. If it works, i.e. returns a valid
|
||||
// window we are done.
|
||||
// 2. If the ABM_GETAUTOHIDEBAR message does not work we query the auto hide
|
||||
// state of the taskbar and then retrieve its position. That call returns
|
||||
// the edge on which the taskbar is present. If it matches the edge we
|
||||
// are looking for, we are done.
|
||||
// NOTE: This call spins a nested run loop.
|
||||
HWND taskbar = reinterpret_cast<HWND>(
|
||||
SHAppBarMessage(ABM_GETAUTOHIDEBAR, &taskbar_data));
|
||||
if (!::IsWindow(taskbar)) {
|
||||
APPBARDATA taskbar_data = {sizeof(APPBARDATA), 0, 0, 0};
|
||||
unsigned int taskbar_state = SHAppBarMessage(ABM_GETSTATE, &taskbar_data);
|
||||
if (!(taskbar_state & ABS_AUTOHIDE))
|
||||
return false;
|
||||
|
||||
taskbar_data.hWnd = ::FindWindow(L"Shell_TrayWnd", NULL);
|
||||
if (!::IsWindow(taskbar_data.hWnd))
|
||||
return false;
|
||||
|
||||
SHAppBarMessage(ABM_GETTASKBARPOS, &taskbar_data);
|
||||
if (taskbar_data.uEdge == edge)
|
||||
taskbar = taskbar_data.hWnd;
|
||||
}
|
||||
|
||||
// There is a potential race condition here:
|
||||
// 1. A maximized chrome window is fullscreened.
|
||||
// 2. It is switched back to maximized.
|
||||
// 3. In the process the window gets a WM_NCCACLSIZE message which calls us to
|
||||
// get the autohide state.
|
||||
// 4. The worker thread is invoked. It calls the API to get the autohide
|
||||
// state. On Windows versions earlier than Windows 7, taskbars could
|
||||
// easily be always on top or not.
|
||||
// This meant that we only want to look for taskbars which have the topmost
|
||||
// bit set. However this causes problems in cases where the window on the
|
||||
// main thread is still in the process of switching away from fullscreen.
|
||||
// In this case the taskbar might not yet have the topmost bit set.
|
||||
// 5. The main thread resumes and does not leave space for the taskbar and
|
||||
// hence it does not pop when hovered.
|
||||
//
|
||||
// To address point 4 above, it is best to not check for the WS_EX_TOPMOST
|
||||
// window style on the taskbar, as starting from Windows 7, the topmost
|
||||
// style is always set. We don't support XP and Vista anymore.
|
||||
if (::IsWindow(taskbar)) {
|
||||
if (MonitorFromWindow(taskbar, MONITOR_DEFAULTTONEAREST) == monitor)
|
||||
return true;
|
||||
// In some cases like when the autohide taskbar is on the left of the
|
||||
// secondary monitor, the MonitorFromWindow call above fails to return the
|
||||
// correct monitor the taskbar is on. We fallback to MonitorFromPoint for
|
||||
// the cursor position in that case, which seems to work well.
|
||||
POINT cursor_pos = {0};
|
||||
GetCursorPos(&cursor_pos);
|
||||
if (MonitorFromPoint(cursor_pos, MONITOR_DEFAULTTONEAREST) == monitor)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int GetAppbarAutohideEdges(HWND hwnd) {
|
||||
HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONULL);
|
||||
if (!monitor)
|
||||
return 0;
|
||||
|
||||
int edges = 0;
|
||||
if (MonitorHasAutohideTaskbarForEdge(ABE_LEFT, monitor))
|
||||
edges |= AppbarAutohideEdge::LEFT;
|
||||
if (MonitorHasAutohideTaskbarForEdge(ABE_TOP, monitor))
|
||||
edges |= AppbarAutohideEdge::TOP;
|
||||
if (MonitorHasAutohideTaskbarForEdge(ABE_RIGHT, monitor))
|
||||
edges |= AppbarAutohideEdge::RIGHT;
|
||||
if (MonitorHasAutohideTaskbarForEdge(ABE_BOTTOM, monitor))
|
||||
edges |= AppbarAutohideEdge::BOTTOM;
|
||||
return edges;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::set<NativeWindowViews*> NativeWindowViews::forwarding_windows_;
|
||||
HHOOK NativeWindowViews::mouse_hook_ = NULL;
|
||||
|
||||
void NativeWindowViews::Maximize() {
|
||||
int autohide_edges = 0;
|
||||
if (!has_frame())
|
||||
autohide_edges = GetAppbarAutohideEdges(GetAcceleratedWidget());
|
||||
|
||||
// Only use Maximize() when:
|
||||
// 1. window has WS_THICKFRAME style;
|
||||
// 2. and window is not frameless when there is autohide taskbar.
|
||||
if ((::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_THICKFRAME) &&
|
||||
(has_frame() || autohide_edges == 0)) {
|
||||
if (IsVisible())
|
||||
widget()->Maximize();
|
||||
else
|
||||
widget()->native_widget_private()->Show(ui::SHOW_STATE_MAXIMIZED,
|
||||
gfx::Rect());
|
||||
return;
|
||||
}
|
||||
|
||||
gfx::Insets insets;
|
||||
if (!has_frame()) {
|
||||
// When taskbar is autohide, we need to leave some space so the window
|
||||
// isn't treated as a "fullscreen app", which would cause the taskbars
|
||||
// to disappear.
|
||||
//
|
||||
// This trick comes from hwnd_message_handler.cc. While Chromium already
|
||||
// does this for normal window, somehow it is not applying the trick when
|
||||
// using frameless window, and we have to do it ourselves.
|
||||
float scale_factor =
|
||||
display::win::ScreenWin::GetScaleFactorForHWND(GetAcceleratedWidget());
|
||||
int thickness = std::ceil(kAutoHideTaskbarThicknessPx / scale_factor);
|
||||
if (autohide_edges & AppbarAutohideEdge::LEFT)
|
||||
insets.set_left(-thickness);
|
||||
if (autohide_edges & AppbarAutohideEdge::TOP)
|
||||
insets.set_top(-thickness);
|
||||
if (autohide_edges & AppbarAutohideEdge::RIGHT)
|
||||
insets.set_right(thickness);
|
||||
if (autohide_edges & AppbarAutohideEdge::BOTTOM)
|
||||
insets.set_bottom(thickness);
|
||||
}
|
||||
|
||||
restore_bounds_ = GetBounds();
|
||||
auto display =
|
||||
display::Screen::GetScreen()->GetDisplayNearestPoint(GetPosition());
|
||||
gfx::Rect bounds = display.work_area();
|
||||
bounds.Inset(insets);
|
||||
SetBounds(bounds, false);
|
||||
}
|
||||
|
||||
bool NativeWindowViews::ExecuteWindowsCommand(int command_id) {
|
||||
std::string command = AppCommandToString(command_id);
|
||||
NotifyWindowExecuteAppCommand(command);
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
<key>CFBundleIconFile</key>
|
||||
<string>electron.icns</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>6.0.0-nightly.20190404</string>
|
||||
<string>7.0.0-nightly.20190521</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>6.0.0-nightly.20190404</string>
|
||||
<string>7.0.0-nightly.20190521</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.developer-tools</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
|
|
|
@ -50,8 +50,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 6,0,0,20190404
|
||||
PRODUCTVERSION 6,0,0,20190404
|
||||
FILEVERSION 7,0,0,20190521
|
||||
PRODUCTVERSION 7,0,0,20190521
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -68,12 +68,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "GitHub, Inc."
|
||||
VALUE "FileDescription", "Electron"
|
||||
VALUE "FileVersion", "6.0.0"
|
||||
VALUE "FileVersion", "7.0.0"
|
||||
VALUE "InternalName", "electron.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
||||
VALUE "OriginalFilename", "electron.exe"
|
||||
VALUE "ProductName", "Electron"
|
||||
VALUE "ProductVersion", "6.0.0"
|
||||
VALUE "ProductVersion", "7.0.0"
|
||||
VALUE "SquirrelAwareVersion", "1"
|
||||
END
|
||||
END
|
||||
|
|
|
@ -117,7 +117,7 @@ void RunSaveDialogInNewThread(const RunState& run_state,
|
|||
bool result = ShowSaveDialogSync(settings, &path);
|
||||
run_state.ui_task_runner->PostTask(
|
||||
FROM_HERE,
|
||||
base::BindOnce(&OnSaveDialogDone, std::move(promise), result, path));
|
||||
base::BindOnce(&OnSaveDialogDone, std::move(promise), !result, path));
|
||||
run_state.ui_task_runner->DeleteSoon(FROM_HERE, run_state.dialog_thread);
|
||||
}
|
||||
|
||||
|
@ -321,7 +321,7 @@ void ShowSaveDialog(const DialogSettings& settings,
|
|||
RunState run_state;
|
||||
if (!CreateDialogThread(&run_state)) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(promise.isolate());
|
||||
dict.Set("canceled", false);
|
||||
dict.Set("canceled", true);
|
||||
dict.Set("filePath", base::FilePath());
|
||||
promise.Resolve(dict.GetHandle());
|
||||
} else {
|
||||
|
|
|
@ -108,8 +108,8 @@ WebContentsPreferences::WebContentsPreferences(
|
|||
mate::Dictionary copied(isolate, web_preferences.GetHandle()->Clone());
|
||||
// Following fields should not be stored.
|
||||
copied.Delete("embedder");
|
||||
copied.Delete("isGuest");
|
||||
copied.Delete("session");
|
||||
copied.Delete("type");
|
||||
|
||||
mate::ConvertFromV8(isolate, copied.GetHandle(), &preference_);
|
||||
web_contents->SetUserData(UserDataKey(), base::WrapUnique(this));
|
||||
|
|
|
@ -35,7 +35,8 @@ using blink::mojom::FileChooserParams;
|
|||
namespace {
|
||||
|
||||
class FileSelectHelper : public base::RefCounted<FileSelectHelper>,
|
||||
public content::WebContentsObserver {
|
||||
public content::WebContentsObserver,
|
||||
public atom::DirectoryListerHelperDelegate {
|
||||
public:
|
||||
FileSelectHelper(content::RenderFrameHost* render_frame_host,
|
||||
std::unique_ptr<content::FileSelectListener> listener,
|
||||
|
@ -71,23 +72,61 @@ class FileSelectHelper : public base::RefCounted<FileSelectHelper>,
|
|||
isolate, base::Bind(&FileSelectHelper::OnSaveDialogDone, this)))));
|
||||
}
|
||||
|
||||
void OnDirectoryListerDone(std::vector<FileChooserFileInfoPtr> file_info,
|
||||
base::FilePath base_dir) override {
|
||||
OnFilesSelected(std::move(file_info), base_dir);
|
||||
Release();
|
||||
}
|
||||
|
||||
private:
|
||||
friend class base::RefCounted<FileSelectHelper>;
|
||||
|
||||
~FileSelectHelper() override {}
|
||||
|
||||
void EnumerateDirectory(base::FilePath base_dir) {
|
||||
auto* lister = new net::DirectoryLister(
|
||||
base_dir, net::DirectoryLister::NO_SORT_RECURSIVE,
|
||||
new atom::DirectoryListerHelper(base_dir, this));
|
||||
lister->Start();
|
||||
// It is difficult for callers to know how long to keep a reference to
|
||||
// this instance. We AddRef() here to keep the instance alive after we
|
||||
// return to the caller. Once the directory lister is complete we
|
||||
// Release() in OnDirectoryListerDone() and at that point we run
|
||||
// OnFilesSelected() which will deref the last reference held by the
|
||||
// listener.
|
||||
AddRef();
|
||||
}
|
||||
|
||||
void OnOpenDialogDone(mate::Dictionary result) {
|
||||
std::vector<FileChooserFileInfoPtr> file_info;
|
||||
bool canceled = true;
|
||||
result.Get("canceled", &canceled);
|
||||
base::FilePath base_dir;
|
||||
// For certain file chooser modes (kUploadFolder) we need to do some async
|
||||
// work before calling back to the listener. In that particular case the
|
||||
// listener is called from the directory enumerator.
|
||||
bool ready_to_call_listener = false;
|
||||
|
||||
if (!canceled) {
|
||||
std::vector<base::FilePath> paths;
|
||||
if (result.Get("filePaths", &paths)) {
|
||||
for (auto& path : paths) {
|
||||
file_info.push_back(FileChooserFileInfo::NewNativeFile(
|
||||
blink::mojom::NativeFileInfo::New(
|
||||
path, path.BaseName().AsUTF16Unsafe())));
|
||||
// If we are uploading a folder we need to enumerate its contents
|
||||
if (mode_ == FileChooserParams::Mode::kUploadFolder &&
|
||||
paths.size() >= 1) {
|
||||
base_dir = paths[0];
|
||||
|
||||
// Actually enumerate soemwhere off-thread
|
||||
base::SequencedTaskRunnerHandle::Get()->PostTask(
|
||||
FROM_HERE, base::BindOnce(&FileSelectHelper::EnumerateDirectory,
|
||||
this, base_dir));
|
||||
} else {
|
||||
for (auto& path : paths) {
|
||||
file_info.push_back(FileChooserFileInfo::NewNativeFile(
|
||||
blink::mojom::NativeFileInfo::New(
|
||||
path, path.BaseName().AsUTF16Unsafe())));
|
||||
}
|
||||
|
||||
ready_to_call_listener = true;
|
||||
}
|
||||
|
||||
if (render_frame_host_ && !paths.empty()) {
|
||||
|
@ -98,7 +137,9 @@ class FileSelectHelper : public base::RefCounted<FileSelectHelper>,
|
|||
}
|
||||
}
|
||||
}
|
||||
OnFilesSelected(std::move(file_info));
|
||||
|
||||
if (ready_to_call_listener)
|
||||
OnFilesSelected(std::move(file_info), base_dir);
|
||||
}
|
||||
|
||||
void OnSaveDialogDone(mate::Dictionary result) {
|
||||
|
@ -114,12 +155,13 @@ class FileSelectHelper : public base::RefCounted<FileSelectHelper>,
|
|||
path, path.BaseName().AsUTF16Unsafe())));
|
||||
}
|
||||
}
|
||||
OnFilesSelected(std::move(file_info));
|
||||
OnFilesSelected(std::move(file_info), base::FilePath());
|
||||
}
|
||||
|
||||
void OnFilesSelected(std::vector<FileChooserFileInfoPtr> file_info) {
|
||||
void OnFilesSelected(std::vector<FileChooserFileInfoPtr> file_info,
|
||||
base::FilePath base_dir) {
|
||||
if (listener_) {
|
||||
listener_->FileSelected(std::move(file_info), base::FilePath(), mode_);
|
||||
listener_->FileSelected(std::move(file_info), base_dir, mode_);
|
||||
listener_.reset();
|
||||
}
|
||||
render_frame_host_ = nullptr;
|
||||
|
@ -216,6 +258,30 @@ file_dialog::Filters GetFileTypesFromAcceptType(
|
|||
|
||||
namespace atom {
|
||||
|
||||
DirectoryListerHelper::DirectoryListerHelper(
|
||||
base::FilePath base,
|
||||
DirectoryListerHelperDelegate* helper)
|
||||
: base_dir_(base), delegate_(helper) {}
|
||||
DirectoryListerHelper::~DirectoryListerHelper() {}
|
||||
|
||||
void DirectoryListerHelper::OnListFile(
|
||||
const net::DirectoryLister::DirectoryListerData& data) {
|
||||
// We don't want to return directory paths, only file paths
|
||||
if (data.info.IsDirectory())
|
||||
return;
|
||||
|
||||
paths_.push_back(data.path);
|
||||
}
|
||||
void DirectoryListerHelper::OnListDone(int error) {
|
||||
std::vector<FileChooserFileInfoPtr> file_info;
|
||||
for (auto path : paths_)
|
||||
file_info.push_back(FileChooserFileInfo::NewNativeFile(
|
||||
blink::mojom::NativeFileInfo::New(path, base::string16())));
|
||||
|
||||
delegate_->OnDirectoryListerDone(std::move(file_info), base_dir_);
|
||||
delete this;
|
||||
}
|
||||
|
||||
WebDialogHelper::WebDialogHelper(NativeWindow* window, bool offscreen)
|
||||
: window_(window), offscreen_(offscreen), weak_factory_(this) {}
|
||||
|
||||
|
|
|
@ -6,8 +6,10 @@
|
|||
#define ATOM_BROWSER_WEB_DIALOG_HELPER_H_
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "net/base/directory_lister.h"
|
||||
#include "third_party/blink/public/mojom/choosers/file_chooser.mojom.h"
|
||||
|
||||
namespace base {
|
||||
|
@ -22,6 +24,32 @@ class WebContents;
|
|||
|
||||
namespace atom {
|
||||
|
||||
class DirectoryListerHelperDelegate {
|
||||
public:
|
||||
virtual void OnDirectoryListerDone(
|
||||
std::vector<blink::mojom::FileChooserFileInfoPtr> file_info,
|
||||
base::FilePath base_dir) = 0;
|
||||
};
|
||||
|
||||
class DirectoryListerHelper
|
||||
: public net::DirectoryLister::DirectoryListerDelegate {
|
||||
public:
|
||||
DirectoryListerHelper(base::FilePath base,
|
||||
DirectoryListerHelperDelegate* helper);
|
||||
~DirectoryListerHelper() override;
|
||||
|
||||
private:
|
||||
void OnListFile(
|
||||
const net::DirectoryLister::DirectoryListerData& data) override;
|
||||
void OnListDone(int error) override;
|
||||
|
||||
base::FilePath base_dir_;
|
||||
DirectoryListerHelperDelegate* delegate_;
|
||||
std::vector<base::FilePath> paths_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DirectoryListerHelper);
|
||||
};
|
||||
|
||||
class NativeWindow;
|
||||
|
||||
class WebDialogHelper {
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
#ifndef ATOM_COMMON_ATOM_VERSION_H_
|
||||
#define ATOM_COMMON_ATOM_VERSION_H_
|
||||
|
||||
#define ATOM_MAJOR_VERSION 6
|
||||
#define ATOM_MAJOR_VERSION 7
|
||||
#define ATOM_MINOR_VERSION 0
|
||||
#define ATOM_PATCH_VERSION 0
|
||||
// clang-format off
|
||||
#define ATOM_PRE_RELEASE_VERSION -nightly.20190404
|
||||
#define ATOM_PRE_RELEASE_VERSION -nightly.20190521
|
||||
// clang-format on
|
||||
|
||||
#ifndef ATOM_STRINGIFY
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue