Merge branch 'master' into chrome52
authorCheng Zhao <zcbenz@gmail.com>
Thu, 21 Jul 2016 11:34:36 +0000 (05:34 -0600)
committerCheng Zhao <zcbenz@gmail.com>
Thu, 21 Jul 2016 11:34:36 +0000 (05:34 -0600)
24 files changed:
1  2 
atom/app/node_main.cc
atom/browser/api/atom_api_menu.h
atom/browser/api/atom_api_menu_views.cc
atom/browser/api/atom_api_protocol.cc
atom/browser/api/atom_api_session.cc
atom/browser/api/atom_api_tray.h
atom/browser/atom_browser_context.cc
atom/browser/atom_browser_main_parts.cc
atom/browser/browser_win.cc
atom/browser/native_window.cc
atom/browser/native_window.h
atom/browser/native_window_views.cc
atom/browser/net/asar/url_request_asar_job.cc
atom/browser/ui/tray_icon_cocoa.mm
atom/browser/ui/views/menu_delegate.h
atom/browser/ui/win/notify_icon.cc
atom/browser/ui/win/notify_icon.h
atom/common/api/atom_api_native_image.cc
atom/common/native_mate_converters/v8_value_converter.cc
atom/renderer/atom_renderer_client.cc
atom/renderer/atom_renderer_client.h
common.gypi
docs/api/browser-window.md
vendor/brightray

diff --combined atom/app/node_main.cc
@@@ -7,14 -7,15 +7,15 @@@
  #include "atom/app/uv_task_runner.h"
  #include "atom/browser/javascript_environment.h"
  #include "atom/browser/node_debugger.h"
- #include "atom/common/node_includes.h"
  #include "base/command_line.h"
  #include "base/feature_list.h"
 -#include "base/thread_task_runner_handle.h"
 +#include "base/threading/thread_task_runner_handle.h"
  #include "gin/array_buffer.h"
  #include "gin/public/isolate_holder.h"
  #include "gin/v8_initializer.h"
  
