Merge remote-tracking branch 'origin/master' into roller/chromium-ad1b791122c04bd91b825fbfbdf1ff4da82a0edb-1558011686736

This commit is contained in:
Jeremy Apthorp 2019-05-21 10:07:17 -07:00
commit ca283c74c9
64 changed files with 2026 additions and 3216 deletions

View file

@ -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);

View file

@ -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:

View file

@ -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);

View file

@ -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)

View file

@ -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_

View file

@ -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)

View file

@ -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);

View file

@ -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>

View file

@ -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

View file

@ -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 {

View file

@ -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));

View file

@ -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) {}

View file

@ -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 {