+ #include "atom/common/node_includes.h"
  namespace atom {
  
  int NodeMain(int argc, char *argv[]) {
@@@ -69,7 -70,7 +70,7 @@@
      exit_code = node::EmitExit(env);
      node::RunAtExit(env);
  
-     env->Dispose();
+     node::FreeEnvironment(env);
    }
  
    v8::V8::Dispose();
@@@ -5,13 -5,13 +5,13 @@@
  #ifndef ATOM_BROWSER_API_ATOM_API_MENU_H_
  #define ATOM_BROWSER_API_ATOM_API_MENU_H_
  
 +#include <memory>
  #include <string>
  
  #include "atom/browser/api/atom_api_window.h"
  #include "atom/browser/api/trackable_object.h"
  #include "atom/browser/ui/atom_menu_model.h"
  #include "base/callback.h"
 -#include "base/memory/scoped_ptr.h"
  
  namespace atom {
  
@@@ -46,8 -46,10 +46,10 @@@ class Menu : public mate::TrackableObje
    bool IsCommandIdChecked(int command_id) const override;
    bool IsCommandIdEnabled(int command_id) const override;
    bool IsCommandIdVisible(int command_id) const override;
-   bool GetAcceleratorForCommandId(int command_id,
-                                   ui::Accelerator* accelerator) override;
+   bool GetAcceleratorForCommandIdWithParams(
+       int command_id,
+       bool use_default_accelerator,
+       ui::Accelerator* accelerator) const override;
    void ExecuteCommand(int command_id, int event_flags) override;
    void MenuWillShow(ui::SimpleMenuModel* source) override;
  
@@@ -89,7 -91,7 +91,7 @@@
    base::Callback<bool(int)> is_checked_;
    base::Callback<bool(int)> is_enabled_;
    base::Callback<bool(int)> is_visible_;
-   base::Callback<v8::Local<v8::Value>(int)> get_accelerator_;
+   base::Callback<v8::Local<v8::Value>(int, bool)> get_accelerator_;
    base::Callback<void(v8::Local<v8::Value>, int)> execute_command_;
    base::Callback<void()> menu_will_show_;
  
@@@ -5,8 -5,9 +5,9 @@@
  #include "atom/browser/api/atom_api_menu_views.h"
  
  #include "atom/browser/native_window_views.h"
+ #include "atom/browser/unresponsive_suppressor.h"
  #include "content/public/browser/render_widget_host_view.h"
 -#include "ui/gfx/screen.h"
 +#include "ui/display/screen.h"
  #include "ui/views/controls/menu/menu_runner.h"
  
  namespace atom {
@@@ -30,12 -31,15 +31,15 @@@ void MenuViews::PopupAt(Window* window
    // (-1, -1) means showing on mouse location.
    gfx::Point location;
    if (x == -1 || y == -1) {
 -    location = gfx::Screen::GetScreen()->GetCursorScreenPoint();
 +    location = display::Screen::GetScreen()->GetCursorScreenPoint();
    } else {
      gfx::Point origin = view->GetViewBounds().origin();
      location = gfx::Point(origin.x() + x, origin.y() + y);
    }
  
+   // Don't emit unresponsive event when showing menu.
+   atom::UnresponsiveSuppressor suppressor;
    // Show the menu.
    views::MenuRunner menu_runner(
        model(),
@@@ -6,6 -6,7 +6,7 @@@
  
  #include "atom/browser/atom_browser_client.h"
  #include "atom/browser/atom_browser_main_parts.h"
+ #include "atom/browser/browser.h"
  #include "atom/browser/net/url_request_async_asar_job.h"
  #include "atom/browser/net/url_request_buffer_job.h"
  #include "atom/browser/net/url_request_fetch_job.h"
@@@ -26,12 -27,31 +27,30 @@@ namespace atom 
  
  namespace api {
  
+ namespace {
+ // Clear protocol handlers in IO thread.
+ void ClearJobFactoryInIO(
+     scoped_refptr<brightray::URLRequestContextGetter> request_context_getter) {
+   auto job_factory = static_cast<AtomURLRequestJobFactory*>(
+       request_context_getter->job_factory());
+   job_factory->Clear();
+ }
+ }  // namespace
  Protocol::Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context)
 -    : request_context_getter_(static_cast<brightray::URLRequestContextGetter*>(
 -          browser_context->GetRequestContext())),
 +    : request_context_getter_(browser_context->GetRequestContext()),
        weak_factory_(this) {
    Init(isolate);
  }
  
+ Protocol::~Protocol() {
+   content::BrowserThread::PostTask(
+       content::BrowserThread::IO, FROM_HERE,
+       base::Bind(ClearJobFactoryInIO, request_context_getter_));
+ }
  void Protocol::RegisterServiceWorkerSchemes(
      const std::vector<std::string>& schemes) {
    atom::AtomBrowserClient::SetCustomServiceWorkerSchemes(schemes);
@@@ -173,7 -193,13 +192,13 @@@ void Protocol::BuildPrototype
  namespace {
  
  void RegisterStandardSchemes(
-     const std::vector<std::string>& schemes) {
+     const std::vector<std::string>& schemes, mate::Arguments* args) {
+   if (atom::Browser::Get()->is_ready()) {
+     args->ThrowError("protocol.registerStandardSchemes should be called before "
+                      "app is ready");
+     return;
+   }
    auto policy = content::ChildProcessSecurityPolicy::GetInstance();
    for (const auto& scheme : schemes) {
      url::AddStandardScheme(scheme.c_str(), url::SCHEME_WITHOUT_PORT);
@@@ -11,6 -11,7 +11,7 @@@
  #include "atom/browser/api/atom_api_download_item.h"
  #include "atom/browser/api/atom_api_protocol.h"
  #include "atom/browser/api/atom_api_web_request.h"
+ #include "atom/browser/browser.h"
  #include "atom/browser/atom_browser_context.h"
  #include "atom/browser/atom_browser_main_parts.h"
  #include "atom/browser/atom_permission_manager.h"
  #include "atom/common/native_mate_converters/gurl_converter.h"
  #include "atom/common/native_mate_converters/file_path_converter.h"
  #include "atom/common/native_mate_converters/net_converter.h"
+ #include "atom/common/native_mate_converters/value_converter.h"
  #include "atom/common/node_includes.h"
  #include "base/files/file_path.h"
  #include "base/guid.h"
  #include "components/prefs/pref_service.h"
  #include "base/strings/string_number_conversions.h"
  #include "base/strings/string_util.h"
 -#include "base/thread_task_runner_handle.h"
 +#include "base/threading/thread_task_runner_handle.h"
  #include "brightray/browser/net/devtools_network_conditions.h"
  #include "brightray/browser/net/devtools_network_controller_handle.h"
  #include "chrome/common/pref_names.h"
@@@ -163,6 -165,8 +165,8 @@@ namespace api 
  
  namespace {
  
+ const char kPersistPrefix[] = "persist:";
  // The wrapSession funtion which is implemented in JavaScript
  using WrapSessionCallback = base::Callback<void(v8::Local<v8::Value>)>;
  WrapSessionCallback g_wrap_session;
@@@ -175,7 -179,7 +179,7 @@@ class ResolveProxyHelper 
        : callback_(callback),
          original_thread_(base::ThreadTaskRunnerHandle::Get()) {
      scoped_refptr<net::URLRequestContextGetter> context_getter =
 -        browser_context->GetRequestContext();
 +        browser_context->url_request_context_getter();
      context_getter->GetNetworkTaskRunner()->PostTask(
          FROM_HERE,
          base::Bind(&ResolveProxyHelper::ResolveProxy,
@@@ -241,10 -245,10 +245,10 @@@ void OnGetBackend(disk_cache::Backend*
      } else if (action == Session::CacheAction::STATS) {
        base::StringPairs stats;
        (*backend_ptr)->GetStats(&stats);
-       for (size_t i = 0; i < stats.size(); ++i) {
-         if (stats[i].first == "Current size") {
+       for (const auto& stat : stats) {
+         if (stat.first == "Current size") {
            int current_size;
-           base::StringToInt(stats[i].second, &current_size);
+           base::StringToInt(stat.second, &current_size);
            RunCallbackInUI(callback, current_size);
            break;
          }
@@@ -266,7 -270,7 +270,7 @@@ void DoCacheActionInIO
  
    // Call GetBackend and make the backend's ptr accessable in OnGetBackend.
    using BackendPtr = disk_cache::Backend*;
-   BackendPtr* backend_ptr = new BackendPtr(nullptr);
+   auto* backend_ptr = new BackendPtr(nullptr);
    net::CompletionCallback on_get_backend =
        base::Bind(&OnGetBackend, base::Owned(backend_ptr), action, callback);
    int rv = http_cache->GetBackend(backend_ptr, on_get_backend);
@@@ -278,13 -282,21 +282,21 @@@ void SetProxyInIO(net::URLRequestContex
                    const net::ProxyConfig& config,
                    const base::Closure& callback) {
    auto proxy_service = getter->GetURLRequestContext()->proxy_service();
 -  proxy_service->ResetConfigService(make_scoped_ptr(
 +  proxy_service->ResetConfigService(base::WrapUnique(
        new net::ProxyConfigServiceFixed(config)));
    // Refetches and applies the new pac script if provided.
    proxy_service->ForceReloadProxyConfig();
    RunCallbackInUI(callback);
  }
  
+ void SetCertVerifyProcInIO(
+     const scoped_refptr<net::URLRequestContextGetter>& context_getter,
+     const AtomCertVerifier::VerifyProc& proc) {
+   auto request_context = context_getter->GetURLRequestContext();
+   static_cast<AtomCertVerifier*>(request_context->cert_verifier())->
+       SetVerifyProc(proc);
+ }
  void ClearHostResolverCacheInIO(
      const scoped_refptr<net::URLRequestContextGetter>& context_getter,
      const base::Closure& callback) {
@@@ -311,6 -323,11 +323,11 @@@ void AllowNTLMCredentialsForDomainsInIO
    }
  }
  
+ void OnClearStorageDataDone(const base::Closure& callback) {
+   if (!callback.is_null())
+     callback.Run();
+ }
  }  // namespace
  
  Session::Session(v8::Isolate* isolate, AtomBrowserContext* browser_context)
@@@ -360,21 -377,19 +377,19 @@@ void Session::DoCacheAction(const net::
  }
  
  void Session::ClearStorageData(mate::Arguments* args) {
-   // clearStorageData([options, ]callback)
+   // clearStorageData([options, callback])
    ClearStorageDataOptions options;
-   args->GetNext(&options);
    base::Closure callback;
-   if (!args->GetNext(&callback)) {
-     args->ThrowError();
-     return;
-   }
+   args->GetNext(&options);
+   args->GetNext(&callback);
  
    auto storage_partition =
        content::BrowserContext::GetStoragePartition(browser_context(), nullptr);
    storage_partition->ClearData(
        options.storage_types, options.quota_types, options.origin,
        content::StoragePartition::OriginMatcherFunction(),
-       base::Time(), base::Time::Max(), callback);
+       base::Time(), base::Time::Max(),
+       base::Bind(&OnClearStorageDataDone, callback));
  }
  
  void Session::FlushStorageData() {
@@@ -434,7 -449,10 +449,10 @@@ void Session::SetCertVerifyProc(v8::Loc
      return;
    }
  
-   browser_context_->cert_verifier()->SetVerifyProc(proc);
+   BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+       base::Bind(&SetCertVerifyProcInIO,
+                  make_scoped_refptr(browser_context_->GetRequestContext()),
+                  proc));
  }
  
  void Session::SetPermissionRequestHandler(v8::Local<v8::Value> val,
@@@ -522,10 -540,19 +540,19 @@@ mate::Handle<Session> Session::CreateFr
  
  // static
  mate::Handle<Session> Session::FromPartition(
-     v8::Isolate* isolate, const std::string& partition, bool in_memory) {
-   auto browser_context = brightray::BrowserContext::From(partition, in_memory);
-   return CreateFrom(isolate,
-                     static_cast<AtomBrowserContext*>(browser_context.get()));
+     v8::Isolate* isolate, const std::string& partition,
+     const base::DictionaryValue& options) {
+   scoped_refptr<AtomBrowserContext> browser_context;
+   if (partition.empty()) {
+     browser_context = AtomBrowserContext::From("", false, options);
+   } else if (base::StartsWith(partition, kPersistPrefix,
+                               base::CompareCase::SENSITIVE)) {
+     std::string name = partition.substr(8);
+     browser_context = AtomBrowserContext::From(name, false, options);
+   } else {
+     browser_context = AtomBrowserContext::From(partition, true, options);
+   }
+   return CreateFrom(isolate, browser_context.get());
  }
  
  // static
@@@ -565,11 -592,23 +592,23 @@@ void SetWrapSession(const WrapSessionCa
  
  namespace {
  
+ v8::Local<v8::Value> FromPartition(
+     const std::string& partition, mate::Arguments* args) {
+   if (!atom::Browser::Get()->is_ready()) {
+     args->ThrowError("Session can only be received when app is ready");
+     return v8::Null(args->isolate());
+   }
+   base::DictionaryValue options;
+   args->GetNext(&options);
+   return atom::api::Session::FromPartition(
+       args->isolate(), partition, options).ToV8();
+ }
  void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
                  v8::Local<v8::Context> context, void* priv) {
    v8::Isolate* isolate = context->GetIsolate();
    mate::Dictionary dict(isolate, exports);
-   dict.SetMethod("fromPartition", &atom::api::Session::FromPartition);
+   dict.SetMethod("fromPartition", &FromPartition);
    dict.SetMethod("_setWrapSession", &atom::api::SetWrapSession);
  }
  
@@@ -5,12 -5,12 +5,12 @@@
  #ifndef ATOM_BROWSER_API_ATOM_API_TRAY_H_
  #define ATOM_BROWSER_API_ATOM_API_TRAY_H_
  
 +#include <memory>
  #include <string>
  #include <vector>
  
  #include "atom/browser/api/trackable_object.h"
  #include "atom/browser/ui/tray_icon_observer.h"
 -#include "base/memory/scoped_ptr.h"
  #include "native_mate/handle.h"
  
  namespace gfx {
@@@ -53,6 -53,7 +53,7 @@@ class Tray : public mate::TrackableObje
    void OnBalloonClosed() override;
    void OnDrop() override;
    void OnDropFiles(const std::vector<std::string>& files) override;
+   void OnDropText(const std::string& text) override;
    void OnDragEntered() override;
    void OnDragExited() override;
    void OnDragEnded() override;
@@@ -63,10 -63,10 +63,10 @@@ std::string RemoveWhitespace(const std:
  
  }  // namespace
  
- AtomBrowserContext::AtomBrowserContext(const std::string& partition,
-                                        bool in_memory)
+ AtomBrowserContext::AtomBrowserContext(
+     const std::string& partition, bool in_memory,
+     const base::DictionaryValue& options)
      : brightray::BrowserContext(partition, in_memory),
-       cert_verifier_(new AtomCertVerifier),
        network_delegate_(new AtomNetworkDelegate) {
    // Construct user agent string.
    Browser* browser = Browser::Get();
          CHROME_VERSION_STRING);
    }
    user_agent_ = content::BuildUserAgentFromProduct(user_agent);
+   // Read options.
+   use_cache_ = true;
+   options.GetBoolean("cache", &use_cache_);
  }
  
  AtomBrowserContext::~AtomBrowserContext() {
@@@ -113,29 -117,29 +117,29 @@@ AtomBrowserContext::CreateURLRequestJob
    protocol_handlers->clear();
  
    job_factory->SetProtocolHandler(
 -      url::kDataScheme, make_scoped_ptr(new net::DataProtocolHandler));
 +      url::kDataScheme, base::WrapUnique(new net::DataProtocolHandler));
    job_factory->SetProtocolHandler(
 -      url::kFileScheme, make_scoped_ptr(new asar::AsarProtocolHandler(
 +      url::kFileScheme, base::WrapUnique(new asar::AsarProtocolHandler(
            BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
                base::SequencedWorkerPool::SKIP_ON_SHUTDOWN))));
    job_factory->SetProtocolHandler(
        url::kHttpScheme,
 -      make_scoped_ptr(new HttpProtocolHandler(url::kHttpScheme)));
 +      base::WrapUnique(new HttpProtocolHandler(url::kHttpScheme)));
    job_factory->SetProtocolHandler(
        url::kHttpsScheme,
 -      make_scoped_ptr(new HttpProtocolHandler(url::kHttpsScheme)));
 +      base::WrapUnique(new HttpProtocolHandler(url::kHttpsScheme)));
    job_factory->SetProtocolHandler(
        url::kWsScheme,
 -      make_scoped_ptr(new HttpProtocolHandler(url::kWsScheme)));
 +      base::WrapUnique(new HttpProtocolHandler(url::kWsScheme)));
    job_factory->SetProtocolHandler(
        url::kWssScheme,
 -      make_scoped_ptr(new HttpProtocolHandler(url::kWssScheme)));
 +      base::WrapUnique(new HttpProtocolHandler(url::kWssScheme)));
  
    auto host_resolver =
        url_request_context_getter()->GetURLRequestContext()->host_resolver();
    job_factory->SetProtocolHandler(
        url::kFtpScheme,
 -      make_scoped_ptr(new net::FtpProtocolHandler(
 +      base::WrapUnique(new net::FtpProtocolHandler(
            new net::FtpNetworkLayer(host_resolver))));
  
    return std::move(job_factory);
@@@ -145,7 -149,7 +149,7 @@@ net::HttpCache::BackendFactory
  AtomBrowserContext::CreateHttpCacheBackendFactory(
      const base::FilePath& base_path) {
    base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
-   if (command_line->HasSwitch(switches::kDisableHttpCache))
+   if (!use_cache_ || command_line->HasSwitch(switches::kDisableHttpCache))
      return new NoCacheBackend;
    else
      return brightray::BrowserContext::CreateHttpCacheBackendFactory(base_path);
@@@ -174,7 -178,7 +178,7 @@@ content::PermissionManager* AtomBrowser
  }
  
  std::unique_ptr<net::CertVerifier> AtomBrowserContext::CreateCertVerifier() {
-   return base::WrapUnique(cert_verifier_);
 -  return std::unique_ptr<net::CertVerifier>(new AtomCertVerifier);
++  return base::WrapUnique(new AtomCertVerifier);
  }
  
  net::SSLConfigService* AtomBrowserContext::CreateSSLConfigService() {
@@@ -191,14 -195,15 +195,15 @@@ void AtomBrowserContext::RegisterPrefs(
    pref_registry->RegisterDictionaryPref(prefs::kDevToolsFileSystemPaths);
  }
  
- }  // namespace atom
- namespace brightray {
  // static
- scoped_refptr<BrowserContext> BrowserContext::Create(
-     const std::string& partition, bool in_memory) {
-   return make_scoped_refptr(new atom::AtomBrowserContext(partition, in_memory));
+ scoped_refptr<AtomBrowserContext> AtomBrowserContext::From(
+     const std::string& partition, bool in_memory,
+     const base::DictionaryValue& options) {
+   auto browser_context = brightray::BrowserContext::Get(partition, in_memory);
+   if (browser_context)
+     return static_cast<AtomBrowserContext*>(browser_context.get());
+   return new AtomBrowserContext(partition, in_memory, options);
  }
  
- }  // namespace brightray
+ }  // namespace atom
@@@ -15,7 -15,7 +15,7 @@@
  #include "atom/common/node_bindings.h"
  #include "atom/common/node_includes.h"
  #include "base/command_line.h"
 -#include "base/thread_task_runner_handle.h"
 +#include "base/threading/thread_task_runner_handle.h"
  #include "chrome/browser/browser_process.h"
  #include "v8/include/v8-debug.h"
  
@@@ -32,7 -32,7 +32,7 @@@ void Erase(T* container, typename T::it
  }
  
  // static
- AtomBrowserMainParts* AtomBrowserMainParts::self_ = NULL;
+ AtomBrowserMainParts* AtomBrowserMainParts::self_ = nullptr;
  
  AtomBrowserMainParts::AtomBrowserMainParts()
      : fake_browser_process_(new BrowserProcess),
@@@ -13,6 -13,7 +13,6 @@@
  #include "base/base_paths.h"
  #include "base/file_version_info.h"
  #include "base/files/file_path.h"
 -#include "base/memory/scoped_ptr.h"
  #include "base/path_service.h"
  #include "base/strings/string_util.h"
  #include "base/strings/stringprintf.h"
@@@ -272,6 -273,39 +272,39 @@@ bool Browser::SetBadgeCount(int count) 
    return false;
  }
  
+ void Browser::SetLoginItemSettings(LoginItemSettings settings) {
+   std::wstring keyPath = L"Software\\Microsoft\\Windows\\CurrentVersion\\Run";
+   base::win::RegKey key(HKEY_CURRENT_USER, keyPath.c_str(), KEY_ALL_ACCESS);
+   if (settings.open_at_login) {
+     base::FilePath path;
+     if (PathService::Get(base::FILE_EXE, &path)) {
+       std::wstring exePath(path.value());
+       key.WriteValue(GetAppUserModelID(), exePath.c_str());
+     }
+   } else {
+     key.DeleteValue(GetAppUserModelID());
+   }
+ }
+ Browser::LoginItemSettings Browser::GetLoginItemSettings() {
+   LoginItemSettings settings;
+   std::wstring keyPath = L"Software\\Microsoft\\Windows\\CurrentVersion\\Run";
+   base::win::RegKey key(HKEY_CURRENT_USER, keyPath.c_str(), KEY_ALL_ACCESS);
+   std::wstring keyVal;
+   if (!FAILED(key.ReadValue(GetAppUserModelID(), &keyVal))) {
+     base::FilePath path;
+     if (PathService::Get(base::FILE_EXE, &path)) {
+       std::wstring exePath(path.value());
+       settings.open_at_login = keyVal == exePath;
+     }
+   }
+   return settings;
+ }
  PCWSTR Browser::GetAppUserModelID() {
    if (app_user_model_id_.empty()) {
      SetAppUserModelID(base::ReplaceStringPlaceholders(
@@@ -11,6 -11,7 +11,7 @@@
  #include "atom/browser/atom_browser_context.h"
  #include "atom/browser/atom_browser_main_parts.h"
  #include "atom/browser/browser.h"
+ #include "atom/browser/unresponsive_suppressor.h"
  #include "atom/browser/window_list.h"
  #include "atom/common/api/api_messages.h"
  #include "atom/common/native_mate_converters/file_path_converter.h"
@@@ -37,7 -38,6 +38,7 @@@
  #include "ui/gfx/geometry/rect.h"
  #include "ui/gfx/geometry/size.h"
  #include "ui/gfx/geometry/size_conversions.h"
 +#include "ui/display/screen.h"
  #include "ui/gl/gpu_switching_manager.h"
  
  DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::NativeWindowRelay);
@@@ -53,7 -53,6 +54,6 @@@ NativeWindow::NativeWindow
        transparent_(false),
        enable_larger_than_screen_(false),
        is_closed_(false),
-       has_dialog_attached_(false),
        sheet_offset_x_(0.0),
        sheet_offset_y_(0.0),
        aspect_ratio_(0.0),
@@@ -210,7 -209,7 +210,7 @@@ gfx::Size NativeWindow::GetContentSize(
  
  void NativeWindow::SetSizeConstraints(
      const extensions::SizeConstraints& window_constraints) {
-   extensions::SizeConstraints content_constraints;
+   extensions::SizeConstraints content_constraints(GetContentSizeConstraints());
    if (window_constraints.HasMaximumSize())
      content_constraints.set_maximum_size(
          WindowSizeToContentSize(window_constraints.GetMaximumSize()));
@@@ -291,11 -290,7 +291,7 @@@ bool NativeWindow::IsDocumentEdited() 
  void NativeWindow::SetFocusable(bool focusable) {
  }
  
- void NativeWindow::SetMenu(ui::MenuModel* menu) {
- }
- bool NativeWindow::HasModalDialog() {
-   return has_dialog_attached_;
+ void NativeWindow::SetMenu(AtomMenuModel* menu) {
  }
  
  void NativeWindow::SetParentWindow(NativeWindow* parent) {
@@@ -315,39 -310,6 +311,6 @@@ bool NativeWindow::IsWebViewFocused() 
    return host_view && host_view->HasFocus();
  }
  
- void NativeWindow::CapturePage(const gfx::Rect& rect,
-                                const CapturePageCallback& callback) {
-   const auto view = web_contents()->GetRenderWidgetHostView();
-   const auto host = view ? view->GetRenderWidgetHost() : nullptr;
-   if (!view || !host) {
-     callback.Run(SkBitmap());
-     return;
-   }
-   // Capture full page if user doesn't specify a |rect|.
-   const gfx::Size view_size = rect.IsEmpty() ? view->GetViewBounds().size() :
-                                                rect.size();
-   // By default, the requested bitmap size is the view size in screen
-   // coordinates.  However, if there's more pixel detail available on the
-   // current system, increase the requested bitmap size to capture it all.
-   gfx::Size bitmap_size = view_size;
-   const gfx::NativeView native_view = view->GetNativeView();
-   const float scale =
-       display::Screen::GetScreen()->GetDisplayNearestWindow(native_view)
-       .device_scale_factor();
-   if (scale > 1.0f)
-     bitmap_size = gfx::ScaleToCeiledSize(view_size, scale);
-   host->CopyFromBackingStore(
-       gfx::Rect(rect.origin(), view_size),
-       bitmap_size,
-       base::Bind(&NativeWindow::OnCapturePageDone,
-                  weak_factory_.GetWeakPtr(),
-                  callback),
-       kBGRA_8888_SkColorType);
- }
  void NativeWindow::SetAutoHideMenuBar(bool auto_hide) {
  }
  
@@@ -394,7 -356,7 +357,7 @@@ void NativeWindow::RequestToClosePage(
      ScheduleUnresponsiveEvent(5000);
  
    if (web_contents()->NeedToFireBeforeUnload())
 -    web_contents()->DispatchBeforeUnload(false);
 +    web_contents()->DispatchBeforeUnload();
    else
      web_contents()->Close();
  }
@@@ -624,7 -586,7 +587,7 @@@ void NativeWindow::ScheduleUnresponsive
  void NativeWindow::NotifyWindowUnresponsive() {
    window_unresposive_closure_.Cancel();
  
-   if (!is_closed_ && !HasModalDialog() && IsEnabled())
+   if (!is_closed_ && !IsUnresponsiveEventSuppressed() && IsEnabled())
      FOR_EACH_OBSERVER(NativeWindowObserver,
                        observers_,
                        OnRendererUnresponsive());
@@@ -634,10 -596,4 +597,4 @@@ void NativeWindow::NotifyReadyToShow() 
    FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnReadyToShow());
  }
  
- void NativeWindow::OnCapturePageDone(const CapturePageCallback& callback,
-                                      const SkBitmap& bitmap,
-                                      content::ReadbackResponse response) {
-   callback.Run(bitmap);
- }
  }  // namespace atom
@@@ -6,13 -6,14 +6,14 @@@
  #define ATOM_BROWSER_NATIVE_WINDOW_H_
  
  #include <map>
 +#include <memory>
  #include <string>
  #include <vector>
  
  #include "atom/browser/native_window_observer.h"
  #include "atom/browser/ui/accelerator_util.h"
+ #include "atom/browser/ui/atom_menu_model.h"
  #include "base/cancelable_callback.h"
 -#include "base/memory/scoped_ptr.h"
  #include "base/memory/weak_ptr.h"
  #include "base/observer_list.h"
  #include "base/supports_user_data.h"
@@@ -43,10 -44,6 +44,6 @@@ namespace mate 
  class Dictionary;
  }
  
- namespace ui {
- class MenuModel;
- }
  namespace atom {
  
  struct DraggableRegion;
  class NativeWindow : public base::SupportsUserData,
                       public content::WebContentsObserver {
   public:
-   using CapturePageCallback = base::Callback<void(const SkBitmap& bitmap)>;
-   class DialogScope {
-    public:
-     explicit DialogScope(NativeWindow* window)
-         : window_(window) {
-       if (window_ != NULL)
-         window_->set_has_dialog_attached(true);
-     }
-     ~DialogScope() {
-       if (window_ != NULL)
-         window_->set_has_dialog_attached(false);
-     }
-    private:
-     NativeWindow* window_;
-     DISALLOW_COPY_AND_ASSIGN(DialogScope);
-   };
-   virtual ~NativeWindow();
+   ~NativeWindow() override;
  
    // Create window with existing WebContents, the caller is responsible for
    // managing the window's live.
    virtual void SetIgnoreMouseEvents(bool ignore) = 0;
    virtual void SetContentProtection(bool enable) = 0;
    virtual void SetFocusable(bool focusable);
-   virtual void SetMenu(ui::MenuModel* menu);
-   virtual bool HasModalDialog();
+   virtual void SetMenu(AtomMenuModel* menu);
    virtual void SetParentWindow(NativeWindow* parent);
    virtual gfx::NativeWindow GetNativeWindow() = 0;
    virtual gfx::AcceleratedWidget GetAcceleratedWidget() = 0;
    virtual void BlurWebView();
    virtual bool IsWebViewFocused();
  
-   // Captures the page with |rect|, |callback| would be called when capturing is
-   // done.
-   virtual void CapturePage(const gfx::Rect& rect,
-                            const CapturePageCallback& callback);
    // Toggle the menu bar.
    virtual void SetAutoHideMenuBar(bool auto_hide);
    virtual bool IsMenuBarAutoHide();
    SkRegion* draggable_region() const { return draggable_region_.get(); }
    bool enable_larger_than_screen() const { return enable_larger_than_screen_; }
  
-   void set_has_dialog_attached(bool has_dialog_attached) {
-     has_dialog_attached_ = has_dialog_attached;
-   }
    NativeWindow* parent() const { return parent_; }
    bool is_modal() const { return is_modal_; }
  
    // Dispatch ReadyToShow event to observers.
    void NotifyReadyToShow();
  
-   // Called when CapturePage has done.
-   void OnCapturePageDone(const CapturePageCallback& callback,
-                          const SkBitmap& bitmap,
-                          content::ReadbackResponse response);
    // Whether window has standard frame.
    bool has_frame_;
  
    // The windows has been closed.
    bool is_closed_;
  
-   // There is a dialog that has been attached to window.
-   bool has_dialog_attached_;
    // Closure that would be called when window is unresponsive when closing,
    // it should be cancelled when we can prove that the window is responsive.
    base::CancelableClosure window_unresposive_closure_;
@@@ -23,6 -23,7 +23,7 @@@
  #include "ui/aura/window_tree_host.h"
  #include "ui/base/hit_test.h"
  #include "ui/gfx/image/image.h"
+ #include "ui/gfx/screen.h"
  #include "ui/views/background.h"
  #include "ui/views/controls/webview/unhandled_keyboard_event_handler.h"
  #include "ui/views/controls/webview/webview.h"
@@@ -51,7 -52,7 +52,7 @@@
  #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/gfx/win/dpi.h"
 +#include "ui/display/win/screen_win.h"
  #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
  #endif
  
@@@ -135,6 -136,10 +136,10 @@@ NativeWindowViews::NativeWindowViews
        menu_bar_autohide_(false),
        menu_bar_visible_(false),
        menu_bar_alt_pressed_(false),
+ #if defined(OS_WIN)
+       enabled_a11y_support_(false),
+       thick_frame_(true),
+ #endif
        keyboard_event_handler_(new views::UnhandledKeyboardEventHandler),
        disable_count_(0),
        use_content_size_(false),
    options.Get(options::kResizable, &resizable_);
    options.Get(options::kMinimizable, &minimizable_);
    options.Get(options::kMaximizable, &maximizable_);
+   // Transparent window must not have thick frame.
+   options.Get("thickFrame", &thick_frame_);
+   if (transparent())
+     thick_frame_ = false;
  #endif
  
    if (enable_larger_than_screen())
    bool fullscreen = false;
    options.Get(options::kFullscreen, &fullscreen);
  
+   std::string window_type;
+   options.Get(options::kType, &window_type);
  #if defined(USE_X11)
    // Start monitoring window states.
    window_state_watcher_.reset(new WindowStateWatcher(this));
      state_atom_list.push_back(GetAtom("_NET_WM_STATE_FULLSCREEN"));
    }
  
-   std::string window_type;
-   options.Get(options::kType, &window_type);
    if (parent) {
      SetParentWindow(parent);
      // Force using dialog type for child window.
    AddChildView(web_view_);
  
  #if defined(OS_WIN)
-   // Save initial window state.
-   if (fullscreen)
-     last_window_state_ = ui::SHOW_STATE_FULLSCREEN;
-   else
-     last_window_state_ = ui::SHOW_STATE_NORMAL;
-   last_normal_size_ = gfx::Size(widget_size_);
    if (!has_frame()) {
      // Set Window style so that we get a minimize and maximize animation when
      // frameless.
      if (maximizable_)
        frame_style |= WS_MAXIMIZEBOX;
      // We should not show a frame for transparent window.
-     if (transparent())
+     if (!thick_frame_)
        frame_style &= ~(WS_THICKFRAME | WS_CAPTION);
      ::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, frame_style);
    }
  
-   if (transparent()) {
-     // Transparent window on Windows has to have WS_EX_COMPOSITED style.
-     LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE);
+   LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE);
+   // Window without thick frame has to have WS_EX_COMPOSITED style.
+   if (!thick_frame_)
      ex_style |= WS_EX_COMPOSITED;
-     ::SetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE, ex_style);
-   }
+   if (window_type == "toolbar")
+     ex_style |= WS_EX_TOOLWINDOW;
+   ::SetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE, ex_style);
  #endif
  
    // TODO(zcbenz): This was used to force using native frame on Windows 2003, we
  
    window_->CenterWindow(size);
    Layout();
+ #if defined(OS_WIN)
+   // Save initial window state.
+   if (fullscreen)
+     last_window_state_ = ui::SHOW_STATE_FULLSCREEN;
+   else
+     last_window_state_ = ui::SHOW_STATE_NORMAL;
+   last_normal_bounds_ = GetBounds();
+ #endif
  }
  
  NativeWindowViews::~NativeWindowViews() {
@@@ -335,10 -348,6 +348,10 @@@ void NativeWindowViews::CloseImmediatel
  }
  
  void NativeWindowViews::Focus(bool focus) {
 +  // For hidden window focus() should do nothing.
 +  if (!IsVisible())
 +    return;
 +
    if (focus) {
  #if defined(OS_WIN)
      window_->Activate();
@@@ -410,6 -419,17 +423,17 @@@ bool NativeWindowViews::IsEnabled() 
  }
  
  void NativeWindowViews::Maximize() {
+ #if defined(OS_WIN)
+   // For window without WS_THICKFRAME style, we can not call Maximize().
+   if (!thick_frame_) {
+     restore_bounds_ = GetBounds();
+     auto display =
+         gfx::Screen::GetScreen()->GetDisplayNearestPoint(GetPosition());
+     SetBounds(display.work_area(), false);
+     return;
+   }
+ #endif
    if (IsVisible())
      window_->Maximize();
    else
  }
  
  void NativeWindowViews::Unmaximize() {
+ #if defined(OS_WIN)
+   if (!thick_frame_) {
+     SetBounds(restore_bounds_, false);
+     return;
+   }
+ #endif
    window_->Restore();
  }
  
@@@ -454,6 -481,20 +485,20 @@@ void NativeWindowViews::SetFullScreen(b
      last_window_state_ = ui::SHOW_STATE_NORMAL;
      NotifyWindowLeaveFullScreen();
    }
+   // For window without WS_THICKFRAME style, we can not call SetFullscreen().
+   if (!thick_frame_) {
+     if (fullscreen) {
+       restore_bounds_ = GetBounds();
+       auto display =
+           gfx::Screen::GetScreen()->GetDisplayNearestPoint(GetPosition());
+       SetBounds(display.bounds(), false);
+     } else {
+       SetBounds(restore_bounds_, false);
+     }
+     return;
+   }
    // We set the new value after notifying, so we can handle the size event
    // correctly.
    window_->SetFullscreen(fullscreen);
    else
      window_->native_widget_private()->ShowWithWindowState(
          ui::SHOW_STATE_FULLSCREEN);
+   // Auto-hide menubar when in fullscreen.
+   if (fullscreen)
+     SetMenuBarVisibility(false);
+   else
+     SetMenuBarVisibility(!menu_bar_autohide_);
  #endif
  }
  
@@@ -470,8 -517,7 +521,7 @@@ bool NativeWindowViews::IsFullscreen() 
    return window_->IsFullscreen();
  }
  
- void NativeWindowViews::SetBounds(const gfx::Rect& bounds,
-     bool animate = false) {
+ void NativeWindowViews::SetBounds(const gfx::Rect& bounds, bool animate) {
  #if defined(USE_X11)
    // On Linux the minimum and maximum size should be updated with window size
    // when window is not resizable.
@@@ -517,7 -563,7 +567,7 @@@ void NativeWindowViews::SetContentSizeC
  
  void NativeWindowViews::SetResizable(bool resizable) {
  #if defined(OS_WIN)
-   if (!transparent())
+   if (thick_frame_)
      FlipWindowStyle(GetAcceleratedWidget(), resizable, WS_THICKFRAME);
  #elif defined(USE_X11)
    if (resizable != resizable_) {
  
  bool NativeWindowViews::IsResizable() {
  #if defined(OS_WIN)
-   return ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_THICKFRAME;
+   if (thick_frame_) {
+     return ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_THICKFRAME;
+   } else {
+     return CanResize();
+   }
  #else
    return CanResize();
  #endif
@@@ -752,7 -802,7 +806,7 @@@ void NativeWindowViews::SetFocusable(bo
  #endif
  }
  
- void NativeWindowViews::SetMenu(ui::MenuModel* menu_model) {
+ void NativeWindowViews::SetMenu(AtomMenuModel* menu_model) {
    if (menu_model == nullptr) {
      // Remove accelerators
      accelerator_table_.clear();
@@@ -1097,11 -1147,9 +1151,11 @@@ gfx::Size NativeWindowViews::ContentSiz
  
    gfx::Size window_size(size);
  #if defined(OS_WIN)
 -  gfx::Rect dpi_bounds =
 -      gfx::Rect(gfx::Point(), gfx::win::DIPToScreenSize(size));
 -  gfx::Rect window_bounds = gfx::win::ScreenToDIPRect(
 +  HWND hwnd = GetAcceleratedWidget();
 +  gfx::Rect dpi_bounds = gfx::Rect(
 +      gfx::Point(), display::win::ScreenWin::DIPToScreenSize(hwnd, size));
 +  gfx::Rect window_bounds = display::win::ScreenWin::ScreenToDIPRect(
 +      hwnd,
        window_->non_client_view()->GetWindowBoundsForClientBounds(dpi_bounds));
    window_size = window_bounds.size();
  #endif
@@@ -1117,16 -1165,16 +1171,16 @@@ gfx::Size NativeWindowViews::WindowSize
  
    gfx::Size content_size(size);
  #if defined(OS_WIN)
 -  content_size = gfx::win::DIPToScreenSize(content_size);
 +  HWND hwnd = GetAcceleratedWidget();
 +  content_size = display::win::ScreenWin::DIPToScreenSize(hwnd, content_size);
    RECT rect;
    SetRectEmpty(&rect);
 -  HWND hwnd = GetAcceleratedWidget();
    DWORD style = ::GetWindowLong(hwnd, GWL_STYLE);
    DWORD ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
    AdjustWindowRectEx(&rect, style, FALSE, ex_style);
    content_size.set_width(content_size.width() - (rect.right - rect.left));
    content_size.set_height(content_size.height() - (rect.bottom - rect.top));
 -  content_size = gfx::win::ScreenToDIPSize(content_size);
 +  content_size = display::win::ScreenWin::ScreenToDIPSize(hwnd, content_size);
  #endif
  
    if (menu_bar_ && menu_bar_visible_)
@@@ -1188,7 -1236,7 +1242,7 @@@ bool NativeWindowViews::AcceleratorPres
        &accelerator_table_, accelerator);
  }
  
- void NativeWindowViews::RegisterAccelerators(ui::MenuModel* menu_model) {
+ void NativeWindowViews::RegisterAccelerators(AtomMenuModel* menu_model) {
    // Clear previous accelerators.
    views::FocusManager* focus_manager = GetFocusManager();
    accelerator_table_.clear();
@@@ -111,7 -111,7 +111,7 @@@ void URLRequestAsarJob::Start() 
      if (rv != net::ERR_IO_PENDING)
        DidOpen(rv);
    } else if (type_ == TYPE_FILE) {
-     FileMetaInfo* meta_info = new FileMetaInfo();
+     auto* meta_info = new FileMetaInfo();
      file_task_runner_->PostTaskAndReply(
          FROM_HERE,
          base::Bind(&URLRequestAsarJob::FetchMetaInfo, file_path_,
@@@ -180,7 -180,7 +180,7 @@@ bool URLRequestAsarJob::IsRedirectRespo
  #endif
  }
  
 -net::Filter* URLRequestAsarJob::SetupFilter() const {
 +std::unique_ptr<net::Filter> URLRequestAsarJob::SetupFilter() const {
    // Bug 9936 - .svgz files needs to be decompressed.
    return base::LowerCaseEqualsASCII(file_path_.Extension(), ".svgz")
        ? net::Filter::GZipFactory() : nullptr;
@@@ -224,7 -224,7 +224,7 @@@ int URLRequestAsarJob::GetResponseCode(
  
  void URLRequestAsarJob::GetResponseInfo(net::HttpResponseInfo* info) {
    std::string status("HTTP/1.1 200 OK");
-   net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status);
+   auto* headers = new net::HttpResponseHeaders(status);
  
    headers->AddHeader(atom::kCORSHeader);
    info->headers = headers;
@@@ -338,7 -338,7 +338,7 @@@ void URLRequestAsarJob::DidRead(scoped_
      DCHECK_GE(remaining_bytes_, 0);
    }
  
-   buf = NULL;
+   buf = nullptr;
  
    ReadRawDataComplete(result);
  }
@@@ -9,7 -9,7 +9,7 @@@
  #include "ui/events/cocoa/cocoa_event_utils.h"
  #include "ui/gfx/image/image.h"
  #include "ui/gfx/mac/coordinate_conversion.h"
 -#include "ui/gfx/screen.h"
 +#include "ui/display/screen.h"
  
  namespace {
  
@@@ -44,7 -44,10 +44,10 @@@ const CGFloat kVerticalTitleMargin = 2
    inMouseEventSequence_ = NO;
  
    if ((self = [super initWithFrame: CGRectZero])) {
-     [self registerForDraggedTypes: @[NSFilenamesPboardType]];
+     [self registerForDraggedTypes: @[
+       NSFilenamesPboardType,
+       NSStringPboardType,
+     ]];
  
      // Create the status item.
      NSStatusItem * item = [[NSStatusBar systemStatusBar]
    [self setNeedsDisplay:YES];
  }
  
- - (void)popUpContextMenu:(ui::SimpleMenuModel*)menu_model {
+ - (void)popUpContextMenu:(atom::AtomMenuModel*)menu_model {
    // Show a custom menu.
    if (menu_model) {
      base::scoped_nsobject<AtomMenuController> menuController(
-         [[AtomMenuController alloc] initWithModel:menu_model]);
+         [[AtomMenuController alloc] initWithModel:menu_model
+                             useDefaultAccelerator:NO]);
      forceHighlight_ = YES;  // Should highlight when showing menu.
      [self setNeedsDisplay:YES];
      [statusItem_ popUpStatusItemMenu:[menuController menu]];
        dropFiles.push_back(base::SysNSStringToUTF8(file));
      trayIcon_->NotifyDropFiles(dropFiles);
      return YES;
+   } else if ([[pboard types] containsObject:NSStringPboardType]) {
+     NSString* dropText = [pboard stringForType:NSStringPboardType];
+     trayIcon_->NotifyDropText(base::SysNSStringToUTF8(dropText));
+     return YES;
    }
    return NO;
  }
  
@@@ -365,18 -374,19 +374,19 @@@ void TrayIconCocoa::SetHighlightMode(bo
  }
  
  void TrayIconCocoa::PopUpContextMenu(const gfx::Point& pos,
-                                      ui::SimpleMenuModel* menu_model) {
+                                      AtomMenuModel* menu_model) {
    [status_item_view_ popUpContextMenu:menu_model];
  }
  
- void TrayIconCocoa::SetContextMenu(ui::SimpleMenuModel* menu_model) {
+ void TrayIconCocoa::SetContextMenu(AtomMenuModel* menu_model) {
    // Substribe to MenuClosed event.
    if (menu_model_)
      menu_model_->RemoveObserver(this);
-   static_cast<AtomMenuModel*>(menu_model)->AddObserver(this);
+   menu_model->AddObserver(this);
  
    // Create native menu.
-   menu_.reset([[AtomMenuController alloc] initWithModel:menu_model]);
+   menu_.reset([[AtomMenuController alloc] initWithModel:menu_model
+                                   useDefaultAccelerator:NO]);
    [status_item_view_ setMenuController:menu_.get()];
  }
  
@@@ -5,18 -5,14 +5,15 @@@
  #ifndef ATOM_BROWSER_UI_VIEWS_MENU_DELEGATE_H_
  #define ATOM_BROWSER_UI_VIEWS_MENU_DELEGATE_H_
  
 -#include "base/memory/scoped_ptr.h"
 +#include <memory>
 +
+ #include "atom/browser/ui/atom_menu_model.h"
  #include "ui/views/controls/menu/menu_delegate.h"
  
  namespace views {
  class MenuRunner;
  }
  
- namespace ui {
- class MenuModel;
- }
  namespace atom {
  
  class MenuBar;
@@@ -26,7 -22,7 +23,7 @@@ class MenuDelegate : public views::Menu
    explicit MenuDelegate(MenuBar* menu_bar);
    virtual ~MenuDelegate();
  
-   void RunMenu(ui::MenuModel* model, views::MenuButton* button);
+   void RunMenu(AtomMenuModel* model, views::MenuButton* button);
  
   protected:
    // views::MenuDelegate:
@@@ -12,8 -12,8 +12,8 @@@
  #include "ui/gfx/image/image.h"
  #include "ui/gfx/geometry/point.h"
  #include "ui/gfx/geometry/rect.h"
 -#include "ui/gfx/screen.h"
 -#include "ui/gfx/win/dpi.h"
 +#include "ui/display/screen.h"
 +#include "ui/display/win/screen_win.h"
  #include "ui/views/controls/menu/menu_runner.h"
  
  namespace atom {
@@@ -132,7 -132,7 +132,7 @@@ void NotifyIcon::DisplayBalloon(HICON i
  }
  
  void NotifyIcon::PopUpContextMenu(const gfx::Point& pos,
-                                   ui::SimpleMenuModel* menu_model) {
+                                   AtomMenuModel* menu_model) {
    // Returns if context menu isn't set.
    if (menu_model == nullptr && menu_model_ == nullptr)
      return;
    // Show menu at mouse's position by default.
    gfx::Rect rect(pos, gfx::Size());
    if (pos.IsOrigin())
 -    rect.set_origin(gfx::Screen::GetScreen()->GetCursorScreenPoint());
 +    rect.set_origin(display::Screen::GetScreen()->GetCursorScreenPoint());
  
    views::MenuRunner menu_runner(
        menu_model != nullptr ? menu_model : menu_model_,
        NULL, NULL, rect, views::MENU_ANCHOR_TOPLEFT, ui::MENU_SOURCE_MOUSE));
  }
  
- void NotifyIcon::SetContextMenu(ui::SimpleMenuModel* menu_model) {
+ void NotifyIcon::SetContextMenu(AtomMenuModel* menu_model) {
    menu_model_ = menu_model;
  }
  
@@@ -167,7 -167,7 +167,7 @@@ gfx::Rect NotifyIcon::GetBounds() 
  
    RECT rect = { 0 };
    Shell_NotifyIconGetRect(&icon_id, &rect);
 -  return gfx::win::ScreenToDIPRect(gfx::Rect(rect));
 +  return display::win::ScreenWin::ScreenToDIPRect(window_, gfx::Rect(rect));
  }
  
  void NotifyIcon::InitIconData(NOTIFYICONDATA* icon_data) {
@@@ -13,6 -13,7 +13,6 @@@
  #include "atom/browser/ui/tray_icon.h"
  #include "base/macros.h"
  #include "base/compiler_specific.h"
 -#include "base/memory/scoped_ptr.h"
  #include "base/win/scoped_gdi_object.h"
  
  namespace gfx {
@@@ -51,8 -52,8 +51,8 @@@ class NotifyIcon : public TrayIcon 
                        const base::string16& title,
                        const base::string16& contents) override;
    void PopUpContextMenu(const gfx::Point& pos,
-                         ui::SimpleMenuModel* menu_model) override;
-   void SetContextMenu(ui::SimpleMenuModel* menu_model) override;
+                         AtomMenuModel* menu_model) override;
+   void SetContextMenu(AtomMenuModel* menu_model) override;
    gfx::Rect GetBounds() override;
  
   private:
@@@ -74,7 -75,7 +74,7 @@@
    base::win::ScopedHICON icon_;
  
    // The context menu.
-   ui::SimpleMenuModel* menu_model_;
+   AtomMenuModel* menu_model_;
  
    DISALLOW_COPY_AND_ASSIGN(NotifyIcon);
  };
@@@ -63,10 -63,10 +63,10 @@@ float GetScaleFactorFromPath(const base
  
    // We don't try to convert string to float here because it is very very
    // expensive.
-   for (unsigned i = 0; i < node::arraysize(kScaleFactorPairs); ++i) {
-     if (base::EndsWith(filename, kScaleFactorPairs[i].name,
+   for (const auto& kScaleFactorPair : kScaleFactorPairs) {
+     if (base::EndsWith(filename, kScaleFactorPair.name,
                         base::CompareCase::INSENSITIVE_ASCII))
-       return kScaleFactorPairs[i].scale;
+       return kScaleFactorPair.scale;
    }
  
    return 1.0f;
@@@ -81,7 -81,7 +81,7 @@@ bool AddImageSkiaRep(gfx::ImageSkia* im
    // Try PNG first.
    if (!gfx::PNGCodec::Decode(data, size, decoded.get()))
      // Try JPEG.
 -    decoded.reset(gfx::JPEGCodec::Decode(data, size));
 +    decoded = gfx::JPEGCodec::Decode(data, size);
  
    if (!decoded)
      return false;
@@@ -5,14 -5,15 +5,15 @@@
  #include "atom/common/native_mate_converters/v8_value_converter.h"
  
  #include <map>
 +#include <memory>
  #include <string>
  #include <utility>
  
  #include "base/logging.h"
 -#include "base/memory/scoped_ptr.h"
  #include "base/values.h"
  #include "native_mate/dictionary.h"
- #include "vendor/node/src/node_buffer.h"
+ #include "atom/common/node_includes.h"
  
  namespace atom {
  
@@@ -55,7 -56,7 +56,7 @@@ class V8ValueConverter::FromV8ValueStat
      // hash. Different hash obviously means different objects, but two objects
      // in a couple of thousands could have the same identity hash.
      std::pair<Iterator, Iterator> range = unique_map_.equal_range(hash);
-     for (Iterator it = range.first; it != range.second; ++it) {
+     for (auto it = range.first; it != range.second; ++it) {
        // Operator == for handles actually compares the underlying objects.
        if (it->second == handle)
          return false;
@@@ -110,32 -111,31 +111,31 @@@ base::Value* V8ValueConverter::FromV8Va
  
  v8::Local<v8::Value> V8ValueConverter::ToV8ValueImpl(
       v8::Isolate* isolate, const base::Value* value) const {
-   CHECK(value);
    switch (value->GetType()) {
      case base::Value::TYPE_NULL:
        return v8::Null(isolate);
  
      case base::Value::TYPE_BOOLEAN: {
        bool val = false;
-       CHECK(value->GetAsBoolean(&val));
+       value->GetAsBoolean(&val);
        return v8::Boolean::New(isolate, val);
      }
  
      case base::Value::TYPE_INTEGER: {
        int val = 0;
-       CHECK(value->GetAsInteger(&val));
+       value->GetAsInteger(&val);
        return v8::Integer::New(isolate, val);
      }
  
      case base::Value::TYPE_DOUBLE: {
        double val = 0.0;
-       CHECK(value->GetAsDouble(&val));
+       value->GetAsDouble(&val);
        return v8::Number::New(isolate, val);
      }
  
      case base::Value::TYPE_STRING: {
        std::string val;
-       CHECK(value->GetAsString(&val));
+       value->GetAsString(&val);
        return v8::String::NewFromUtf8(
            isolate, val.c_str(), v8::String::kNormalString, val.length());
      }
@@@ -162,11 -162,10 +162,10 @@@ v8::Local<v8::Value> V8ValueConverter::
    v8::Local<v8::Array> result(v8::Array::New(isolate, val->GetSize()));
  
    for (size_t i = 0; i < val->GetSize(); ++i) {
-     const base::Value* child = NULL;
-     CHECK(val->Get(i, &child));
+     const base::Value* child = nullptr;
+     val->Get(i, &child);
  
      v8::Local<v8::Value> child_v8 = ToV8ValueImpl(isolate, child);
-     CHECK(!child_v8.IsEmpty());
  
      v8::TryCatch try_catch;
      result->Set(static_cast<uint32_t>(i), child_v8);
@@@ -186,7 -185,6 +185,6 @@@ v8::Local<v8::Value> V8ValueConverter::
         !iter.IsAtEnd(); iter.Advance()) {
      const std::string& key = iter.key();
      v8::Local<v8::Value> child_v8 = ToV8ValueImpl(isolate, &iter.value());
-     CHECK(!child_v8.IsEmpty());
  
      v8::TryCatch try_catch;
      result.Set(key, child_v8);
@@@ -210,11 -208,9 +208,9 @@@ base::Value* V8ValueConverter::FromV8Va
      FromV8ValueState* state,
      v8::Local<v8::Value> val,
      v8::Isolate* isolate) const {
-   CHECK(!val.IsEmpty());
    FromV8ValueState::Level state_level(state);
    if (state->HasReachedMaxRecursionDepth())
-     return NULL;
+     return nullptr;
  
    if (val->IsNull())
      return base::Value::CreateNullValue().release();
  
    if (val->IsUndefined())
      // JSON.stringify ignores undefined.
-     return NULL;
+     return nullptr;
  
    if (val->IsDate()) {
      v8::Date* date = v8::Date::Cast(*val);
    if (val->IsFunction()) {
      if (!function_allowed_)
        // JSON.stringify refuses to convert function(){}.
-       return NULL;
+       return nullptr;
      return FromV8Object(val->ToObject(), state, isolate);
    }
  
    }
  
    LOG(ERROR) << "Unexpected v8 value type encountered.";
-   return NULL;
+   return nullptr;
  }
  
  base::Value* V8ValueConverter::FromV8Array(
        val->CreationContext() != isolate->GetCurrentContext())
      scope.reset(new v8::Context::Scope(val->CreationContext()));
  
-   base::ListValue* result = new base::ListValue();
+   auto* result = new base::ListValue();
  
    // Only fields with integer keys are carried over to the ListValue.
    for (uint32_t i = 0; i < val->Length(); ++i) {
@@@ -20,7 -20,6 +20,6 @@@
  #include "atom/renderer/node_array_buffer_bridge.h"
  #include "atom/renderer/preferences_manager.h"
  #include "base/command_line.h"
- #include "base/strings/utf_string_conversions.h"
  #include "chrome/renderer/media/chrome_key_systems.h"
  #include "chrome/renderer/pepper/pepper_helper.h"
  #include "chrome/renderer/printing/print_web_view_helper.h"
@@@ -32,7 -31,6 +31,6 @@@
  #include "content/public/renderer/render_view.h"
  #include "ipc/ipc_message_macros.h"
  #include "native_mate/dictionary.h"
- #include "net/base/net_errors.h"
  #include "third_party/WebKit/public/web/WebCustomElement.h"
  #include "third_party/WebKit/public/web/WebDocument.h"
  #include "third_party/WebKit/public/web/WebFrameWidget.h"
@@@ -317,20 -315,8 +315,8 @@@ content::BrowserPluginDelegate* AtomRen
    }
  }
  
- void AtomRendererClient::GetNavigationErrorStrings(
-     content::RenderFrame* render_frame,
-     const blink::WebURLRequest& failed_request,
-     const blink::WebURLError& error,
-     std::string* error_html,
-     base::string16* error_description) {
-   if (!error_description)
-     return;
-   *error_description = base::UTF8ToUTF16(net::ErrorToShortString(error.reason));
- }
 -void AtomRendererClient::AddKeySystems(
 -    std::vector<media::KeySystemInfo>* key_systems) {
 +void AtomRendererClient::AddSupportedKeySystems(
 +    std::vector<std::unique_ptr<::media::KeySystemProperties>>* key_systems) {
    AddChromeKeySystems(key_systems);
  }
  
@@@ -57,14 -57,7 +57,9 @@@ class AtomRendererClient : public conte
        content::RenderFrame* render_frame,
        const std::string& mime_type,
        const GURL& original_url) override;
-   void GetNavigationErrorStrings(content::RenderFrame* render_frame,
-                                  const blink::WebURLRequest& failed_request,
-                                  const blink::WebURLError& error,
-                                  std::string* error_html,
-                                  base::string16* error_description) override;
 -  void AddKeySystems(std::vector<media::KeySystemInfo>* key_systems) override;
 +  void AddSupportedKeySystems(
 +      std::vector<std::unique_ptr<::media::KeySystemProperties>>* key_systems)
 +      override;
  
    std::unique_ptr<NodeBindings> node_bindings_;
    std::unique_ptr<AtomBindings> atom_bindings_;
diff --combined common.gypi
      'python': 'python',
      'openssl_fips': '',
      'openssl_no_asm': 1,
+     'OPENSSL_PRODUCT': 'libopenssl.a',
      'node_release_urlbase': 'https://atom.io/download/atom-shell',
      'node_byteorder': '<!(node <(DEPTH)/tools/get-endianness.js)',
      'node_target_type': 'shared_library',
      'node_install_npm': 'false',
      'node_prefix': '',
+     'node_shared': 'true',
      'node_shared_cares': 'false',
      'node_shared_http_parser': 'false',
      'node_shared_libuv': 'false',
      'node_use_mdb': 'false',
      'node_use_openssl': 'true',
      'node_use_perfctr': 'false',
+     'node_use_v8_platform': 'false',
+     'node_use_bundled_v8': 'false',
      'uv_library': 'static_library',
      'uv_parent_path': 'vendor/node/deps/uv',
      'uv_use_dtrace': 'false',
      'V8_BASE': '',
      'v8_postmortem_support': 'false',
      'v8_enable_i18n_support': 'false',
+     'v8_inspector': 'false',
    },
    # Settings to compile node under Windows.
    'target_defaults': {
      'target_conditions': [
-       ['_target_name in ["libuv", "http_parser", "openssl", "cares", "node", "zlib"]', {
+       ['_target_name in ["libuv", "http_parser", "openssl", "openssl-cli", "cares", "node", "zlib"]', {
          'msvs_disabled_warnings': [
            4003,  # not enough actual parameters for macro 'V'
            4013,  # 'free' undefined; assuming extern returning int
                          '_uspoof_open_56',
                          '_usearch_setPattern_56',
                          '?createInstance@Transliterator@icu_56@@SAPAV12@ABVUnicodeString@2@W4UTransDirection@@AAW4UErrorCode@@@Z',
 +                        '??0MeasureFormat@icu_56@@QAE@ABVLocale@1@W4UMeasureFormatWidth@@AAW4UErrorCode@@@Z',
                        ],
                      }, {
                        'reference_symbols': [
                          'uspoof_open_56',
                          'usearch_setPattern_56',
                          '?createInstance@Transliterator@icu_56@@SAPEAV12@AEBVUnicodeString@2@W4UTransDirection@@AEAW4UErrorCode@@@Z',
 +                        '??0MeasureFormat@icu_56@@QEAA@AEBVLocale@1@W4UMeasureFormatWidth@@AEAW4UErrorCode@@@Z',
                        ],
                      }],
                    ],
@@@ -174,16 -174,19 +174,19 @@@ It creates a new `BrowserWindow` with n
      this below.
    * `titleBarStyle` String - The style of window title bar. See more about this
      below.
+   * `thickFrame` Boolean - Use `WS_THICKFRAME` style for frameless windows on
+     Windows, which adds standard window frame. Setting it to `false` will remove
+     window shadow and window animations. Default is `true`.
    * `webPreferences` Object - Settings of web page's features. See more about
      this below.
  
  When setting minimum or maximum window size with `minWidth`/`maxWidth`/
- `minHeight`/`maxHeight`, it only constrains the users, it won't prevent you from
+ `minHeight`/`maxHeight`, it only constrains the users. It won't prevent you from
  passing a size that does not follow size constraints to `setBounds`/`setSize` or
  to the constructor of `BrowserWindow`.
  
- The possible values and behaviors of `type` option are platform dependent,
supported values are:
+ The possible values and behaviors of the `type` option are platform dependent.
Possible values are:
  
  * On Linux, possible types are `desktop`, `dock`, `toolbar`, `splash`,
    `notification`.
      (`kCGDesktopWindowLevel - 1`). Note that desktop window will not receive
      focus, keyboard or mouse events, but you can use `globalShortcut` to receive
      input sparingly.
+ * On Windows, possible type is `toolbar`.
  
  The `titleBarStyle` option is only supported on macOS 10.10 Yosemite and newer.
  Possible values are:
  * `hidden-inset` results in a hidden title bar with an alternative look
    where the traffic light buttons are slightly more inset from the window edge.
  
- The `webPreferences` option is an object that can have following properties:
+ The `webPreferences` option is an object that can have the following properties:
  
  * `nodeIntegration` Boolean - Whether node integration is enabled. Default
    is `true`.
  * `session` [Session](session.md#class-session) - Sets the session used by the
    page. Instead of passing the Session object directly, you can also choose to
    use the `partition` option instead, which accepts a partition string. When
-   both `session` and `partition` are provided, `session` would be preferred.
+   both `session` and `partition` are provided, `session` will be preferred.
    Default is the default session.
  * `partition` String - Sets the session used by the page according to the
    session's partition string. If `partition` starts with `persist:`, the page
    will use a persistent session available to all pages in the app with the
-   same `partition`. if there is no `persist:` prefix, the page will use an
+   same `partition`. If there is no `persist:` prefix, the page will use an
    in-memory session. By assigning the same `partition`, multiple pages can share
    the same session. Default is the default session.
  * `zoomFactor` Number - The default zoom factor of the page, `3.0` represents
    `300%`. Default is `1.0`.
  * `javascript` Boolean - Enables JavaScript support. Default is `true`.
- * `webSecurity` Boolean - When setting `false`, it will disable the
-   same-origin policy (Usually using testing websites by people), and set
+ * `webSecurity` Boolean - When `false`, it will disable the
+   same-origin policy (usually using testing websites by people), and set
    `allowDisplayingInsecureContent` and `allowRunningInsecureContent` to
    `true` if these two options are not set by user. Default is `true`.
  * `allowDisplayingInsecureContent` Boolean - Allow an https page to display
    content like images from http URLs. Default is `false`.
- * `allowRunningInsecureContent` Boolean - Allow a https page to run
+ * `allowRunningInsecureContent` Boolean - Allow an https page to run
    JavaScript, CSS or plugins from http URLs. Default is `false`.
  * `images` Boolean - Enables image support. Default is `true`.
  * `textAreasAreResizable` Boolean - Make TextArea elements resizable. Default
    Default is `false`.
  * `experimentalCanvasFeatures` Boolean - Enables Chromium's experimental
    canvas features. Default is `false`.
 -* `directWrite` Boolean - Enables DirectWrite font rendering system on
 -  Windows. Default is `true`.
  * `scrollBounce` Boolean - Enables scroll bounce (rubber banding) effect on
    macOS. Default is `false`.
  * `blinkFeatures` String - A list of feature strings separated by `,`, like
  * `backgroundThrottling` Boolean - Whether to throttle animations and timers
    when the page becomes background. Defaults to `true`.
  
- ## Events
+ ### Instance Events
  
The `BrowserWindow` object emits the following events:
Objects created with `new BrowserWindow` emit the following events:
  
  **Note:** Some events are only available on specific operating systems and are
  labeled as such.
  
- ### Event: 'page-title-updated'
+ #### Event: 'page-title-updated'
  
  Returns:
  
  * `event` Event
  
  Emitted when the document changed its title, calling `event.preventDefault()`
- would prevent the native window's title to change.
+ will prevent the native window's title from changing.
  
- ### Event: 'close'
+ #### Event: 'close'
  
  Returns:
  
@@@ -314,87 -320,87 +318,87 @@@ window.onbeforeunload = (e) => 
  };
  ```
  
- ### Event: 'closed'
+ #### Event: 'closed'
  
  Emitted when the window is closed. After you have received this event you should
- remove the reference to the window and avoid using it anymore.
+ remove the reference to the window and avoid using it any more.
  
- ### Event: 'unresponsive'
+ #### Event: 'unresponsive'
  
  Emitted when the web page becomes unresponsive.
  
- ### Event: 'responsive'
+ #### Event: 'responsive'
  
  Emitted when the unresponsive web page becomes responsive again.
  
- ### Event: 'blur'
+ #### Event: 'blur'
  
  Emitted when the window loses focus.
  
- ### Event: 'focus'
+ #### Event: 'focus'
  
  Emitted when the window gains focus.
  
- ### Event: 'show'
+ #### Event: 'show'
  
  Emitted when the window is shown.
  
- ### Event: 'hide'
+ #### Event: 'hide'
  
  Emitted when the window is hidden.
  
- ### Event: 'ready-to-show'
+ #### Event: 'ready-to-show'
  
  Emitted when the web page has been rendered and window can be displayed without
- visual flash.
visual flash.
  
- ### Event: 'maximize'
+ #### Event: 'maximize'
  
  Emitted when window is maximized.
  
- ### Event: 'unmaximize'
+ #### Event: 'unmaximize'
  
- Emitted when the window exits from maximized state.
+ Emitted when the window exits from maximized state.
  
- ### Event: 'minimize'
+ #### Event: 'minimize'
  
  Emitted when the window is minimized.
  
- ### Event: 'restore'
+ #### Event: 'restore'
  
- Emitted when the window is restored from minimized state.
+ Emitted when the window is restored from minimized state.
  
- ### Event: 'resize'
+ #### Event: 'resize'
  
- Emitted when the window is getting resized.
+ Emitted when the window is being resized.
  
- ### Event: 'move'
+ #### Event: 'move'
  
- Emitted when the window is getting moved to a new position.
+ Emitted when the window is being moved to a new position.
  
  __Note__: On macOS this event is just an alias of `moved`.
  
- ### Event: 'moved' _macOS_
+ #### Event: 'moved' _macOS_
  
  Emitted once when the window is moved to a new position.
  
- ### Event: 'enter-full-screen'
+ #### Event: 'enter-full-screen'
  
- Emitted when the window enters full screen state.
+ Emitted when the window enters a full-screen state.
  
- ### Event: 'leave-full-screen'
+ #### Event: 'leave-full-screen'
  
- Emitted when the window leaves full screen state.
+ Emitted when the window leaves a full-screen state.
  
- ### Event: 'enter-html-full-screen'
+ #### Event: 'enter-html-full-screen'
  
- Emitted when the window enters full screen state triggered by html api.
+ Emitted when the window enters a full-screen state triggered by HTML API.
  
- ### Event: 'leave-html-full-screen'
+ #### Event: 'leave-html-full-screen'
  
- Emitted when the window leaves full screen state triggered by html api.
+ Emitted when the window leaves a full-screen state triggered by HTML API.
  
- ### Event: 'app-command' _Windows_
+ #### Event: 'app-command' _Windows_
  
  Returns:
  
@@@ -405,8 -411,8 +409,8 @@@ Emitted when an [App Command](https://m
  is invoked. These are typically related to keyboard media keys or browser
  commands, as well as the "Back" button built into some mice on Windows.
  
- Commands are lowercased with underscores replaced with hyphens and the
- `APPCOMMAND_` prefix stripped off.
+ Commands are lowercased, underscores are replaced with hyphens, and the
+ `APPCOMMAND_` prefix is stripped off.
  e.g. `APPCOMMAND_BROWSER_BACKWARD` is emitted as `browser-backward`.
  
  ```javascript
@@@ -418,15 -424,15 +422,15 @@@ someWindow.on('app-command', (e, cmd) =
  });
  ```
  
- ### Event: 'scroll-touch-begin' _macOS_
+ #### Event: 'scroll-touch-begin' _macOS_
  
  Emitted when scroll wheel event phase has begun.
  
- ### Event: 'scroll-touch-end' _macOS_
+ #### Event: 'scroll-touch-end' _macOS_
  
  Emitted when scroll wheel event phase has ended.
  
- ### Event: 'swipe' _macOS_
+ #### Event: 'swipe' _macOS_
  
  Returns:
  
  
  Emitted on 3-finger swipe. Possible directions are `up`, `right`, `down`, `left`.
  
- ## Methods
+ ### Static Methods
  
- The `BrowserWindow` object has the following methods:
+ The `BrowserWindow` class has the following static methods:
  
- ### `BrowserWindow.getAllWindows()`
+ #### `BrowserWindow.getAllWindows()`
  
  Returns an array of all opened browser windows.
  
- ### `BrowserWindow.getFocusedWindow()`
+ #### `BrowserWindow.getFocusedWindow()`
  
  Returns the window that is focused in this application, otherwise returns `null`.
  
- ### `BrowserWindow.fromWebContents(webContents)`
+ #### `BrowserWindow.fromWebContents(webContents)`
  
  * `webContents` [WebContents](web-contents.md)
  
  Find a window according to the `webContents` it owns.
  
- ### `BrowserWindow.fromId(id)`
+ #### `BrowserWindow.fromId(id)`
  
  * `id` Integer
  
  Find a window according to its ID.
  
- ### `BrowserWindow.addDevToolsExtension(path)`
+ #### `BrowserWindow.addDevToolsExtension(path)`
  
  * `path` String
  
@@@ -470,21 -476,21 +474,21 @@@ API is not for programming use. If you 
  been loaded, this method will not return and instead log a warning to the
  console.
  
Method will also not return if the extension's manifest is missing or incomplete.
The method will also not return if the extension's manifest is missing or incomplete.
  
  **Note:** This API cannot be called before the `ready` event of the `app` module
  is emitted.
  
- ### `BrowserWindow.removeDevToolsExtension(name)`
+ #### `BrowserWindow.removeDevToolsExtension(name)`
  
  * `name` String
  
- Remove the DevTools extension whose name is `name`.
+ Remove a DevTools extension by name.
  
  **Note:** This API cannot be called before the `ready` event of the `app` module
  is emitted.
  
- ### `BrowserWindow.getDevToolsExtensions()`
+ #### `BrowserWindow.getDevToolsExtensions()`
  
  Returns an Object where the keys are the extension names and each value is
  an Object containing `name` and `version` properties.
@@@ -498,7 -504,7 +502,7 @@@ let installed = BrowserWindow.getDevToo
  **Note:** This API cannot be called before the `ready` event of the `app` module
  is emitted.
  
- ## Instance Properties
+ ### Instance Properties
  
  Objects created with `new BrowserWindow` have the following properties:
  
  let win = new BrowserWindow({width: 800, height: 600});
  ```
  
- ### `win.webContents`
+ #### `win.webContents`
  
- The `WebContents` object this window owns, all web page related events and
+ The `WebContents` object this window owns. All web page related events and
  operations will be done via it.
  
  See the [`webContents` documentation](web-contents.md) for its methods and
  events.
  
- ### `win.id`
+ #### `win.id`
  
- The unique ID of this window.
+ The unique ID of the window.
  
- ## Instance Methods
+ ### Instance Methods
  
  Objects created with `new BrowserWindow` have the following instance methods:
  
  **Note:** Some methods are only available on specific operating systems and are
  labeled as such.
  
- ### `win.destroy()`
+ #### `win.destroy()`
  
  Force closing the window, the `unload` and `beforeunload` event won't be emitted
  for the web page, and `close` event will also not be emitted
  for this window, but it guarantees the `closed` event will be emitted.
  
- ### `win.close()`
+ #### `win.close()`
  
- Try to close the window, this has the same effect with user manually clicking
- the close button of the window. The web page may cancel the close though, see
+ Try to close the window. This has the same effect as a user manually clicking
+ the close button of the window. The web page may cancel the close though. See
  the [close event](#event-close).
  
- ### `win.focus()`
+ #### `win.focus()`
  
  Focuses on the window.
  
- ### `win.blur()`
+ #### `win.blur()`
  
  Removes focus from the window.
  
- ### `win.isFocused()`
+ #### `win.isFocused()`
  
  Returns a boolean, whether the window is focused.
  
- ### `win.show()`
+ #### `win.show()`
  
  Shows and gives focus to the window.
  
- ### `win.showInactive()`
+ #### `win.showInactive()`
  
  Shows the window but doesn't focus on it.
  
- ### `win.hide()`
+ #### `win.hide()`
  
  Hides the window.
  
- ### `win.isVisible()`
+ #### `win.isVisible()`
  
  Returns a boolean, whether the window is visible to the user.
  
- ### `win.isModal()`
+ #### `win.isModal()`
  
- Returns whether current window is a modal window.
+ Returns a boolean, whether current window is a modal window.
  
- ### `win.maximize()`
+ #### `win.maximize()`
  
  Maximizes the window.
  
- ### `win.unmaximize()`
+ #### `win.unmaximize()`
  
  Unmaximizes the window.
  
- ### `win.isMaximized()`
+ #### `win.isMaximized()`
  
  Returns a boolean, whether the window is maximized.
  
- ### `win.minimize()`
+ #### `win.minimize()`
  
  Minimizes the window. On some platforms the minimized window will be shown in
  the Dock.
  
- ### `win.restore()`
+ #### `win.restore()`
  
  Restores the window from minimized state to its previous state.
  
- ### `win.isMinimized()`
+ #### `win.isMinimized()`
  
  Returns a boolean, whether the window is minimized.
  
- ### `win.setFullScreen(flag)`
+ #### `win.setFullScreen(flag)`
  
  * `flag` Boolean
  
  Sets whether the window should be in fullscreen mode.
  
- ### `win.isFullScreen()`
+ #### `win.isFullScreen()`
  
  Returns a boolean, whether the window is in fullscreen mode.
  
- ### `win.setAspectRatio(aspectRatio[, extraSize])` _macOS_
+ #### `win.setAspectRatio(aspectRatio[, extraSize])` _macOS_
  
- * `aspectRatio` The aspect ratio we want to maintain for some portion of the
+ * `aspectRatio` The aspect ratio to maintain for some portion of the
  content view.
  * `extraSize` Object (optional) - The extra size not to be included while
  maintaining the aspect ratio.
    * `width` Integer
    * `height` Integer
  
- This will have a window maintain an aspect ratio. The extra size allows a
+ This will make a window maintain an aspect ratio. The extra size allows a
  developer to have space, specified in pixels, not included within the aspect
  ratio calculations. This API already takes into account the difference between a
  window's size and its content size.
@@@ -628,7 -634,7 +632,7 @@@ the player itself we would call this fu
  are within the content view--only that they exist. Just sum any extra width and
  height areas you have within the overall content view.
  
- ### `win.setBounds(options[, animate])`
+ #### `win.setBounds(options[, animate])`
  
  * `options` Object
    * `x` Integer
  
  Resizes and moves the window to `width`, `height`, `x`, `y`.
  
- ### `win.getBounds()`
+ #### `win.getBounds()`
  
  Returns an object that contains window's width, height, x and y values.
  
- ### `win.setSize(width, height[, animate])`
+ #### `win.setSize(width, height[, animate])`
  
  * `width` Integer
  * `height` Integer
  
  Resizes the window to `width` and `height`.
  
- ### `win.getSize()`
+ #### `win.getSize()`
  
  Returns an array that contains window's width and height.
  
- ### `win.setContentSize(width, height[, animate])`
+ #### `win.setContentSize(width, height[, animate])`
  
  * `width` Integer
  * `height` Integer
  
  Resizes the window's client area (e.g. the web page) to `width` and `height`.
  
- ### `win.getContentSize()`
+ #### `win.getContentSize()`
  
  Returns an array that contains window's client area's width and height.
  
- ### `win.setMinimumSize(width, height)`
+ #### `win.setMinimumSize(width, height)`
  
  * `width` Integer
  * `height` Integer
  
  Sets the minimum size of window to `width` and `height`.
  
- ### `win.getMinimumSize()`
+ #### `win.getMinimumSize()`
  
  Returns an array that contains window's minimum width and height.
  
- ### `win.setMaximumSize(width, height)`
+ #### `win.setMaximumSize(width, height)`
  
  * `width` Integer
  * `height` Integer
  
  Sets the maximum size of window to `width` and `height`.
  
- ### `win.getMaximumSize()`
+ #### `win.getMaximumSize()`
  
  Returns an array that contains window's maximum width and height.
  
- ### `win.setResizable(resizable)`
+ #### `win.setResizable(resizable)`
  
  * `resizable` Boolean
  
  Sets whether the window can be manually resized by user.
  
- ### `win.isResizable()`
+ #### `win.isResizable()`
  
  Returns whether the window can be manually resized by user.
  
- ### `win.setMovable(movable)` _macOS_ _Windows_
+ #### `win.setMovable(movable)` _macOS_ _Windows_
  
  * `movable` Boolean
  
  Sets whether the window can be moved by user. On Linux does nothing.
  
- ### `win.isMovable()` _macOS_ _Windows_
+ #### `win.isMovable()` _macOS_ _Windows_
  
  Returns whether the window can be moved by user. On Linux always returns
  `true`.
  
- ### `win.setMinimizable(minimizable)` _macOS_ _Windows_
+ #### `win.setMinimizable(minimizable)` _macOS_ _Windows_
  
  * `minimizable` Boolean
  
  Sets whether the window can be manually minimized by user. On Linux does
  nothing.
  
- ### `win.isMinimizable()` _macOS_ _Windows_
+ #### `win.isMinimizable()` _macOS_ _Windows_
  
  Returns whether the window can be manually minimized by user. On Linux always
  returns `true`.
  
- ### `win.setMaximizable(maximizable)` _macOS_ _Windows_
+ #### `win.setMaximizable(maximizable)` _macOS_ _Windows_
  
  * `maximizable` Boolean
  
  Sets whether the window can be manually maximized by user. On Linux does
  nothing.
  
- ### `win.isMaximizable()` _macOS_ _Windows_
+ #### `win.isMaximizable()` _macOS_ _Windows_
  
  Returns whether the window can be manually maximized by user. On Linux always
  returns `true`.
  
- ### `win.setFullScreenable(fullscreenable)`
+ #### `win.setFullScreenable(fullscreenable)`
  
  * `fullscreenable` Boolean
  
  Sets whether the maximize/zoom window button toggles fullscreen mode or
  maximizes the window.
  
- ### `win.isFullScreenable()`
+ #### `win.isFullScreenable()`
  
  Returns whether the maximize/zoom window button toggles fullscreen mode or
  maximizes the window.
  
- ### `win.setClosable(closable)` _macOS_ _Windows_
+ #### `win.setClosable(closable)` _macOS_ _Windows_
  
  * `closable` Boolean
  
  Sets whether the window can be manually closed by user. On Linux does nothing.
  
- ### `win.isClosable()` _macOS_ _Windows_
+ #### `win.isClosable()` _macOS_ _Windows_
  
  Returns whether the window can be manually closed by user. On Linux always
  returns `true`.
  
- ### `win.setAlwaysOnTop(flag)`
+ #### `win.setAlwaysOnTop(flag)`
  
  * `flag` Boolean
  
@@@ -765,15 -771,15 +769,15 @@@ Sets whether the window should show alw
  setting this, the window is still a normal window, not a toolbox window which
  can not be focused on.
  
- ### `win.isAlwaysOnTop()`
+ #### `win.isAlwaysOnTop()`
  
  Returns whether the window is always on top of other windows.
  
- ### `win.center()`
+ #### `win.center()`
  
  Moves window to the center of the screen.
  
- ### `win.setPosition(x, y[, animate])`
+ #### `win.setPosition(x, y[, animate])`
  
  * `x` Integer
  * `y` Integer
  
  Moves window to `x` and `y`.
  
- ### `win.getPosition()`
+ #### `win.getPosition()`
  
  Returns an array that contains window's current position.
  
- ### `win.setTitle(title)`
+ #### `win.setTitle(title)`
  
  * `title` String
  
  Changes the title of native window to `title`.
  
- ### `win.getTitle()`
+ #### `win.getTitle()`
  
  Returns the title of the native window.
  
  **Note:** The title of web page can be different from the title of the native
  window.
  
- ### `win.setSheetOffset(offsetY[, offsetX])` _macOS_
+ #### `win.setSheetOffset(offsetY[, offsetX])` _macOS_
  
  Changes the attachment point for sheets on macOS. By default, sheets are
  attached just below the window frame, but you may want to display them beneath
@@@ -809,36 -815,36 +813,36 @@@ let toolbarRect = document.getElementBy
  win.setSheetOffset(toolbarRect.height);
  ```
  
- ### `win.flashFrame(flag)`
+ #### `win.flashFrame(flag)`
  
  * `flag` Boolean
  
  Starts or stops flashing the window to attract user's attention.
  
- ### `win.setSkipTaskbar(skip)`
+ #### `win.setSkipTaskbar(skip)`
  
  * `skip` Boolean
  
  Makes the window not show in the taskbar.
  
- ### `win.setKiosk(flag)`
+ #### `win.setKiosk(flag)`
  
  * `flag` Boolean
  
  Enters or leaves the kiosk mode.
  
- ### `win.isKiosk()`
+ #### `win.isKiosk()`
  
  Returns whether the window is in kiosk mode.
  
- ### `win.getNativeWindowHandle()`
+ #### `win.getNativeWindowHandle()`
  
  Returns the platform-specific handle of the window as `Buffer`.
  
  The native type of the handle is `HWND` on Windows, `NSView*` on macOS, and
  `Window` (`unsigned long`) on Linux.
  
- ### `win.hookWindowMessage(message, callback)` _Windows_
+ #### `win.hookWindowMessage(message, callback)` _Windows_
  
  * `message` Integer
  * `callback` Function
  Hooks a windows message. The `callback` is called when
  the message is received in the WndProc.
  
- ### `win.isWindowMessageHooked(message)` _Windows_
+ #### `win.isWindowMessageHooked(message)` _Windows_
  
  * `message` Integer
  
  Returns `true` or `false` depending on whether the message is hooked.
  
- ### `win.unhookWindowMessage(message)` _Windows_
+ #### `win.unhookWindowMessage(message)` _Windows_
  
  * `message` Integer
  
  Unhook the window message.
  
- ### `win.unhookAllWindowMessages()` _Windows_
+ #### `win.unhookAllWindowMessages()` _Windows_
  
  Unhooks all of the window messages.
  
- ### `win.setRepresentedFilename(filename)` _macOS_
+ #### `win.setRepresentedFilename(filename)` _macOS_
  
  * `filename` String
  
  Sets the pathname of the file the window represents, and the icon of the file
  will show in window's title bar.
  
- ### `win.getRepresentedFilename()` _macOS_
+ #### `win.getRepresentedFilename()` _macOS_
  
  Returns the pathname of the file the window represents.
  
- ### `win.setDocumentEdited(edited)` _macOS_
+ #### `win.setDocumentEdited(edited)` _macOS_
  
  * `edited` Boolean
  
  Specifies whether the window’s document has been edited, and the icon in title
  bar will become gray when set to `true`.
  
- ### `win.isDocumentEdited()` _macOS_
+ #### `win.isDocumentEdited()` _macOS_
  
  Whether the window's document has been edited.
  
- ### `win.focusOnWebView()`
- ### `win.blurWebView()`
+ #### `win.focusOnWebView()`
  
- ### `win.capturePage([rect, ]callback)`
+ #### `win.blurWebView()`
  
- * `rect` Object (optional) - The area of page to be captured
-   * `x` Integer
-   * `y` Integer
-   * `width` Integer
-   * `height` Integer
- * `callback` Function
+ #### `win.capturePage([rect, ]callback)`
  
- Captures a snapshot of the page within `rect`. Upon completion `callback` will
- be called with `callback(image)`. The `image` is an instance of
- [NativeImage](native-image.md) that stores data of the snapshot. Omitting
- `rect` will capture the whole visible page.
+ Same as `webContents.capturePage([rect, ]callback)`.
  
- ### `win.loadURL(url[, options])`
+ #### `win.loadURL(url[, options])`
  
  Same as `webContents.loadURL(url[, options])`.
  
- ### `win.reload()`
+ #### `win.reload()`
  
  Same as `webContents.reload`.
  
- ### `win.setMenu(menu)` _Linux_ _Windows_
+ #### `win.setMenu(menu)` _Linux_ _Windows_
  
  * `menu` Menu
  
  Sets the `menu` as the window's menu bar, setting it to `null` will remove the
  menu bar.
  
- ### `win.setProgressBar(progress)`
+ #### `win.setProgressBar(progress)`
  
  * `progress` Double
  
@@@ -930,7 -926,7 +924,7 @@@ On Linux platform, only supports Unity 
  the `*.desktop` file name to `desktopName` field in `package.json`. By default,
  it will assume `app.getName().desktop`.
  
- ### `win.setOverlayIcon(overlay, description)` _Windows 7+_
+ #### `win.setOverlayIcon(overlay, description)` _Windows_
  
  * `overlay` [NativeImage](native-image.md) - the icon to display on the bottom
  right corner of the taskbar icon. If this parameter is `null`, the overlay is
@@@ -941,19 -937,19 +935,19 @@@ screen reader
  Sets a 16 x 16 pixel overlay onto the current taskbar icon, usually used to
  convey some sort of application status or to passively notify the user.
  
- ### `win.setHasShadow(hasShadow)` _macOS_
+ #### `win.setHasShadow(hasShadow)` _macOS_
  
  * `hasShadow` Boolean
  
  Sets whether the window should have a shadow. On Windows and Linux does
  nothing.
  
- ### `win.hasShadow()` _macOS_
+ #### `win.hasShadow()` _macOS_
  
  Returns whether the window has a shadow. On Windows and Linux always returns
  `true`.
  
- ### `win.setThumbarButtons(buttons)` _Windows 7+_
+ #### `win.setThumbarButtons(buttons)` _Windows_
  
  * `buttons` Array
  
@@@ -989,17 -985,30 +983,30 @@@ The `flags` is an array that can includ
    button state is drawn. This value is intended for instances where the button
    is used in a notification.
  
- ### `win.showDefinitionForSelection()` _macOS_
+ #### `win.setThumbnailClip(region)` _Windows_
+ * `region` - Object
+   * `x` Integer - x-position of region
+   * `y` Integer - y-position of region
+   * `width` Integer - width of region
+   * `height` Integer - height of region
+ Sets the region of the window to show as the thumbnail image displayed when
+ hovering over the window in the taskbar. You can reset the thumbnail to be
+ the entire window by specifying an empty region:
+ `{x: 0, y: 0, width: 0, height: 0}`.
+ #### `win.showDefinitionForSelection()` _macOS_
  
  Same as `webContents.showDefinitionForSelection()`.
  
- ### `win.setIcon(icon)` _Windows_ _Linux_
+ #### `win.setIcon(icon)` _Windows_ _Linux_
  
  * `icon` [NativeImage](native-image.md)
  
  Changes window icon.
  
- ### `win.setAutoHideMenuBar(hide)`
+ #### `win.setAutoHideMenuBar(hide)`
  
  * `hide` Boolean
  
@@@ -1009,22 -1018,22 +1016,22 @@@ menu bar will only show when users pres
  If the menu bar is already visible, calling `setAutoHideMenuBar(true)` won't
  hide it immediately.
  
- ### `win.isMenuBarAutoHide()`
+ #### `win.isMenuBarAutoHide()`
  
  Returns whether menu bar automatically hides itself.
  
- ### `win.setMenuBarVisibility(visible)`
+ #### `win.setMenuBarVisibility(visible)`
  
  * `visible` Boolean
  
  Sets whether the menu bar should be visible. If the menu bar is auto-hide, users
  can still bring up the menu bar by pressing the single `Alt` key.
  
- ### `win.isMenuBarVisible()`
+ #### `win.isMenuBarVisible()`
  
  Returns whether the menu bar is visible.
  
- ### `win.setVisibleOnAllWorkspaces(visible)`
+ #### `win.setVisibleOnAllWorkspaces(visible)`
  
  * `visible` Boolean
  
@@@ -1032,13 -1041,13 +1039,13 @@@ Sets whether the window should be visib
  
  **Note:** This API does nothing on Windows.
  
- ### `win.isVisibleOnAllWorkspaces()`
+ #### `win.isVisibleOnAllWorkspaces()`
  
  Returns whether the window is visible on all workspaces.
  
  **Note:** This API always returns false on Windows.
  
- ### `win.setIgnoreMouseEvents(ignore)`
+ #### `win.setIgnoreMouseEvents(ignore)`
  
  * `ignore` Boolean
  
@@@ -1048,14 -1057,14 +1055,14 @@@ All mouse events happened in this windo
  this window, but if this window has focus, it will still receive keyboard
  events.
  
- ### `win.setContentProtection(enable)` _macOS_ _Windows_
+ #### `win.setContentProtection(enable)` _macOS_ _Windows_
  
  Prevents the window contents from being captured by other apps.
  
  On macOS it sets the NSWindow's sharingType to NSWindowSharingNone.
  On Windows it calls SetWindowDisplayAffinity with WDA_MONITOR.
  
- ### `win.setFocusable(focusable)` _Windows_
+ #### `win.setFocusable(focusable)` _Windows_
  
  * `focusable` Boolean
  
@@@ -1063,17 -1072,17 +1070,17 @@@ Changes whether the window can be focus
  
  [blink-feature-string]: https://cs.chromium.org/chromium/src/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
  
- ### `win.setParentWindow(parent)` _Linux_ _macOS_
+ #### `win.setParentWindow(parent)` _Linux_ _macOS_
  
  * `parent` BrowserWindow
  
  Sets `parent` as current window's parent window, passing `null` will turn
  current window into a top-level window.
  
- ### `win.getParentWindow()`
+ #### `win.getParentWindow()`
  
  Returns the parent window.
  
- ### `win.getChildWindows()`
+ #### `win.getChildWindows()`
  
  Returns all child windows.
diff --combined vendor/brightray
@@@ -1,1 -1,1 +1,1 @@@
- Subproject commit df6f56413fe226095d68435320d0986f92a412ef
 -Subproject commit 91abdb01a1825c12522fd5fc2349a7ba9a091a48
++Subproject commit 38bdbe0c926b47779a45f2cf5f55105cc818a89b