Merge pull request #13 from electron/master

update as upstream
This commit is contained in:
Heilig Benedek 2016-07-31 05:19:43 +02:00 committed by GitHub
commit 015516497c
370 changed files with 6877 additions and 3476 deletions

View file

@ -1 +1 @@
v6.1.0 v6.3.0

View file

@ -75,6 +75,7 @@ npm install electron-prebuilt --save-dev
- [`electron-br`](https://electron-br.slack.com) *(브라질)* 커뮤니티 - [`electron-br`](https://electron-br.slack.com) *(브라질)* 커뮤니티
- [`electron-kr`](http://www.meetup.com/electron-kr/) *(한국)* 커뮤니티 - [`electron-kr`](http://www.meetup.com/electron-kr/) *(한국)* 커뮤니티
- [`electron-jp`](https://electron-jp-slackin.herokuapp.com/) *(일본)* 커뮤니티 - [`electron-jp`](https://electron-jp-slackin.herokuapp.com/) *(일본)* 커뮤니티
- [`electron-tr`](http://www.meetup.com/Electron-JS-Istanbul/) *(터키)* 커뮤니티
[awesome-electron](https://github.com/sindresorhus/awesome-electron) 프로젝트에 [awesome-electron](https://github.com/sindresorhus/awesome-electron) 프로젝트에
커뮤니티가 운영중인 유용한 예시 애플리케이션과 도구, 리소스가 있으니 참고하기 바랍니다. 커뮤니티가 운영중인 유용한 예시 애플리케이션과 도구, 리소스가 있으니 참고하기 바랍니다.

View file

@ -72,6 +72,8 @@ forums
- [`electron-br`](https://electron-br.slack.com) *(Brazilian Portuguese)* - [`electron-br`](https://electron-br.slack.com) *(Brazilian Portuguese)*
- [`electron-kr`](http://www.meetup.com/electron-kr/) *(Korean)* - [`electron-kr`](http://www.meetup.com/electron-kr/) *(Korean)*
- [`electron-jp`](https://electron-jp-slackin.herokuapp.com/) *(Japanese)* - [`electron-jp`](https://electron-jp-slackin.herokuapp.com/) *(Japanese)*
- [`electron-tr`](http://www.meetup.com/Electron-JS-Istanbul/) *(Turkish)*
- [`electron-id`](https://electron-id.slack.com) *(Indonesia)*
Check out [awesome-electron](https://github.com/sindresorhus/awesome-electron) Check out [awesome-electron](https://github.com/sindresorhus/awesome-electron)
for a community maintained list of useful example apps, tools and resources. for a community maintained list of useful example apps, tools and resources.

View file

@ -19,7 +19,6 @@
#include "base/win/windows_version.h" #include "base/win/windows_version.h"
#include "content/public/app/sandbox_helper_win.h" #include "content/public/app/sandbox_helper_win.h"
#include "sandbox/win/src/sandbox_types.h" #include "sandbox/win/src/sandbox_types.h"
#include "ui/gfx/win/dpi.h"
#elif defined(OS_LINUX) // defined(OS_WIN) #elif defined(OS_LINUX) // defined(OS_WIN)
#include "atom/app/atom_main_delegate.h" // NOLINT #include "atom/app/atom_main_delegate.h" // NOLINT
#include "content/public/app/content_main.h" #include "content/public/app/content_main.h"

View file

@ -7,14 +7,15 @@
#include "atom/app/uv_task_runner.h" #include "atom/app/uv_task_runner.h"
#include "atom/browser/javascript_environment.h" #include "atom/browser/javascript_environment.h"
#include "atom/browser/node_debugger.h" #include "atom/browser/node_debugger.h"
#include "atom/common/node_includes.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/feature_list.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/array_buffer.h"
#include "gin/public/isolate_holder.h" #include "gin/public/isolate_holder.h"
#include "gin/v8_initializer.h" #include "gin/v8_initializer.h"
#include "atom/common/node_includes.h"
namespace atom { namespace atom {
int NodeMain(int argc, char *argv[]) { int NodeMain(int argc, char *argv[]) {
@ -69,7 +70,7 @@ int NodeMain(int argc, char *argv[]) {
exit_code = node::EmitExit(env); exit_code = node::EmitExit(env);
node::RunAtExit(env); node::RunAtExit(env);
env->Dispose(); node::FreeEnvironment(env);
} }
v8::V8::Dispose(); v8::V8::Dispose();

View file

@ -21,7 +21,7 @@ UvTaskRunner::~UvTaskRunner() {
bool UvTaskRunner::PostDelayedTask(const tracked_objects::Location& from_here, bool UvTaskRunner::PostDelayedTask(const tracked_objects::Location& from_here,
const base::Closure& task, const base::Closure& task,
base::TimeDelta delay) { base::TimeDelta delay) {
uv_timer_t* timer = new uv_timer_t; auto* timer = new uv_timer_t;
timer->data = this; timer->data = this;
uv_timer_init(loop_, timer); uv_timer_init(loop_, timer);
uv_timer_start(timer, UvTaskRunner::OnTimeout, delay.InMilliseconds(), 0); uv_timer_start(timer, UvTaskRunner::OnTimeout, delay.InMilliseconds(), 0);

View file

@ -32,6 +32,7 @@
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "brightray/browser/brightray_paths.h" #include "brightray/browser/brightray_paths.h"
#include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_paths.h"
#include "content/public/browser/browser_accessibility_state.h"
#include "content/public/browser/client_certificate_delegate.h" #include "content/public/browser/client_certificate_delegate.h"
#include "content/public/browser/gpu_data_manager.h" #include "content/public/browser/gpu_data_manager.h"
#include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_frame_host.h"
@ -71,6 +72,30 @@ struct Converter<Browser::UserTask> {
}; };
#endif #endif
template<>
struct Converter<Browser::LoginItemSettings> {
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
Browser::LoginItemSettings* out) {
mate::Dictionary dict;
if (!ConvertFromV8(isolate, val, &dict))
return false;
dict.Get("openAtLogin", &(out->open_at_login));
dict.Get("openAsHidden", &(out->open_as_hidden));
return true;
}
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
Browser::LoginItemSettings val) {
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
dict.Set("openAtLogin", val.open_at_login);
dict.Set("openAsHidden", val.open_as_hidden);
dict.Set("restoreState", val.restore_state);
dict.Set("wasOpenedAtLogin", val.opened_at_login);
dict.Set("wasOpenedAsHidden", val.opened_as_hidden);
return dict.GetHandle();
}
};
} // namespace mate } // namespace mate
@ -254,6 +279,10 @@ void App::OnFinishLaunching() {
Emit("ready"); Emit("ready");
} }
void App::OnAccessibilitySupportChanged() {
Emit("accessibility-support-changed", IsAccessibilitySupportEnabled());
}
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
void App::OnContinueUserActivity( void App::OnContinueUserActivity(
bool* prevent_default, bool* prevent_default,
@ -459,14 +488,20 @@ void App::DisableHardwareAcceleration(mate::Arguments* args) {
content::GpuDataManager::GetInstance()->DisableHardwareAcceleration(); content::GpuDataManager::GetInstance()->DisableHardwareAcceleration();
} }
bool App::IsAccessibilitySupportEnabled() {
auto ax_state = content::BrowserAccessibilityState::GetInstance();
return ax_state->IsAccessibleBrowser();
}
#if defined(USE_NSS_CERTS) #if defined(USE_NSS_CERTS)
void App::ImportCertificate( void App::ImportCertificate(
const base::DictionaryValue& options, const base::DictionaryValue& options,
const net::CompletionCallback& callback) { const net::CompletionCallback& callback) {
auto browser_context = AtomBrowserMainParts::Get()->browser_context(); auto browser_context = AtomBrowserContext::From("", false);
if (!certificate_manager_model_) { if (!certificate_manager_model_) {
std::unique_ptr<base::DictionaryValue> copy = options.CreateDeepCopy(); std::unique_ptr<base::DictionaryValue> copy = options.CreateDeepCopy();
CertificateManagerModel::Create(browser_context, CertificateManagerModel::Create(
browser_context.get(),
base::Bind(&App::OnCertificateManagerModelCreated, base::Bind(&App::OnCertificateManagerModelCreated,
base::Unretained(this), base::Unretained(this),
base::Passed(&copy), base::Passed(&copy),
@ -519,6 +554,12 @@ void App::BuildPrototype(
base::Bind(&Browser::SetAsDefaultProtocolClient, browser)) base::Bind(&Browser::SetAsDefaultProtocolClient, browser))
.SetMethod("removeAsDefaultProtocolClient", .SetMethod("removeAsDefaultProtocolClient",
base::Bind(&Browser::RemoveAsDefaultProtocolClient, browser)) base::Bind(&Browser::RemoveAsDefaultProtocolClient, browser))
.SetMethod("setBadgeCount", base::Bind(&Browser::SetBadgeCount, browser))
.SetMethod("getBadgeCount", base::Bind(&Browser::GetBadgeCount, browser))
.SetMethod("getLoginItemSettings",
base::Bind(&Browser::GetLoginItemSettings, browser))
.SetMethod("setLoginItemSettings",
base::Bind(&Browser::SetLoginItemSettings, browser))
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
.SetMethod("hide", base::Bind(&Browser::Hide, browser)) .SetMethod("hide", base::Bind(&Browser::Hide, browser))
.SetMethod("show", base::Bind(&Browser::Show, browser)) .SetMethod("show", base::Bind(&Browser::Show, browser))
@ -528,8 +569,11 @@ void App::BuildPrototype(
base::Bind(&Browser::GetCurrentActivityType, browser)) base::Bind(&Browser::GetCurrentActivityType, browser))
#endif #endif
#if defined(OS_WIN) #if defined(OS_WIN)
.SetMethod("setUserTasks", .SetMethod("setUserTasks", base::Bind(&Browser::SetUserTasks, browser))
base::Bind(&Browser::SetUserTasks, browser)) #endif
#if defined(OS_LINUX)
.SetMethod("isUnityRunning",
base::Bind(&Browser::IsUnityRunning, browser))
#endif #endif
.SetMethod("setPath", &App::SetPath) .SetMethod("setPath", &App::SetPath)
.SetMethod("getPath", &App::GetPath) .SetMethod("getPath", &App::GetPath)
@ -541,6 +585,8 @@ void App::BuildPrototype(
.SetMethod("makeSingleInstance", &App::MakeSingleInstance) .SetMethod("makeSingleInstance", &App::MakeSingleInstance)
.SetMethod("releaseSingleInstance", &App::ReleaseSingleInstance) .SetMethod("releaseSingleInstance", &App::ReleaseSingleInstance)
.SetMethod("relaunch", &App::Relaunch) .SetMethod("relaunch", &App::Relaunch)
.SetMethod("isAccessibilitySupportEnabled",
&App::IsAccessibilitySupportEnabled)
.SetMethod("disableHardwareAcceleration", .SetMethod("disableHardwareAcceleration",
&App::DisableHardwareAcceleration); &App::DisableHardwareAcceleration);
} }

View file

@ -72,6 +72,7 @@ class App : public AtomBrowserClient::Delegate,
void OnFinishLaunching() override; void OnFinishLaunching() override;
void OnLogin(LoginHandler* login_handler, void OnLogin(LoginHandler* login_handler,
const base::DictionaryValue& request_details) override; const base::DictionaryValue& request_details) override;
void OnAccessibilitySupportChanged() override;
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
void OnContinueUserActivity( void OnContinueUserActivity(
bool* prevent_default, bool* prevent_default,
@ -113,6 +114,7 @@ class App : public AtomBrowserClient::Delegate,
void ReleaseSingleInstance(); void ReleaseSingleInstance();
bool Relaunch(mate::Arguments* args); bool Relaunch(mate::Arguments* args);
void DisableHardwareAcceleration(mate::Arguments* args); void DisableHardwareAcceleration(mate::Arguments* args);
bool IsAccessibilitySupportEnabled();
#if defined(USE_NSS_CERTS) #if defined(USE_NSS_CERTS)
void ImportCertificate(const base::DictionaryValue& options, void ImportCertificate(const base::DictionaryValue& options,
const net::CompletionCallback& callback); const net::CompletionCallback& callback);

View file

@ -109,6 +109,7 @@ void AutoUpdater::BuildPrototype(
v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> prototype) { v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype) mate::ObjectTemplateBuilder(isolate, prototype)
.SetMethod("checkForUpdates", &auto_updater::AutoUpdater::CheckForUpdates) .SetMethod("checkForUpdates", &auto_updater::AutoUpdater::CheckForUpdates)
.SetMethod("getFeedURL", &auto_updater::AutoUpdater::GetFeedURL)
.SetMethod("setFeedURL", &AutoUpdater::SetFeedURL) .SetMethod("setFeedURL", &AutoUpdater::SetFeedURL)
.SetMethod("quitAndInstall", &AutoUpdater::QuitAndInstall); .SetMethod("quitAndInstall", &AutoUpdater::QuitAndInstall);
} }

View file

@ -44,6 +44,7 @@ class AutoUpdater : public mate::EventEmitter<AutoUpdater>,
void OnWindowAllClosed() override; void OnWindowAllClosed() override;
private: private:
std::string GetFeedURL();
void SetFeedURL(const std::string& url, mate::Arguments* args); void SetFeedURL(const std::string& url, mate::Arguments* args);
void QuitAndInstall(); void QuitAndInstall();

View file

@ -4,6 +4,7 @@
#include "atom/browser/api/atom_api_cookies.h" #include "atom/browser/api/atom_api_cookies.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/gurl_converter.h" #include "atom/common/native_mate_converters/gurl_converter.h"
#include "atom/common/native_mate_converters/value_converter.h" #include "atom/common/native_mate_converters/value_converter.h"
@ -30,7 +31,7 @@ struct Converter<atom::api::Cookies::Error> {
if (val == atom::api::Cookies::SUCCESS) if (val == atom::api::Cookies::SUCCESS)
return v8::Null(isolate); return v8::Null(isolate);
else else
return v8::Exception::Error(StringToV8(isolate, "failed")); return v8::Exception::Error(StringToV8(isolate, "Setting cookie failed"));
} }
}; };
@ -204,8 +205,8 @@ void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
} // namespace } // namespace
Cookies::Cookies(v8::Isolate* isolate, Cookies::Cookies(v8::Isolate* isolate,
content::BrowserContext* browser_context) AtomBrowserContext* browser_context)
: request_context_getter_(browser_context->GetRequestContext()) { : request_context_getter_(browser_context->url_request_context_getter()) {
Init(isolate); Init(isolate);
} }
@ -241,7 +242,7 @@ void Cookies::Set(const base::DictionaryValue& details,
// static // static
mate::Handle<Cookies> Cookies::Create( mate::Handle<Cookies> Cookies::Create(
v8::Isolate* isolate, v8::Isolate* isolate,
content::BrowserContext* browser_context) { AtomBrowserContext* browser_context) {
return mate::CreateHandle(isolate, new Cookies(isolate, browser_context)); return mate::CreateHandle(isolate, new Cookies(isolate, browser_context));
} }

View file

@ -16,16 +16,14 @@ namespace base {
class DictionaryValue; class DictionaryValue;
} }
namespace content {
class BrowserContext;
}
namespace net { namespace net {
class URLRequestContextGetter; class URLRequestContextGetter;
} }
namespace atom { namespace atom {
class AtomBrowserContext;
namespace api { namespace api {
class Cookies : public mate::TrackableObject<Cookies> { class Cookies : public mate::TrackableObject<Cookies> {
@ -39,14 +37,14 @@ class Cookies : public mate::TrackableObject<Cookies> {
using SetCallback = base::Callback<void(Error)>; using SetCallback = base::Callback<void(Error)>;
static mate::Handle<Cookies> Create(v8::Isolate* isolate, static mate::Handle<Cookies> Create(v8::Isolate* isolate,
content::BrowserContext* browser_context); AtomBrowserContext* browser_context);
// mate::TrackableObject: // mate::TrackableObject:
static void BuildPrototype(v8::Isolate* isolate, static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype); v8::Local<v8::ObjectTemplate> prototype);
protected: protected:
Cookies(v8::Isolate* isolate, content::BrowserContext* browser_context); Cookies(v8::Isolate* isolate, AtomBrowserContext* browser_context);
~Cookies() override; ~Cookies() override;
void Get(const base::DictionaryValue& filter, const GetCallback& callback); void Get(const base::DictionaryValue& filter, const GetCallback& callback);

View file

@ -21,7 +21,7 @@ namespace api {
Menu::Menu(v8::Isolate* isolate) Menu::Menu(v8::Isolate* isolate)
: model_(new AtomMenuModel(this)), : model_(new AtomMenuModel(this)),
parent_(NULL) { parent_(nullptr) {
} }
Menu::~Menu() { Menu::~Menu() {
@ -53,16 +53,21 @@ bool Menu::IsCommandIdVisible(int command_id) const {
return is_visible_.Run(command_id); return is_visible_.Run(command_id);
} }
bool Menu::GetAcceleratorForCommandId(int command_id, bool Menu::GetAcceleratorForCommandIdWithParams(
ui::Accelerator* accelerator) { int command_id,
bool use_default_accelerator,
ui::Accelerator* accelerator) const {
v8::Locker locker(isolate()); v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate()); v8::HandleScope handle_scope(isolate());
v8::Local<v8::Value> val = get_accelerator_.Run(command_id); v8::Local<v8::Value> val = get_accelerator_.Run(
command_id, use_default_accelerator);
return mate::ConvertFromV8(isolate(), val, accelerator); return mate::ConvertFromV8(isolate(), val, accelerator);
} }
void Menu::ExecuteCommand(int command_id, int event_flags) { void Menu::ExecuteCommand(int command_id, int flags) {
execute_command_.Run(command_id); execute_command_.Run(
mate::internal::CreateEventFromFlags(isolate(), flags),
command_id);
} }
void Menu::MenuWillShow(ui::SimpleMenuModel* source) { void Menu::MenuWillShow(ui::SimpleMenuModel* source) {

View file

@ -5,13 +5,13 @@
#ifndef ATOM_BROWSER_API_ATOM_API_MENU_H_ #ifndef ATOM_BROWSER_API_ATOM_API_MENU_H_
#define ATOM_BROWSER_API_ATOM_API_MENU_H_ #define ATOM_BROWSER_API_ATOM_API_MENU_H_
#include <memory>
#include <string> #include <string>
#include "atom/browser/api/atom_api_window.h" #include "atom/browser/api/atom_api_window.h"
#include "atom/browser/api/trackable_object.h" #include "atom/browser/api/trackable_object.h"
#include "atom/browser/ui/atom_menu_model.h" #include "atom/browser/ui/atom_menu_model.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/memory/scoped_ptr.h"
namespace atom { namespace atom {
@ -46,8 +46,10 @@ class Menu : public mate::TrackableObject<Menu>,
bool IsCommandIdChecked(int command_id) const override; bool IsCommandIdChecked(int command_id) const override;
bool IsCommandIdEnabled(int command_id) const override; bool IsCommandIdEnabled(int command_id) const override;
bool IsCommandIdVisible(int command_id) const override; bool IsCommandIdVisible(int command_id) const override;
bool GetAcceleratorForCommandId(int command_id, bool GetAcceleratorForCommandIdWithParams(
ui::Accelerator* accelerator) override; int command_id,
bool use_default_accelerator,
ui::Accelerator* accelerator) const override;
void ExecuteCommand(int command_id, int event_flags) override; void ExecuteCommand(int command_id, int event_flags) override;
void MenuWillShow(ui::SimpleMenuModel* source) override; void MenuWillShow(ui::SimpleMenuModel* source) override;
@ -89,8 +91,8 @@ class Menu : public mate::TrackableObject<Menu>,
base::Callback<bool(int)> is_checked_; base::Callback<bool(int)> is_checked_;
base::Callback<bool(int)> is_enabled_; base::Callback<bool(int)> is_enabled_;
base::Callback<bool(int)> is_visible_; 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(int)> execute_command_; base::Callback<void(v8::Local<v8::Value>, int)> execute_command_;
base::Callback<void()> menu_will_show_; base::Callback<void()> menu_will_show_;
DISALLOW_COPY_AND_ASSIGN(Menu); DISALLOW_COPY_AND_ASSIGN(Menu);

View file

@ -5,6 +5,7 @@
#import "atom/browser/api/atom_api_menu_mac.h" #import "atom/browser/api/atom_api_menu_mac.h"
#include "atom/browser/native_window.h" #include "atom/browser/native_window.h"
#include "atom/browser/unresponsive_suppressor.h"
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
#include "base/strings/sys_string_conversions.h" #include "base/strings/sys_string_conversions.h"
#include "brightray/browser/inspectable_web_contents.h" #include "brightray/browser/inspectable_web_contents.h"
@ -30,7 +31,8 @@ void MenuMac::PopupAt(Window* window, int x, int y, int positioning_item) {
return; return;
base::scoped_nsobject<AtomMenuController> menu_controller( base::scoped_nsobject<AtomMenuController> menu_controller(
[[AtomMenuController alloc] initWithModel:model_.get()]); [[AtomMenuController alloc] initWithModel:model_.get()
useDefaultAccelerator:NO]);
NSMenu* menu = [menu_controller menu]; NSMenu* menu = [menu_controller menu];
NSView* view = web_contents->GetView()->GetNativeView(); NSView* view = web_contents->GetView()->GetNativeView();
@ -66,6 +68,9 @@ void MenuMac::PopupAt(Window* window, int x, int y, int positioning_item) {
if (rightmostMenuPoint > screenRight) if (rightmostMenuPoint > screenRight)
position.x = position.x - [menu size].width; position.x = position.x - [menu size].width;
// Don't emit unresponsive event when showing menu.
atom::UnresponsiveSuppressor suppressor;
// Show the menu. // Show the menu.
[menu popUpMenuPositioningItem:item atLocation:position inView:view]; [menu popUpMenuPositioningItem:item atLocation:position inView:view];
} }
@ -74,7 +79,8 @@ void MenuMac::PopupAt(Window* window, int x, int y, int positioning_item) {
void Menu::SetApplicationMenu(Menu* base_menu) { void Menu::SetApplicationMenu(Menu* base_menu) {
MenuMac* menu = static_cast<MenuMac*>(base_menu); MenuMac* menu = static_cast<MenuMac*>(base_menu);
base::scoped_nsobject<AtomMenuController> menu_controller( base::scoped_nsobject<AtomMenuController> menu_controller(
[[AtomMenuController alloc] initWithModel:menu->model_.get()]); [[AtomMenuController alloc] initWithModel:menu->model_.get()
useDefaultAccelerator:YES]);
[NSApp setMainMenu:[menu_controller menu]]; [NSApp setMainMenu:[menu_controller menu]];
// Ensure the menu_controller_ is destroyed after main menu is set. // Ensure the menu_controller_ is destroyed after main menu is set.

View file

@ -5,8 +5,9 @@
#include "atom/browser/api/atom_api_menu_views.h" #include "atom/browser/api/atom_api_menu_views.h"
#include "atom/browser/native_window_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 "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" #include "ui/views/controls/menu/menu_runner.h"
namespace atom { namespace atom {
@ -30,12 +31,15 @@ void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item) {
// (-1, -1) means showing on mouse location. // (-1, -1) means showing on mouse location.
gfx::Point location; gfx::Point location;
if (x == -1 || y == -1) { if (x == -1 || y == -1) {
location = gfx::Screen::GetScreen()->GetCursorScreenPoint(); location = display::Screen::GetScreen()->GetCursorScreenPoint();
} else { } else {
gfx::Point origin = view->GetViewBounds().origin(); gfx::Point origin = view->GetViewBounds().origin();
location = gfx::Point(origin.x() + x, origin.y() + y); location = gfx::Point(origin.x() + x, origin.y() + y);
} }
// Don't emit unresponsive event when showing menu.
atom::UnresponsiveSuppressor suppressor;
// Show the menu. // Show the menu.
views::MenuRunner menu_runner( views::MenuRunner menu_runner(
model(), model(),

View file

@ -6,7 +6,7 @@
#define ATOM_BROWSER_API_ATOM_API_MENU_VIEWS_H_ #define ATOM_BROWSER_API_ATOM_API_MENU_VIEWS_H_
#include "atom/browser/api/atom_api_menu.h" #include "atom/browser/api/atom_api_menu.h"
#include "ui/gfx/screen.h" #include "ui/display/screen.h"
namespace atom { namespace atom {

View file

@ -6,9 +6,9 @@
#define ATOM_BROWSER_API_ATOM_API_POWER_SAVE_BLOCKER_H_ #define ATOM_BROWSER_API_ATOM_API_POWER_SAVE_BLOCKER_H_
#include <map> #include <map>
#include <memory>
#include "atom/browser/api/trackable_object.h" #include "atom/browser/api/trackable_object.h"
#include "base/memory/scoped_ptr.h"
#include "content/public/browser/power_save_blocker.h" #include "content/public/browser/power_save_blocker.h"
#include "native_mate/handle.h" #include "native_mate/handle.h"

View file

@ -6,6 +6,7 @@
#include "atom/browser/atom_browser_client.h" #include "atom/browser/atom_browser_client.h"
#include "atom/browser/atom_browser_main_parts.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_async_asar_job.h"
#include "atom/browser/net/url_request_buffer_job.h" #include "atom/browser/net/url_request_buffer_job.h"
#include "atom/browser/net/url_request_fetch_job.h" #include "atom/browser/net/url_request_fetch_job.h"
@ -26,13 +27,30 @@ namespace atom {
namespace api { 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) Protocol::Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context)
: request_context_getter_(static_cast<brightray::URLRequestContextGetter*>( : request_context_getter_(browser_context->GetRequestContext()),
browser_context->GetRequestContext())),
weak_factory_(this) { weak_factory_(this) {
Init(isolate); Init(isolate);
} }
Protocol::~Protocol() {
content::BrowserThread::PostTask(
content::BrowserThread::IO, FROM_HERE,
base::Bind(ClearJobFactoryInIO, request_context_getter_));
}
void Protocol::RegisterServiceWorkerSchemes( void Protocol::RegisterServiceWorkerSchemes(
const std::vector<std::string>& schemes) { const std::vector<std::string>& schemes) {
atom::AtomBrowserClient::SetCustomServiceWorkerSchemes(schemes); atom::AtomBrowserClient::SetCustomServiceWorkerSchemes(schemes);
@ -174,7 +192,13 @@ void Protocol::BuildPrototype(
namespace { namespace {
void RegisterStandardSchemes( 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(); auto policy = content::ChildProcessSecurityPolicy::GetInstance();
for (const auto& scheme : schemes) { for (const auto& scheme : schemes) {
url::AddStandardScheme(scheme.c_str(), url::SCHEME_WITHOUT_PORT); url::AddStandardScheme(scheme.c_str(), url::SCHEME_WITHOUT_PORT);

View file

@ -43,6 +43,7 @@ class Protocol : public mate::TrackableObject<Protocol> {
protected: protected:
Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context); Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context);
~Protocol();
private: private:
// Possible errors. // Possible errors.

View file

@ -12,7 +12,9 @@
#include "base/bind.h" #include "base/bind.h"
#include "native_mate/dictionary.h" #include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h" #include "native_mate/object_template_builder.h"
#include "ui/gfx/screen.h" #include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/gfx/geometry/point.h"
#include "atom/common/node_includes.h" #include "atom/common/node_includes.h"
@ -34,20 +36,20 @@ typename T::iterator FindById(T* container, int id) {
// Convert the changed_metrics bitmask to string array. // Convert the changed_metrics bitmask to string array.
std::vector<std::string> MetricsToArray(uint32_t metrics) { std::vector<std::string> MetricsToArray(uint32_t metrics) {
std::vector<std::string> array; std::vector<std::string> array;
if (metrics & gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS) if (metrics & display::DisplayObserver::DISPLAY_METRIC_BOUNDS)
array.push_back("bounds"); array.push_back("bounds");
if (metrics & gfx::DisplayObserver::DISPLAY_METRIC_WORK_AREA) if (metrics & display::DisplayObserver::DISPLAY_METRIC_WORK_AREA)
array.push_back("workArea"); array.push_back("workArea");
if (metrics & gfx::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR) if (metrics & display::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR)
array.push_back("scaleFactor"); array.push_back("scaleFactor");
if (metrics & gfx::DisplayObserver::DISPLAY_METRIC_ROTATION) if (metrics & display::DisplayObserver::DISPLAY_METRIC_ROTATION)
array.push_back("rotation"); array.push_back("rotation");
return array; return array;
} }
} // namespace } // namespace
Screen::Screen(v8::Isolate* isolate, gfx::Screen* screen) Screen::Screen(v8::Isolate* isolate, display::Screen* screen)
: screen_(screen) { : screen_(screen) {
screen_->AddObserver(this); screen_->AddObserver(this);
Init(isolate); Init(isolate);
@ -61,31 +63,31 @@ gfx::Point Screen::GetCursorScreenPoint() {
return screen_->GetCursorScreenPoint(); return screen_->GetCursorScreenPoint();
} }
gfx::Display Screen::GetPrimaryDisplay() { display::Display Screen::GetPrimaryDisplay() {
return screen_->GetPrimaryDisplay(); return screen_->GetPrimaryDisplay();
} }
std::vector<gfx::Display> Screen::GetAllDisplays() { std::vector<display::Display> Screen::GetAllDisplays() {
return screen_->GetAllDisplays(); return screen_->GetAllDisplays();
} }
gfx::Display Screen::GetDisplayNearestPoint(const gfx::Point& point) { display::Display Screen::GetDisplayNearestPoint(const gfx::Point& point) {
return screen_->GetDisplayNearestPoint(point); return screen_->GetDisplayNearestPoint(point);
} }
gfx::Display Screen::GetDisplayMatching(const gfx::Rect& match_rect) { display::Display Screen::GetDisplayMatching(const gfx::Rect& match_rect) {
return screen_->GetDisplayMatching(match_rect); return screen_->GetDisplayMatching(match_rect);
} }
void Screen::OnDisplayAdded(const gfx::Display& new_display) { void Screen::OnDisplayAdded(const display::Display& new_display) {
Emit("display-added", new_display); Emit("display-added", new_display);
} }
void Screen::OnDisplayRemoved(const gfx::Display& old_display) { void Screen::OnDisplayRemoved(const display::Display& old_display) {
Emit("display-removed", old_display); Emit("display-removed", old_display);
} }
void Screen::OnDisplayMetricsChanged(const gfx::Display& display, void Screen::OnDisplayMetricsChanged(const display::Display& display,
uint32_t changed_metrics) { uint32_t changed_metrics) {
Emit("display-metrics-changed", display, MetricsToArray(changed_metrics)); Emit("display-metrics-changed", display, MetricsToArray(changed_metrics));
} }
@ -99,7 +101,7 @@ v8::Local<v8::Value> Screen::Create(v8::Isolate* isolate) {
return v8::Null(isolate); return v8::Null(isolate);
} }
gfx::Screen* screen = gfx::Screen::GetScreen(); display::Screen* screen = display::Screen::GetScreen();
if (!screen) { if (!screen) {
isolate->ThrowException(v8::Exception::Error(mate::StringToV8( isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
isolate, "Failed to get screen information"))); isolate, "Failed to get screen information")));

View file

@ -9,7 +9,8 @@
#include "atom/browser/api/event_emitter.h" #include "atom/browser/api/event_emitter.h"
#include "native_mate/handle.h" #include "native_mate/handle.h"
#include "ui/gfx/display_observer.h" #include "ui/display/display_observer.h"
#include "ui/display/screen.h"
namespace gfx { namespace gfx {
class Point; class Point;
@ -22,7 +23,7 @@ namespace atom {
namespace api { namespace api {
class Screen : public mate::EventEmitter<Screen>, class Screen : public mate::EventEmitter<Screen>,
public gfx::DisplayObserver { public display::DisplayObserver {
public: public:
static v8::Local<v8::Value> Create(v8::Isolate* isolate); static v8::Local<v8::Value> Create(v8::Isolate* isolate);
@ -30,23 +31,23 @@ class Screen : public mate::EventEmitter<Screen>,
v8::Local<v8::ObjectTemplate> prototype); v8::Local<v8::ObjectTemplate> prototype);
protected: protected:
Screen(v8::Isolate* isolate, gfx::Screen* screen); Screen(v8::Isolate* isolate, display::Screen* screen);
~Screen() override; ~Screen() override;
gfx::Point GetCursorScreenPoint(); gfx::Point GetCursorScreenPoint();
gfx::Display GetPrimaryDisplay(); display::Display GetPrimaryDisplay();
std::vector<gfx::Display> GetAllDisplays(); std::vector<display::Display> GetAllDisplays();
gfx::Display GetDisplayNearestPoint(const gfx::Point& point); display::Display GetDisplayNearestPoint(const gfx::Point& point);
gfx::Display GetDisplayMatching(const gfx::Rect& match_rect); display::Display GetDisplayMatching(const gfx::Rect& match_rect);
// gfx::DisplayObserver: // display::DisplayObserver:
void OnDisplayAdded(const gfx::Display& new_display) override; void OnDisplayAdded(const display::Display& new_display) override;
void OnDisplayRemoved(const gfx::Display& old_display) override; void OnDisplayRemoved(const display::Display& old_display) override;
void OnDisplayMetricsChanged(const gfx::Display& display, void OnDisplayMetricsChanged(const display::Display& display,
uint32_t changed_metrics) override; uint32_t changed_metrics) override;
private: private:
gfx::Screen* screen_; display::Screen* screen_;
DISALLOW_COPY_AND_ASSIGN(Screen); DISALLOW_COPY_AND_ASSIGN(Screen);
}; };

View file

@ -11,6 +11,7 @@
#include "atom/browser/api/atom_api_download_item.h" #include "atom/browser/api/atom_api_download_item.h"
#include "atom/browser/api/atom_api_protocol.h" #include "atom/browser/api/atom_api_protocol.h"
#include "atom/browser/api/atom_api_web_request.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_context.h"
#include "atom/browser/atom_browser_main_parts.h" #include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/atom_permission_manager.h" #include "atom/browser/atom_permission_manager.h"
@ -20,13 +21,14 @@
#include "atom/common/native_mate_converters/gurl_converter.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/file_path_converter.h"
#include "atom/common/native_mate_converters/net_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 "atom/common/node_includes.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/guid.h" #include "base/guid.h"
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.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_conditions.h"
#include "brightray/browser/net/devtools_network_controller_handle.h" #include "brightray/browser/net/devtools_network_controller_handle.h"
#include "chrome/common/pref_names.h" #include "chrome/common/pref_names.h"
@ -41,8 +43,10 @@
#include "net/http/http_auth_preferences.h" #include "net/http/http_auth_preferences.h"
#include "net/proxy/proxy_service.h" #include "net/proxy/proxy_service.h"
#include "net/proxy/proxy_config_service_fixed.h" #include "net/proxy/proxy_config_service_fixed.h"
#include "net/url_request/static_http_user_agent_settings.h"
#include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_context_getter.h"
#include "ui/base/l10n/l10n_util.h"
using content::BrowserThread; using content::BrowserThread;
using content::StoragePartition; using content::StoragePartition;
@ -93,6 +97,15 @@ uint32_t GetQuotaMask(const std::vector<std::string>& quota_types) {
return quota_mask; return quota_mask;
} }
void SetUserAgentInIO(scoped_refptr<net::URLRequestContextGetter> getter,
const std::string& accept_lang,
const std::string& user_agent) {
getter->GetURLRequestContext()->set_http_user_agent_settings(
new net::StaticHttpUserAgentSettings(
net::HttpUtil::GenerateAcceptLanguageHeader(accept_lang),
user_agent));
}
} // namespace } // namespace
namespace mate { namespace mate {
@ -120,7 +133,7 @@ struct Converter<net::ProxyConfig> {
static bool FromV8(v8::Isolate* isolate, static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val, v8::Local<v8::Value> val,
net::ProxyConfig* out) { net::ProxyConfig* out) {
std::string proxy_rules; std::string proxy_rules, proxy_bypass_rules;
GURL pac_url; GURL pac_url;
mate::Dictionary options; mate::Dictionary options;
// Fallback to previous API when passed String. // Fallback to previous API when passed String.
@ -130,6 +143,7 @@ struct Converter<net::ProxyConfig> {
} else if (ConvertFromV8(isolate, val, &options)) { } else if (ConvertFromV8(isolate, val, &options)) {
options.Get("pacScript", &pac_url); options.Get("pacScript", &pac_url);
options.Get("proxyRules", &proxy_rules); options.Get("proxyRules", &proxy_rules);
options.Get("proxyBypassRules", &proxy_bypass_rules);
} else { } else {
return false; return false;
} }
@ -139,6 +153,7 @@ struct Converter<net::ProxyConfig> {
out->set_pac_url(pac_url); out->set_pac_url(pac_url);
} else { } else {
out->proxy_rules().ParseFromString(proxy_rules); out->proxy_rules().ParseFromString(proxy_rules);
out->proxy_rules().bypass_rules.ParseFromString(proxy_bypass_rules);
} }
return true; return true;
} }
@ -152,6 +167,8 @@ namespace api {
namespace { namespace {
const char kPersistPrefix[] = "persist:";
// The wrapSession funtion which is implemented in JavaScript // The wrapSession funtion which is implemented in JavaScript
using WrapSessionCallback = base::Callback<void(v8::Local<v8::Value>)>; using WrapSessionCallback = base::Callback<void(v8::Local<v8::Value>)>;
WrapSessionCallback g_wrap_session; WrapSessionCallback g_wrap_session;
@ -164,7 +181,7 @@ class ResolveProxyHelper {
: callback_(callback), : callback_(callback),
original_thread_(base::ThreadTaskRunnerHandle::Get()) { original_thread_(base::ThreadTaskRunnerHandle::Get()) {
scoped_refptr<net::URLRequestContextGetter> context_getter = scoped_refptr<net::URLRequestContextGetter> context_getter =
browser_context->GetRequestContext(); browser_context->url_request_context_getter();
context_getter->GetNetworkTaskRunner()->PostTask( context_getter->GetNetworkTaskRunner()->PostTask(
FROM_HERE, FROM_HERE,
base::Bind(&ResolveProxyHelper::ResolveProxy, base::Bind(&ResolveProxyHelper::ResolveProxy,
@ -230,10 +247,10 @@ void OnGetBackend(disk_cache::Backend** backend_ptr,
} else if (action == Session::CacheAction::STATS) { } else if (action == Session::CacheAction::STATS) {
base::StringPairs stats; base::StringPairs stats;
(*backend_ptr)->GetStats(&stats); (*backend_ptr)->GetStats(&stats);
for (size_t i = 0; i < stats.size(); ++i) { for (const auto& stat : stats) {
if (stats[i].first == "Current size") { if (stat.first == "Current size") {
int current_size; int current_size;
base::StringToInt(stats[i].second, &current_size); base::StringToInt(stat.second, &current_size);
RunCallbackInUI(callback, current_size); RunCallbackInUI(callback, current_size);
break; break;
} }
@ -255,7 +272,7 @@ void DoCacheActionInIO(
// Call GetBackend and make the backend's ptr accessable in OnGetBackend. // Call GetBackend and make the backend's ptr accessable in OnGetBackend.
using BackendPtr = disk_cache::Backend*; using BackendPtr = disk_cache::Backend*;
BackendPtr* backend_ptr = new BackendPtr(nullptr); auto* backend_ptr = new BackendPtr(nullptr);
net::CompletionCallback on_get_backend = net::CompletionCallback on_get_backend =
base::Bind(&OnGetBackend, base::Owned(backend_ptr), action, callback); base::Bind(&OnGetBackend, base::Owned(backend_ptr), action, callback);
int rv = http_cache->GetBackend(backend_ptr, on_get_backend); int rv = http_cache->GetBackend(backend_ptr, on_get_backend);
@ -267,13 +284,21 @@ void SetProxyInIO(net::URLRequestContextGetter* getter,
const net::ProxyConfig& config, const net::ProxyConfig& config,
const base::Closure& callback) { const base::Closure& callback) {
auto proxy_service = getter->GetURLRequestContext()->proxy_service(); auto proxy_service = getter->GetURLRequestContext()->proxy_service();
proxy_service->ResetConfigService(make_scoped_ptr( proxy_service->ResetConfigService(base::WrapUnique(
new net::ProxyConfigServiceFixed(config))); new net::ProxyConfigServiceFixed(config)));
// Refetches and applies the new pac script if provided. // Refetches and applies the new pac script if provided.
proxy_service->ForceReloadProxyConfig(); proxy_service->ForceReloadProxyConfig();
RunCallbackInUI(callback); 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( void ClearHostResolverCacheInIO(
const scoped_refptr<net::URLRequestContextGetter>& context_getter, const scoped_refptr<net::URLRequestContextGetter>& context_getter,
const base::Closure& callback) { const base::Closure& callback) {
@ -300,6 +325,11 @@ void AllowNTLMCredentialsForDomainsInIO(
} }
} }
void OnClearStorageDataDone(const base::Closure& callback) {
if (!callback.is_null())
callback.Run();
}
} // namespace } // namespace
Session::Session(v8::Isolate* isolate, AtomBrowserContext* browser_context) Session::Session(v8::Isolate* isolate, AtomBrowserContext* browser_context)
@ -349,21 +379,19 @@ void Session::DoCacheAction(const net::CompletionCallback& callback) {
} }
void Session::ClearStorageData(mate::Arguments* args) { void Session::ClearStorageData(mate::Arguments* args) {
// clearStorageData([options, ]callback) // clearStorageData([options, callback])
ClearStorageDataOptions options; ClearStorageDataOptions options;
args->GetNext(&options);
base::Closure callback; base::Closure callback;
if (!args->GetNext(&callback)) { args->GetNext(&options);
args->ThrowError(); args->GetNext(&callback);
return;
}
auto storage_partition = auto storage_partition =
content::BrowserContext::GetStoragePartition(browser_context(), nullptr); content::BrowserContext::GetStoragePartition(browser_context(), nullptr);
storage_partition->ClearData( storage_partition->ClearData(
options.storage_types, options.quota_types, options.origin, options.storage_types, options.quota_types, options.origin,
content::StoragePartition::OriginMatcherFunction(), content::StoragePartition::OriginMatcherFunction(),
base::Time(), base::Time::Max(), callback); base::Time(), base::Time::Max(),
base::Bind(&OnClearStorageDataDone, callback));
} }
void Session::FlushStorageData() { void Session::FlushStorageData() {
@ -423,7 +451,10 @@ void Session::SetCertVerifyProc(v8::Local<v8::Value> val,
return; 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, void Session::SetPermissionRequestHandler(v8::Local<v8::Value> val,
@ -455,6 +486,23 @@ void Session::AllowNTLMCredentialsForDomains(const std::string& domains) {
domains)); domains));
} }
void Session::SetUserAgent(const std::string& user_agent,
mate::Arguments* args) {
browser_context_->SetUserAgent(user_agent);
std::string accept_lang = l10n_util::GetApplicationLocale("");
args->GetNext(&accept_lang);
auto getter = browser_context_->GetRequestContext();
getter->GetNetworkTaskRunner()->PostTask(
FROM_HERE,
base::Bind(&SetUserAgentInIO, getter, accept_lang, user_agent));
}
std::string Session::GetUserAgent() {
return browser_context_->GetUserAgent();
}
v8::Local<v8::Value> Session::Cookies(v8::Isolate* isolate) { v8::Local<v8::Value> Session::Cookies(v8::Isolate* isolate) {
if (cookies_.IsEmpty()) { if (cookies_.IsEmpty()) {
auto handle = atom::api::Cookies::Create(isolate, browser_context()); auto handle = atom::api::Cookies::Create(isolate, browser_context());
@ -494,10 +542,19 @@ mate::Handle<Session> Session::CreateFrom(
// static // static
mate::Handle<Session> Session::FromPartition( mate::Handle<Session> Session::FromPartition(
v8::Isolate* isolate, const std::string& partition, bool in_memory) { v8::Isolate* isolate, const std::string& partition,
auto browser_context = brightray::BrowserContext::From(partition, in_memory); const base::DictionaryValue& options) {
return CreateFrom(isolate, scoped_refptr<AtomBrowserContext> browser_context;
static_cast<AtomBrowserContext*>(browser_context.get())); 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 // static
@ -520,6 +577,8 @@ void Session::BuildPrototype(v8::Isolate* isolate,
.SetMethod("clearHostResolverCache", &Session::ClearHostResolverCache) .SetMethod("clearHostResolverCache", &Session::ClearHostResolverCache)
.SetMethod("allowNTLMCredentialsForDomains", .SetMethod("allowNTLMCredentialsForDomains",
&Session::AllowNTLMCredentialsForDomains) &Session::AllowNTLMCredentialsForDomains)
.SetMethod("setUserAgent", &Session::SetUserAgent)
.SetMethod("getUserAgent", &Session::GetUserAgent)
.SetProperty("cookies", &Session::Cookies) .SetProperty("cookies", &Session::Cookies)
.SetProperty("protocol", &Session::Protocol) .SetProperty("protocol", &Session::Protocol)
.SetProperty("webRequest", &Session::WebRequest); .SetProperty("webRequest", &Session::WebRequest);
@ -535,11 +594,23 @@ void SetWrapSession(const WrapSessionCallback& callback) {
namespace { 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, void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) { v8::Local<v8::Context> context, void* priv) {
v8::Isolate* isolate = context->GetIsolate(); v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports); mate::Dictionary dict(isolate, exports);
dict.SetMethod("fromPartition", &atom::api::Session::FromPartition); dict.SetMethod("fromPartition", &FromPartition);
dict.SetMethod("_setWrapSession", &atom::api::SetWrapSession); dict.SetMethod("_setWrapSession", &atom::api::SetWrapSession);
} }

View file

@ -8,6 +8,7 @@
#include <string> #include <string>
#include "atom/browser/api/trackable_object.h" #include "atom/browser/api/trackable_object.h"
#include "base/values.h"
#include "content/public/browser/download_manager.h" #include "content/public/browser/download_manager.h"
#include "native_mate/handle.h" #include "native_mate/handle.h"
#include "net/base/completion_callback.h" #include "net/base/completion_callback.h"
@ -47,9 +48,10 @@ class Session: public mate::TrackableObject<Session>,
static mate::Handle<Session> CreateFrom( static mate::Handle<Session> CreateFrom(
v8::Isolate* isolate, AtomBrowserContext* browser_context); v8::Isolate* isolate, AtomBrowserContext* browser_context);
// Gets the Session of |partition| and |in_memory|. // Gets the Session of |partition|.
static mate::Handle<Session> FromPartition( static mate::Handle<Session> FromPartition(
v8::Isolate* isolate, const std::string& partition, bool in_memory); v8::Isolate* isolate, const std::string& partition,
const base::DictionaryValue& options = base::DictionaryValue());
AtomBrowserContext* browser_context() const { return browser_context_.get(); } AtomBrowserContext* browser_context() const { return browser_context_.get(); }
@ -57,15 +59,7 @@ class Session: public mate::TrackableObject<Session>,
static void BuildPrototype(v8::Isolate* isolate, static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype); v8::Local<v8::ObjectTemplate> prototype);
protected: // Methods.
Session(v8::Isolate* isolate, AtomBrowserContext* browser_context);
~Session();
// content::DownloadManager::Observer:
void OnDownloadCreated(content::DownloadManager* manager,
content::DownloadItem* item) override;
private:
void ResolveProxy(const GURL& url, ResolveProxyCallback callback); void ResolveProxy(const GURL& url, ResolveProxyCallback callback);
template<CacheAction action> template<CacheAction action>
void DoCacheAction(const net::CompletionCallback& callback); void DoCacheAction(const net::CompletionCallback& callback);
@ -80,10 +74,21 @@ class Session: public mate::TrackableObject<Session>,
mate::Arguments* args); mate::Arguments* args);
void ClearHostResolverCache(mate::Arguments* args); void ClearHostResolverCache(mate::Arguments* args);
void AllowNTLMCredentialsForDomains(const std::string& domains); void AllowNTLMCredentialsForDomains(const std::string& domains);
void SetUserAgent(const std::string& user_agent, mate::Arguments* args);
std::string GetUserAgent();
v8::Local<v8::Value> Cookies(v8::Isolate* isolate); v8::Local<v8::Value> Cookies(v8::Isolate* isolate);
v8::Local<v8::Value> Protocol(v8::Isolate* isolate); v8::Local<v8::Value> Protocol(v8::Isolate* isolate);
v8::Local<v8::Value> WebRequest(v8::Isolate* isolate); v8::Local<v8::Value> WebRequest(v8::Isolate* isolate);
protected:
Session(v8::Isolate* isolate, AtomBrowserContext* browser_context);
~Session();
// content::DownloadManager::Observer:
void OnDownloadCreated(content::DownloadManager* manager,
content::DownloadItem* item) override;
private:
// Cached object. // Cached object.
v8::Global<v8::Value> cookies_; v8::Global<v8::Value> cookies_;
v8::Global<v8::Value> protocol_; v8::Global<v8::Value> protocol_;

View file

@ -53,6 +53,10 @@ void SystemPreferences::BuildPrototype(
&SystemPreferences::SubscribeNotification) &SystemPreferences::SubscribeNotification)
.SetMethod("unsubscribeNotification", .SetMethod("unsubscribeNotification",
&SystemPreferences::UnsubscribeNotification) &SystemPreferences::UnsubscribeNotification)
.SetMethod("subscribeLocalNotification",
&SystemPreferences::SubscribeLocalNotification)
.SetMethod("unsubscribeLocalNotification",
&SystemPreferences::UnsubscribeLocalNotification)
.SetMethod("getUserDefault", &SystemPreferences::GetUserDefault) .SetMethod("getUserDefault", &SystemPreferences::GetUserDefault)
#endif #endif
.SetMethod("isDarkMode", &SystemPreferences::IsDarkMode); .SetMethod("isDarkMode", &SystemPreferences::IsDarkMode);

View file

@ -26,17 +26,18 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences> {
static void BuildPrototype(v8::Isolate* isolate, static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype); v8::Local<v8::ObjectTemplate> prototype);
#if defined(OS_MACOSX)
using NotificationCallback = base::Callback<
void(const std::string&, const base::DictionaryValue&)>;
#endif
#if defined(OS_WIN) #if defined(OS_WIN)
bool IsAeroGlassEnabled(); bool IsAeroGlassEnabled();
#elif defined(OS_MACOSX) #elif defined(OS_MACOSX)
using NotificationCallback = base::Callback<
void(const std::string&, const base::DictionaryValue&)>;
int SubscribeNotification(const std::string& name, int SubscribeNotification(const std::string& name,
const NotificationCallback& callback); const NotificationCallback& callback);
void UnsubscribeNotification(int id); void UnsubscribeNotification(int id);
int SubscribeLocalNotification(const std::string& name,
const NotificationCallback& callback);
void UnsubscribeLocalNotification(int request_id);
v8::Local<v8::Value> GetUserDefault(const std::string& name, v8::Local<v8::Value> GetUserDefault(const std::string& name,
const std::string& type); const std::string& type);
#endif #endif
@ -46,6 +47,13 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences> {
explicit SystemPreferences(v8::Isolate* isolate); explicit SystemPreferences(v8::Isolate* isolate);
~SystemPreferences() override; ~SystemPreferences() override;
#if defined(OS_MACOSX)
int DoSubscribeNotification(const std::string& name,
const NotificationCallback& callback,
bool is_local);
void DoUnsubscribeNotification(int request_id, bool is_local);
#endif
private: private:
DISALLOW_COPY_AND_ASSIGN(SystemPreferences); DISALLOW_COPY_AND_ASSIGN(SystemPreferences);
}; };

View file

@ -30,34 +30,59 @@ std::map<int, id> g_id_map;
int SystemPreferences::SubscribeNotification( int SystemPreferences::SubscribeNotification(
const std::string& name, const NotificationCallback& callback) { const std::string& name, const NotificationCallback& callback) {
return DoSubscribeNotification(name, callback, false);
}
void SystemPreferences::UnsubscribeNotification(int request_id) {
DoUnsubscribeNotification(request_id, false);
}
int SystemPreferences::SubscribeLocalNotification(
const std::string& name, const NotificationCallback& callback) {
return DoSubscribeNotification(name, callback, true);
}
void SystemPreferences::UnsubscribeLocalNotification(int request_id) {
DoUnsubscribeNotification(request_id, true);
}
int SystemPreferences::DoSubscribeNotification(const std::string& name,
const NotificationCallback& callback, bool is_local) {
int request_id = g_next_id++; int request_id = g_next_id++;
__block NotificationCallback copied_callback = callback; __block NotificationCallback copied_callback = callback;
g_id_map[request_id] = [[NSDistributedNotificationCenter defaultCenter] NSNotificationCenter* center = is_local ?
addObserverForName:base::SysUTF8ToNSString(name) [NSNotificationCenter defaultCenter] :
object:nil [NSDistributedNotificationCenter defaultCenter];
queue:nil
usingBlock:^(NSNotification* notification) { g_id_map[request_id] = [center
std::unique_ptr<base::DictionaryValue> user_info = addObserverForName:base::SysUTF8ToNSString(name)
NSDictionaryToDictionaryValue(notification.userInfo); object:nil
if (user_info) { queue:nil
copied_callback.Run( usingBlock:^(NSNotification* notification) {
base::SysNSStringToUTF8(notification.name), std::unique_ptr<base::DictionaryValue> user_info =
*user_info); NSDictionaryToDictionaryValue(notification.userInfo);
} else { if (user_info) {
copied_callback.Run( copied_callback.Run(
base::SysNSStringToUTF8(notification.name), base::SysNSStringToUTF8(notification.name),
base::DictionaryValue()); *user_info);
} } else {
copied_callback.Run(
base::SysNSStringToUTF8(notification.name),
base::DictionaryValue());
} }
}
]; ];
return request_id; return request_id;
} }
void SystemPreferences::UnsubscribeNotification(int request_id) { void SystemPreferences::DoUnsubscribeNotification(int request_id, bool is_local) {
auto iter = g_id_map.find(request_id); auto iter = g_id_map.find(request_id);
if (iter != g_id_map.end()) { if (iter != g_id_map.end()) {
id observer = iter->second; id observer = iter->second;
[[NSDistributedNotificationCenter defaultCenter] removeObserver:observer]; NSNotificationCenter* center = is_local ?
[NSNotificationCenter defaultCenter] :
[NSDistributedNotificationCenter defaultCenter];
[center removeObserver:observer];
g_id_map.erase(iter); g_id_map.erase(iter);
} }
} }

View file

@ -8,7 +8,6 @@
#include "atom/browser/api/atom_api_menu.h" #include "atom/browser/api/atom_api_menu.h"
#include "atom/browser/browser.h" #include "atom/browser/browser.h"
#include "atom/browser/ui/tray_icon.h"
#include "atom/common/api/atom_api_native_image.h" #include "atom/common/api/atom_api_native_image.h"
#include "atom/common/native_mate_converters/gfx_converter.h" #include "atom/common/native_mate_converters/gfx_converter.h"
#include "atom/common/native_mate_converters/image_converter.h" #include "atom/common/native_mate_converters/image_converter.h"
@ -16,9 +15,47 @@
#include "atom/common/node_includes.h" #include "atom/common/node_includes.h"
#include "native_mate/constructor.h" #include "native_mate/constructor.h"
#include "native_mate/dictionary.h" #include "native_mate/dictionary.h"
#include "ui/events/event_constants.h"
#include "ui/gfx/image/image.h" #include "ui/gfx/image/image.h"
namespace mate {
template<>
struct Converter<atom::TrayIcon::HighlightMode> {
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
atom::TrayIcon::HighlightMode* out) {
std::string mode;
if (ConvertFromV8(isolate, val, &mode)) {
if (mode == "always") {
*out = atom::TrayIcon::HighlightMode::ALWAYS;
return true;
}
if (mode == "selection") {
*out = atom::TrayIcon::HighlightMode::SELECTION;
return true;
}
if (mode == "never") {
*out = atom::TrayIcon::HighlightMode::NEVER;
return true;
}
}
// Support old boolean parameter
// TODO(kevinsawicki): Remove in 2.0, deprecate before then with warnings
bool highlight;
if (ConvertFromV8(isolate, val, &highlight)) {
if (highlight)
*out = atom::TrayIcon::HighlightMode::SELECTION;
else
*out = atom::TrayIcon::HighlightMode::NEVER;
return true;
}
return false;
}
};
} // namespace mate
namespace atom { namespace atom {
namespace api { namespace api {
@ -30,6 +67,8 @@ Tray::Tray(v8::Isolate* isolate, mate::Handle<NativeImage> image)
} }
Tray::~Tray() { Tray::~Tray() {
// Destroy the native tray in next tick.
base::MessageLoop::current()->DeleteSoon(FROM_HERE, tray_icon_.release());
} }
// static // static
@ -44,24 +83,15 @@ mate::WrappableBase* Tray::New(v8::Isolate* isolate,
} }
void Tray::OnClicked(const gfx::Rect& bounds, int modifiers) { void Tray::OnClicked(const gfx::Rect& bounds, int modifiers) {
v8::Locker locker(isolate()); EmitWithFlags("click", modifiers, bounds);
v8::HandleScope handle_scope(isolate());
EmitCustomEvent("click",
ModifiersToObject(isolate(), modifiers), bounds);
} }
void Tray::OnDoubleClicked(const gfx::Rect& bounds, int modifiers) { void Tray::OnDoubleClicked(const gfx::Rect& bounds, int modifiers) {
v8::Locker locker(isolate()); EmitWithFlags("double-click", modifiers, bounds);
v8::HandleScope handle_scope(isolate());
EmitCustomEvent("double-click",
ModifiersToObject(isolate(), modifiers), bounds);
} }
void Tray::OnRightClicked(const gfx::Rect& bounds, int modifiers) { void Tray::OnRightClicked(const gfx::Rect& bounds, int modifiers) {
v8::Locker locker(isolate()); EmitWithFlags("right-click", modifiers, bounds);
v8::HandleScope handle_scope(isolate());
EmitCustomEvent("right-click",
ModifiersToObject(isolate(), modifiers), bounds);
} }
void Tray::OnBalloonShow() { void Tray::OnBalloonShow() {
@ -84,6 +114,10 @@ void Tray::OnDropFiles(const std::vector<std::string>& files) {
Emit("drop-files", files); Emit("drop-files", files);
} }
void Tray::OnDropText(const std::string& text) {
Emit("drop-text", text);
}
void Tray::OnDragEntered() { void Tray::OnDragEntered() {
Emit("drag-enter"); Emit("drag-enter");
} }
@ -121,8 +155,8 @@ void Tray::SetTitle(const std::string& title) {
tray_icon_->SetTitle(title); tray_icon_->SetTitle(title);
} }
void Tray::SetHighlightMode(bool highlight) { void Tray::SetHighlightMode(TrayIcon::HighlightMode mode) {
tray_icon_->SetHighlightMode(highlight); tray_icon_->SetHighlightMode(mode);
} }
void Tray::DisplayBalloon(mate::Arguments* args, void Tray::DisplayBalloon(mate::Arguments* args,
@ -159,14 +193,8 @@ void Tray::SetContextMenu(v8::Isolate* isolate, mate::Handle<Menu> menu) {
tray_icon_->SetContextMenu(menu->model()); tray_icon_->SetContextMenu(menu->model());
} }
v8::Local<v8::Object> Tray::ModifiersToObject(v8::Isolate* isolate, gfx::Rect Tray::GetBounds() {
int modifiers) { return tray_icon_->GetBounds();
mate::Dictionary obj(isolate, v8::Object::New(isolate));
obj.Set("shiftKey", static_cast<bool>(modifiers & ui::EF_SHIFT_DOWN));
obj.Set("ctrlKey", static_cast<bool>(modifiers & ui::EF_CONTROL_DOWN));
obj.Set("altKey", static_cast<bool>(modifiers & ui::EF_ALT_DOWN));
obj.Set("metaKey", static_cast<bool>(modifiers & ui::EF_COMMAND_DOWN));
return obj.GetHandle();
} }
// static // static
@ -181,7 +209,8 @@ void Tray::BuildPrototype(v8::Isolate* isolate,
.SetMethod("setHighlightMode", &Tray::SetHighlightMode) .SetMethod("setHighlightMode", &Tray::SetHighlightMode)
.SetMethod("displayBalloon", &Tray::DisplayBalloon) .SetMethod("displayBalloon", &Tray::DisplayBalloon)
.SetMethod("popUpContextMenu", &Tray::PopUpContextMenu) .SetMethod("popUpContextMenu", &Tray::PopUpContextMenu)
.SetMethod("setContextMenu", &Tray::SetContextMenu); .SetMethod("setContextMenu", &Tray::SetContextMenu)
.SetMethod("getBounds", &Tray::GetBounds);
} }
} // namespace api } // namespace api

View file

@ -5,12 +5,13 @@
#ifndef ATOM_BROWSER_API_ATOM_API_TRAY_H_ #ifndef ATOM_BROWSER_API_ATOM_API_TRAY_H_
#define ATOM_BROWSER_API_ATOM_API_TRAY_H_ #define ATOM_BROWSER_API_ATOM_API_TRAY_H_
#include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
#include "atom/browser/api/trackable_object.h" #include "atom/browser/api/trackable_object.h"
#include "atom/browser/ui/tray_icon.h"
#include "atom/browser/ui/tray_icon_observer.h" #include "atom/browser/ui/tray_icon_observer.h"
#include "base/memory/scoped_ptr.h"
#include "native_mate/handle.h" #include "native_mate/handle.h"
namespace gfx { namespace gfx {
@ -53,6 +54,7 @@ class Tray : public mate::TrackableObject<Tray>,
void OnBalloonClosed() override; void OnBalloonClosed() override;
void OnDrop() override; void OnDrop() override;
void OnDropFiles(const std::vector<std::string>& files) override; void OnDropFiles(const std::vector<std::string>& files) override;
void OnDropText(const std::string& text) override;
void OnDragEntered() override; void OnDragEntered() override;
void OnDragExited() override; void OnDragExited() override;
void OnDragEnded() override; void OnDragEnded() override;
@ -61,14 +63,13 @@ class Tray : public mate::TrackableObject<Tray>,
void SetPressedImage(v8::Isolate* isolate, mate::Handle<NativeImage> image); void SetPressedImage(v8::Isolate* isolate, mate::Handle<NativeImage> image);
void SetToolTip(const std::string& tool_tip); void SetToolTip(const std::string& tool_tip);
void SetTitle(const std::string& title); void SetTitle(const std::string& title);
void SetHighlightMode(bool highlight); void SetHighlightMode(TrayIcon::HighlightMode mode);
void DisplayBalloon(mate::Arguments* args, const mate::Dictionary& options); void DisplayBalloon(mate::Arguments* args, const mate::Dictionary& options);
void PopUpContextMenu(mate::Arguments* args); void PopUpContextMenu(mate::Arguments* args);
void SetContextMenu(v8::Isolate* isolate, mate::Handle<Menu> menu); void SetContextMenu(v8::Isolate* isolate, mate::Handle<Menu> menu);
gfx::Rect GetBounds();
private: private:
v8::Local<v8::Object> ModifiersToObject(v8::Isolate* isolate, int modifiers);
v8::Global<v8::Object> menu_; v8::Global<v8::Object> menu_;
std::unique_ptr<TrayIcon> tray_icon_; std::unique_ptr<TrayIcon> tray_icon_;

View file

@ -17,6 +17,7 @@
#include "atom/browser/lib/bluetooth_chooser.h" #include "atom/browser/lib/bluetooth_chooser.h"
#include "atom/browser/native_window.h" #include "atom/browser/native_window.h"
#include "atom/browser/net/atom_network_delegate.h" #include "atom/browser/net/atom_network_delegate.h"
#include "atom/browser/ui/drag_util.h"
#include "atom/browser/web_contents_permission_helper.h" #include "atom/browser/web_contents_permission_helper.h"
#include "atom/browser/web_contents_preferences.h" #include "atom/browser/web_contents_preferences.h"
#include "atom/browser/web_view_guest_delegate.h" #include "atom/browser/web_view_guest_delegate.h"
@ -46,6 +47,7 @@
#include "content/public/browser/native_web_keyboard_event.h" #include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/browser/navigation_details.h" #include "content/public/browser/navigation_details.h"
#include "content/public/browser/navigation_entry.h" #include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/plugin_service.h" #include "content/public/browser/plugin_service.h"
#include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h" #include "content/public/browser/render_process_host.h"
@ -61,11 +63,10 @@
#include "native_mate/dictionary.h" #include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h" #include "native_mate/object_template_builder.h"
#include "net/http/http_response_headers.h" #include "net/http/http_response_headers.h"
#include "net/url_request/static_http_user_agent_settings.h"
#include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context.h"
#include "third_party/WebKit/public/web/WebInputEvent.h" #include "third_party/WebKit/public/web/WebInputEvent.h"
#include "third_party/WebKit/public/web/WebFindOptions.h" #include "third_party/WebKit/public/web/WebFindOptions.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/display/screen.h"
#include "atom/common/node_includes.h" #include "atom/common/node_includes.h"
@ -76,15 +77,6 @@ struct PrintSettings {
bool print_background; bool print_background;
}; };
void SetUserAgentInIO(scoped_refptr<net::URLRequestContextGetter> getter,
std::string accept_lang,
std::string user_agent) {
getter->GetURLRequestContext()->set_http_user_agent_settings(
new net::StaticHttpUserAgentSettings(
net::HttpUtil::GenerateAcceptLanguageHeader(accept_lang),
user_agent));
}
} // namespace } // namespace
namespace mate { namespace mate {
@ -248,6 +240,13 @@ content::ServiceWorkerContext* GetServiceWorkerContext(
return storage_partition->GetServiceWorkerContext(); return storage_partition->GetServiceWorkerContext();
} }
// Called when CapturePage is done.
void OnCapturePageDone(base::Callback<void(const gfx::Image&)> callback,
const SkBitmap& bitmap,
content::ReadbackResponse response) {
callback.Run(gfx::Image::CreateFrom1xBitmap(bitmap));
}
} // namespace } // namespace
WebContents::WebContents(v8::Isolate* isolate, WebContents::WebContents(v8::Isolate* isolate,
@ -287,16 +286,11 @@ WebContents::WebContents(v8::Isolate* isolate,
std::string partition; std::string partition;
mate::Handle<api::Session> session; mate::Handle<api::Session> session;
if (options.Get("session", &session)) { if (options.Get("session", &session)) {
} else if (options.Get("partition", &partition) && !partition.empty()) { } else if (options.Get("partition", &partition)) {
bool in_memory = true; session = Session::FromPartition(isolate, partition);
if (base::StartsWith(partition, "persist:", base::CompareCase::SENSITIVE)) {
in_memory = false;
partition = partition.substr(8);
}
session = Session::FromPartition(isolate, partition, in_memory);
} else { } else {
// Use the default session if not specified. // Use the default session if not specified.
session = Session::FromPartition(isolate, "", false); session = Session::FromPartition(isolate, "");
} }
session_.Reset(isolate, session.ToV8()); session_.Reset(isolate, session.ToV8());
@ -610,17 +604,6 @@ void WebContents::DidFinishLoad(content::RenderFrameHost* render_frame_host,
Emit("did-finish-load"); Emit("did-finish-load");
} }
void WebContents::DidFailProvisionalLoad(
content::RenderFrameHost* render_frame_host,
const GURL& url,
int code,
const base::string16& description,
bool was_ignored_by_handler) {
bool is_main_frame = !render_frame_host->GetParent();
Emit("did-fail-provisional-load", code, description, url, is_main_frame);
Emit("did-fail-load", code, description, url, is_main_frame);
}
void WebContents::DidFailLoad(content::RenderFrameHost* render_frame_host, void WebContents::DidFailLoad(content::RenderFrameHost* render_frame_host,
const GURL& url, const GURL& url,
int error_code, int error_code,
@ -664,13 +647,27 @@ void WebContents::DidGetRedirectForResourceRequest(
details.headers.get()); details.headers.get());
} }
void WebContents::DidNavigateMainFrame( void WebContents::DidFinishNavigation(
const content::LoadCommittedDetails& details, content::NavigationHandle* navigation_handle) {
const content::FrameNavigateParams& params) { bool is_main_frame = navigation_handle->IsInMainFrame();
if (details.is_navigation_to_different_page()) if (navigation_handle->HasCommitted() && !navigation_handle->IsErrorPage()) {
Emit("did-navigate", params.url); auto url = navigation_handle->GetURL();
else if (details.is_in_page) bool is_in_page = navigation_handle->IsSamePage();
Emit("did-navigate-in-page", params.url); if (is_main_frame && !is_in_page) {
Emit("did-navigate", url);
} else if (is_in_page) {
Emit("did-navigate-in-page", url);
}
} else {
auto url = navigation_handle->GetURL();
int code = navigation_handle->GetNetErrorCode();
auto description = net::ErrorToShortString(code);
Emit("did-fail-provisional-load", code, description, url, is_main_frame);
// Do not emit "did-fail-load" for canceled requests.
if (code != net::ERR_ABORTED)
Emit("did-fail-load", code, description, url, is_main_frame);
}
} }
void WebContents::TitleWasSet(content::NavigationEntry* entry, void WebContents::TitleWasSet(content::NavigationEntry* entry,
@ -684,10 +681,10 @@ void WebContents::TitleWasSet(content::NavigationEntry* entry,
void WebContents::DidUpdateFaviconURL( void WebContents::DidUpdateFaviconURL(
const std::vector<content::FaviconURL>& urls) { const std::vector<content::FaviconURL>& urls) {
std::set<GURL> unique_urls; std::set<GURL> unique_urls;
for (auto iter = urls.begin(); iter != urls.end(); ++iter) { for (const auto& iter : urls) {
if (iter->icon_type != content::FaviconURL::FAVICON) if (iter.icon_type != content::FaviconURL::FAVICON)
continue; continue;
const GURL& url = iter->icon_url; const GURL& url = iter.icon_url;
if (url.is_valid()) if (url.is_valid())
unique_urls.insert(url); unique_urls.insert(url);
} }
@ -736,6 +733,7 @@ bool WebContents::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(AtomViewHostMsg_Message, OnRendererMessage) IPC_MESSAGE_HANDLER(AtomViewHostMsg_Message, OnRendererMessage)
IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_Message_Sync, IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_Message_Sync,
OnRendererMessageSync) OnRendererMessageSync)
IPC_MESSAGE_HANDLER(AtomViewHostMsg_DidCommitCompositorFrame, OnViewPainted)
IPC_MESSAGE_HANDLER_CODE(ViewHostMsg_SetCursor, OnCursorChange, IPC_MESSAGE_HANDLER_CODE(ViewHostMsg_SetCursor, OnCursorChange,
handled = false) handled = false)
IPC_MESSAGE_UNHANDLED(handled = false) IPC_MESSAGE_UNHANDLED(handled = false)
@ -745,7 +743,7 @@ bool WebContents::OnMessageReceived(const IPC::Message& message) {
} }
// There are three ways of destroying a webContents: // There are three ways of destroying a webContents:
// 1. call webContents.destory(); // 1. call webContents.destroy();
// 2. garbage collection; // 2. garbage collection;
// 3. user closes the window of webContents; // 3. user closes the window of webContents;
// For webview only #1 will happen, for BrowserWindow both #1 and #3 may // For webview only #1 will happen, for BrowserWindow both #1 and #3 may
@ -788,6 +786,13 @@ WebContents::Type WebContents::GetType() const {
return type_; return type_;
} }
#if !defined(OS_MACOSX)
bool WebContents::IsFocused() const {
auto view = web_contents()->GetRenderWidgetHostView();
return view && view->HasFocus();
}
#endif
bool WebContents::Equal(const WebContents* web_contents) const { bool WebContents::Equal(const WebContents* web_contents) const {
return GetID() == web_contents->GetID(); return GetID() == web_contents->GetID();
} }
@ -811,7 +816,7 @@ void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) {
std::string user_agent; std::string user_agent;
if (options.Get("userAgent", &user_agent)) if (options.Get("userAgent", &user_agent))
SetUserAgent(user_agent); web_contents()->SetUserAgentOverride(user_agent);
std::string extra_headers; std::string extra_headers;
if (options.Get("extraHeaders", &extra_headers)) if (options.Get("extraHeaders", &extra_headers))
@ -898,14 +903,9 @@ bool WebContents::IsCrashed() const {
return web_contents()->IsCrashed(); return web_contents()->IsCrashed();
} }
void WebContents::SetUserAgent(const std::string& user_agent) { void WebContents::SetUserAgent(const std::string& user_agent,
mate::Arguments* args) {
web_contents()->SetUserAgentOverride(user_agent); web_contents()->SetUserAgentOverride(user_agent);
scoped_refptr<net::URLRequestContextGetter> getter =
web_contents()->GetBrowserContext()->GetRequestContext();
auto accept_lang = l10n_util::GetApplicationLocale("");
getter->GetNetworkTaskRunner()->PostTask(FROM_HERE,
base::Bind(&SetUserAgentInIO, getter, accept_lang, user_agent));
} }
std::string WebContents::GetUserAgent() { std::string WebContents::GetUserAgent() {
@ -1146,6 +1146,12 @@ void WebContents::ShowDefinitionForSelection() {
#endif #endif
} }
void WebContents::CopyImageAt(int x, int y) {
const auto host = web_contents()->GetRenderViewHost();
if (host)
host->CopyImageAt(x, y);
}
void WebContents::Focus() { void WebContents::Focus() {
web_contents()->Focus(); web_contents()->Focus();
} }
@ -1194,15 +1200,14 @@ void WebContents::SendInputEvent(v8::Isolate* isolate,
isolate, "Invalid event object"))); isolate, "Invalid event object")));
} }
void WebContents::BeginFrameSubscription( void WebContents::BeginFrameSubscription(mate::Arguments* args) {
mate::Arguments* args) {
FrameSubscriber::FrameCaptureCallback callback;
bool only_dirty = false; bool only_dirty = false;
FrameSubscriber::FrameCaptureCallback callback;
args->GetNext(&only_dirty);
if (!args->GetNext(&callback)) { if (!args->GetNext(&callback)) {
args->GetNext(&only_dirty); args->ThrowError();
if (!args->GetNext(&callback)) return;
args->ThrowTypeError("'callback' must be defined");
} }
const auto view = web_contents()->GetRenderWidgetHostView(); const auto view = web_contents()->GetRenderWidgetHostView();
@ -1219,6 +1224,74 @@ void WebContents::EndFrameSubscription() {
view->EndFrameSubscription(); view->EndFrameSubscription();
} }
void WebContents::StartDrag(const mate::Dictionary& item,
mate::Arguments* args) {
base::FilePath file;
std::vector<base::FilePath> files;
if (!item.Get("files", &files) && item.Get("file", &file)) {
files.push_back(file);
}
mate::Handle<NativeImage> icon;
if (!item.Get("icon", &icon) && !file.empty()) {
// TODO(zcbenz): Set default icon from file.
}
// Error checking.
if (icon.IsEmpty()) {
args->ThrowError("icon must be set");
return;
}
// Start dragging.
if (!files.empty()) {
base::MessageLoop::ScopedNestableTaskAllower allow(
base::MessageLoop::current());
DragFileItems(files, icon->image(), web_contents()->GetNativeView());
} else {
args->ThrowError("There is nothing to drag");
}
}
void WebContents::CapturePage(mate::Arguments* args) {
gfx::Rect rect;
base::Callback<void(const gfx::Image&)> callback;
if (!(args->Length() == 1 && args->GetNext(&callback)) &&
!(args->Length() == 2 && args->GetNext(&rect)
&& args->GetNext(&callback))) {
args->ThrowError();
return;
}
const auto view = web_contents()->GetRenderWidgetHostView();
const auto host = view ? view->GetRenderWidgetHost() : nullptr;
if (!view || !host) {
callback.Run(gfx::Image());
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(&OnCapturePageDone, callback),
kBGRA_8888_SkColorType);
}
void WebContents::OnCursorChange(const content::WebCursor& cursor) { void WebContents::OnCursorChange(const content::WebCursor& cursor) {
content::WebCursor::CursorInfo info; content::WebCursor::CursorInfo info;
cursor.GetCursorInfo(&info); cursor.GetCursorInfo(&info);
@ -1232,6 +1305,10 @@ void WebContents::OnCursorChange(const content::WebCursor& cursor) {
} }
} }
void WebContents::OnViewPainted() {
Emit("view-painted");
}
void WebContents::SetSize(const SetSizeParams& params) { void WebContents::SetSize(const SetSizeParams& params) {
if (guest_delegate_) if (guest_delegate_)
guest_delegate_->SetSize(params); guest_delegate_->SetSize(params);
@ -1338,6 +1415,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
.SetMethod("beginFrameSubscription", .SetMethod("beginFrameSubscription",
&WebContents::BeginFrameSubscription) &WebContents::BeginFrameSubscription)
.SetMethod("endFrameSubscription", &WebContents::EndFrameSubscription) .SetMethod("endFrameSubscription", &WebContents::EndFrameSubscription)
.SetMethod("startDrag", &WebContents::StartDrag)
.SetMethod("setSize", &WebContents::SetSize) .SetMethod("setSize", &WebContents::SetSize)
.SetMethod("isGuest", &WebContents::IsGuest) .SetMethod("isGuest", &WebContents::IsGuest)
.SetMethod("getType", &WebContents::GetType) .SetMethod("getType", &WebContents::GetType)
@ -1353,6 +1431,9 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
.SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace) .SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace)
.SetMethod("showDefinitionForSelection", .SetMethod("showDefinitionForSelection",
&WebContents::ShowDefinitionForSelection) &WebContents::ShowDefinitionForSelection)
.SetMethod("copyImageAt", &WebContents::CopyImageAt)
.SetMethod("capturePage", &WebContents::CapturePage)
.SetMethod("isFocused", &WebContents::IsFocused)
.SetProperty("id", &WebContents::ID) .SetProperty("id", &WebContents::ID)
.SetProperty("session", &WebContents::Session) .SetProperty("session", &WebContents::Session)
.SetProperty("hostWebContents", &WebContents::HostWebContents) .SetProperty("hostWebContents", &WebContents::HostWebContents)

View file

@ -67,6 +67,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
int GetID() const; int GetID() const;
Type GetType() const; Type GetType() const;
bool IsFocused() const;
bool Equal(const WebContents* web_contents) const; bool Equal(const WebContents* web_contents) const;
void LoadURL(const GURL& url, const mate::Dictionary& options); void LoadURL(const GURL& url, const mate::Dictionary& options);
void DownloadURL(const GURL& url); void DownloadURL(const GURL& url);
@ -81,7 +82,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
void GoForward(); void GoForward();
void GoToOffset(int offset); void GoToOffset(int offset);
bool IsCrashed() const; bool IsCrashed() const;
void SetUserAgent(const std::string& user_agent); void SetUserAgent(const std::string& user_agent, mate::Arguments* args);
std::string GetUserAgent(); std::string GetUserAgent();
void InsertCSS(const std::string& css); void InsertCSS(const std::string& css);
bool SavePage(const base::FilePath& full_file_path, bool SavePage(const base::FilePath& full_file_path,
@ -125,6 +126,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
uint32_t FindInPage(mate::Arguments* args); uint32_t FindInPage(mate::Arguments* args);
void StopFindInPage(content::StopFindAction action); void StopFindInPage(content::StopFindAction action);
void ShowDefinitionForSelection(); void ShowDefinitionForSelection();
void CopyImageAt(int x, int y);
// Focus. // Focus.
void Focus(); void Focus();
@ -142,6 +144,13 @@ class WebContents : public mate::TrackableObject<WebContents>,
void BeginFrameSubscription(mate::Arguments* args); void BeginFrameSubscription(mate::Arguments* args);
void EndFrameSubscription(); void EndFrameSubscription();
// Dragging native items.
void StartDrag(const mate::Dictionary& item, mate::Arguments* args);
// Captures the page with |rect|, |callback| would be called when capturing is
// done.
void CapturePage(mate::Arguments* args);
// Methods for creating <webview>. // Methods for creating <webview>.
void SetSize(const SetSizeParams& params); void SetSize(const SetSizeParams& params);
bool IsGuest() const; bool IsGuest() const;
@ -237,11 +246,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
int error_code, int error_code,
const base::string16& error_description, const base::string16& error_description,
bool was_ignored_by_handler) override; bool was_ignored_by_handler) override;
void DidFailProvisionalLoad(content::RenderFrameHost* render_frame_host,
const GURL& validated_url,
int error_code,
const base::string16& error_description,
bool was_ignored_by_handler) override;
void DidStartLoading() override; void DidStartLoading() override;
void DidStopLoading() override; void DidStopLoading() override;
void DidGetResourceResponseStart( void DidGetResourceResponseStart(
@ -249,9 +253,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
void DidGetRedirectForResourceRequest( void DidGetRedirectForResourceRequest(
content::RenderFrameHost* render_frame_host, content::RenderFrameHost* render_frame_host,
const content::ResourceRedirectDetails& details) override; const content::ResourceRedirectDetails& details) override;
void DidNavigateMainFrame( void DidFinishNavigation(
const content::LoadCommittedDetails& details, content::NavigationHandle* navigation_handle) override;
const content::FrameNavigateParams& params) override;
bool OnMessageReceived(const IPC::Message& message) override; bool OnMessageReceived(const IPC::Message& message) override;
void WebContentsDestroyed() override; void WebContentsDestroyed() override;
void NavigationEntryCommitted( void NavigationEntryCommitted(
@ -292,6 +295,9 @@ class WebContents : public mate::TrackableObject<WebContents>,
const base::ListValue& args, const base::ListValue& args,
IPC::Message* message); IPC::Message* message);
// Called when the hosted view gets graphical updates.
void OnViewPainted();
v8::Global<v8::Value> session_; v8::Global<v8::Value> session_;
v8::Global<v8::Value> devtools_web_contents_; v8::Global<v8::Value> devtools_web_contents_;
v8::Global<v8::Value> debugger_; v8::Global<v8::Value> debugger_;

View file

@ -0,0 +1,32 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_web_contents.h"
@interface NSWindow
- (BOOL)isKeyWindow;
@end
namespace atom {
namespace api {
bool WebContents::IsFocused() const {
auto view = web_contents()->GetRenderWidgetHostView();
if (!view) return false;
if (GetType() != BACKGROUND_PAGE) {
auto window = web_contents()->GetTopLevelNativeWindow();
// On Mac the render widget host view does not lose focus when the window
// loses focus so check if the top level window is the key window.
if (window && ![window isKeyWindow])
return false;
}
return view->HasFocus();
}
} // namespace api
} // namespace atom

View file

@ -55,15 +55,6 @@ namespace api {
namespace { namespace {
void OnCapturePageDone(
v8::Isolate* isolate,
const base::Callback<void(const gfx::Image&)>& callback,
const SkBitmap& bitmap) {
v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
callback.Run(gfx::Image::CreateFrom1xBitmap(bitmap));
}
// Converts binary data to Buffer. // Converts binary data to Buffer.
v8::Local<v8::Value> ToBuffer(v8::Isolate* isolate, void* val, int size) { v8::Local<v8::Value> ToBuffer(v8::Isolate* isolate, void* val, int size) {
auto buffer = node::Buffer::Copy(isolate, static_cast<char*>(val), size); auto buffer = node::Buffer::Copy(isolate, static_cast<char*>(val), size);
@ -106,9 +97,6 @@ Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) {
options, options,
parent.IsEmpty() ? nullptr : parent->window_.get())); parent.IsEmpty() ? nullptr : parent->window_.get()));
web_contents->SetOwnerWindow(window_.get()); web_contents->SetOwnerWindow(window_.get());
window_->InitFromOptions(options);
window_->AddObserver(this);
AttachAsUserData(window_.get());
#if defined(TOOLKIT_VIEWS) #if defined(TOOLKIT_VIEWS)
// Sets the window icon. // Sets the window icon.
@ -116,6 +104,10 @@ Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) {
if (options.Get(options::kIcon, &icon)) if (options.Get(options::kIcon, &icon))
SetIcon(icon); SetIcon(icon);
#endif #endif
window_->InitFromOptions(options);
window_->AddObserver(this);
AttachAsUserData(window_.get());
} }
Window::~Window() { Window::~Window() {
@ -572,23 +564,12 @@ void Window::SetIgnoreMouseEvents(bool ignore) {
return window_->SetIgnoreMouseEvents(ignore); return window_->SetIgnoreMouseEvents(ignore);
} }
void Window::SetFocusable(bool focusable) { void Window::SetContentProtection(bool enable) {
return window_->SetFocusable(focusable); return window_->SetContentProtection(enable);
} }
void Window::CapturePage(mate::Arguments* args) { void Window::SetFocusable(bool focusable) {
gfx::Rect rect; return window_->SetFocusable(focusable);
base::Callback<void(const gfx::Image&)> callback;
if (!(args->Length() == 1 && args->GetNext(&callback)) &&
!(args->Length() == 2 && args->GetNext(&rect)
&& args->GetNext(&callback))) {
args->ThrowError();
return;
}
window_->CapturePage(
rect, base::Bind(&OnCapturePageDone, args->isolate(), callback));
} }
void Window::SetProgressBar(double progress) { void Window::SetProgressBar(double progress) {
@ -668,6 +649,12 @@ bool Window::IsWindowMessageHooked(UINT message) {
void Window::UnhookAllWindowMessages() { void Window::UnhookAllWindowMessages() {
messages_callback_map_.clear(); messages_callback_map_.clear();
} }
bool Window::SetThumbnailClip(const gfx::Rect& region) {
auto window = static_cast<NativeWindowViews*>(window_.get());
return window->taskbar_host().SetThumbnailClip(
window_->GetAcceleratedWidget(), region);
}
#endif #endif
#if defined(TOOLKIT_VIEWS) #if defined(TOOLKIT_VIEWS)
@ -833,11 +820,11 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("setDocumentEdited", &Window::SetDocumentEdited) .SetMethod("setDocumentEdited", &Window::SetDocumentEdited)
.SetMethod("isDocumentEdited", &Window::IsDocumentEdited) .SetMethod("isDocumentEdited", &Window::IsDocumentEdited)
.SetMethod("setIgnoreMouseEvents", &Window::SetIgnoreMouseEvents) .SetMethod("setIgnoreMouseEvents", &Window::SetIgnoreMouseEvents)
.SetMethod("setContentProtection", &Window::SetContentProtection)
.SetMethod("setFocusable", &Window::SetFocusable) .SetMethod("setFocusable", &Window::SetFocusable)
.SetMethod("focusOnWebView", &Window::FocusOnWebView) .SetMethod("focusOnWebView", &Window::FocusOnWebView)
.SetMethod("blurWebView", &Window::BlurWebView) .SetMethod("blurWebView", &Window::BlurWebView)
.SetMethod("isWebViewFocused", &Window::IsWebViewFocused) .SetMethod("isWebViewFocused", &Window::IsWebViewFocused)
.SetMethod("capturePage", &Window::CapturePage)
.SetMethod("setProgressBar", &Window::SetProgressBar) .SetMethod("setProgressBar", &Window::SetProgressBar)
.SetMethod("setOverlayIcon", &Window::SetOverlayIcon) .SetMethod("setOverlayIcon", &Window::SetOverlayIcon)
.SetMethod("setThumbarButtons", &Window::SetThumbarButtons) .SetMethod("setThumbarButtons", &Window::SetThumbarButtons)
@ -855,6 +842,7 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("isWindowMessageHooked", &Window::IsWindowMessageHooked) .SetMethod("isWindowMessageHooked", &Window::IsWindowMessageHooked)
.SetMethod("unhookWindowMessage", &Window::UnhookWindowMessage) .SetMethod("unhookWindowMessage", &Window::UnhookWindowMessage)
.SetMethod("unhookAllWindowMessages", &Window::UnhookAllWindowMessages) .SetMethod("unhookAllWindowMessages", &Window::UnhookAllWindowMessages)
.SetMethod("setThumbnailClip", &Window::SetThumbnailClip)
#endif #endif
#if defined(TOOLKIT_VIEWS) #if defined(TOOLKIT_VIEWS)
.SetMethod("setIcon", &Window::SetIcon) .SetMethod("setIcon", &Window::SetIcon)

View file

@ -153,8 +153,8 @@ class Window : public mate::TrackableObject<Window>,
void SetDocumentEdited(bool edited); void SetDocumentEdited(bool edited);
bool IsDocumentEdited(); bool IsDocumentEdited();
void SetIgnoreMouseEvents(bool ignore); void SetIgnoreMouseEvents(bool ignore);
void SetContentProtection(bool enable);
void SetFocusable(bool focusable); void SetFocusable(bool focusable);
void CapturePage(mate::Arguments* args);
void SetProgressBar(double progress); void SetProgressBar(double progress);
void SetOverlayIcon(const gfx::Image& overlay, void SetOverlayIcon(const gfx::Image& overlay,
const std::string& description); const std::string& description);
@ -179,6 +179,7 @@ class Window : public mate::TrackableObject<Window>,
bool IsWindowMessageHooked(UINT message); bool IsWindowMessageHooked(UINT message);
void UnhookWindowMessage(UINT message); void UnhookWindowMessage(UINT message);
void UnhookAllWindowMessages(); void UnhookAllWindowMessages();
bool SetThumbnailClip(const gfx::Rect& region);
#endif #endif
#if defined(TOOLKIT_VIEWS) #if defined(TOOLKIT_VIEWS)

View file

@ -12,8 +12,8 @@
namespace mate { namespace mate {
Event::Event(v8::Isolate* isolate) Event::Event(v8::Isolate* isolate)
: sender_(NULL), : sender_(nullptr),
message_(NULL) { message_(nullptr) {
Init(isolate); Init(isolate);
} }
@ -31,8 +31,8 @@ void Event::SetSenderAndMessage(content::WebContents* sender,
} }
void Event::WebContentsDestroyed() { void Event::WebContentsDestroyed() {
sender_ = NULL; sender_ = nullptr;
message_ = NULL; message_ = nullptr;
} }
void Event::PreventDefault(v8::Isolate* isolate) { void Event::PreventDefault(v8::Isolate* isolate) {
@ -41,13 +41,13 @@ void Event::PreventDefault(v8::Isolate* isolate) {
} }
bool Event::SendReply(const base::string16& json) { bool Event::SendReply(const base::string16& json) {
if (message_ == NULL || sender_ == NULL) if (message_ == nullptr || sender_ == nullptr)
return false; return false;
AtomViewHostMsg_Message_Sync::WriteReplyParams(message_, json); AtomViewHostMsg_Message_Sync::WriteReplyParams(message_, json);
bool success = sender_->Send(message_); bool success = sender_->Send(message_);
message_ = NULL; message_ = nullptr;
sender_ = NULL; sender_ = nullptr;
return success; return success;
} }

View file

@ -8,6 +8,7 @@
#include "native_mate/arguments.h" #include "native_mate/arguments.h"
#include "native_mate/dictionary.h" #include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h" #include "native_mate/object_template_builder.h"
#include "ui/events/event_constants.h"
namespace mate { namespace mate {
@ -65,6 +66,15 @@ v8::Local<v8::Object> CreateCustomEvent(
return event; return event;
} }
v8::Local<v8::Object> CreateEventFromFlags(v8::Isolate* isolate, int flags) {
mate::Dictionary obj = mate::Dictionary::CreateEmpty(isolate);
obj.Set("shiftKey", static_cast<bool>(flags & ui::EF_SHIFT_DOWN));
obj.Set("ctrlKey", static_cast<bool>(flags & ui::EF_CONTROL_DOWN));
obj.Set("altKey", static_cast<bool>(flags & ui::EF_ALT_DOWN));
obj.Set("metaKey", static_cast<bool>(flags & ui::EF_COMMAND_DOWN));
return obj.GetHandle();
}
} // namespace internal } // namespace internal
} // namespace mate } // namespace mate

View file

@ -30,6 +30,7 @@ v8::Local<v8::Object> CreateCustomEvent(
v8::Isolate* isolate, v8::Isolate* isolate,
v8::Local<v8::Object> object, v8::Local<v8::Object> object,
v8::Local<v8::Object> event); v8::Local<v8::Object> event);
v8::Local<v8::Object> CreateEventFromFlags(v8::Isolate* isolate, int flags);
} // namespace internal } // namespace internal
@ -54,6 +55,16 @@ class EventEmitter : public Wrappable<T> {
internal::CreateCustomEvent(isolate(), GetWrapper(), event), args...); internal::CreateCustomEvent(isolate(), GetWrapper(), event), args...);
} }
// this.emit(name, new Event(flags), args...);
template<typename... Args>
bool EmitWithFlags(const base::StringPiece& name,
int flags,
const Args&... args) {
return EmitCustomEvent(
name,
internal::CreateEventFromFlags(isolate(), flags), args...);
}
// this.emit(name, new Event(), args...); // this.emit(name, new Event(), args...);
template<typename... Args> template<typename... Args>
bool Emit(const base::StringPiece& name, const Args&... args) { bool Emit(const base::StringPiece& name, const Args&... args) {

View file

@ -5,8 +5,8 @@
#include "atom/browser/api/frame_subscriber.h" #include "atom/browser/api/frame_subscriber.h"
#include "base/bind.h" #include "base/bind.h"
#include "atom/common/node_includes.h"
#include "atom/common/native_mate_converters/gfx_converter.h" #include "atom/common/native_mate_converters/gfx_converter.h"
#include "atom/common/node_includes.h"
#include "content/public/browser/render_widget_host.h" #include "content/public/browser/render_widget_host.h"
namespace atom { namespace atom {
@ -17,8 +17,11 @@ FrameSubscriber::FrameSubscriber(v8::Isolate* isolate,
content::RenderWidgetHostView* view, content::RenderWidgetHostView* view,
const FrameCaptureCallback& callback, const FrameCaptureCallback& callback,
bool only_dirty) bool only_dirty)
: isolate_(isolate), view_(view), callback_(callback), : isolate_(isolate),
only_dirty_(only_dirty), weak_factory_(this) { view_(view),
callback_(callback),
only_dirty_(only_dirty),
weak_factory_(this) {
} }
bool FrameSubscriber::ShouldCaptureFrame( bool FrameSubscriber::ShouldCaptureFrame(
@ -48,8 +51,9 @@ bool FrameSubscriber::ShouldCaptureFrame(
} }
void FrameSubscriber::OnFrameDelivered(const FrameCaptureCallback& callback, void FrameSubscriber::OnFrameDelivered(const FrameCaptureCallback& callback,
const gfx::Rect& damage_rect, const SkBitmap& bitmap, const gfx::Rect& damage_rect,
content::ReadbackResponse response) { const SkBitmap& bitmap,
content::ReadbackResponse response) {
if (response != content::ReadbackResponse::READBACK_SUCCESS) if (response != content::ReadbackResponse::READBACK_SUCCESS)
return; return;
@ -67,7 +71,7 @@ void FrameSubscriber::OnFrameDelivered(const FrameCaptureCallback& callback,
rgb_arr_size); rgb_arr_size);
v8::Local<v8::Value> damage = v8::Local<v8::Value> damage =
mate::Converter<gfx::Rect>::ToV8(isolate_, damage_rect); mate::Converter<gfx::Rect>::ToV8(isolate_, damage_rect);
callback_.Run(buffer.ToLocalChecked(), damage); callback_.Run(buffer.ToLocalChecked(), damage);
} }

View file

@ -21,7 +21,7 @@ namespace api {
class FrameSubscriber : public content::RenderWidgetHostViewFrameSubscriber { class FrameSubscriber : public content::RenderWidgetHostViewFrameSubscriber {
public: public:
using FrameCaptureCallback = using FrameCaptureCallback =
base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>)>; base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>)>;
FrameSubscriber(v8::Isolate* isolate, FrameSubscriber(v8::Isolate* isolate,
content::RenderWidgetHostView* view, content::RenderWidgetHostView* view,
@ -35,8 +35,9 @@ class FrameSubscriber : public content::RenderWidgetHostViewFrameSubscriber {
private: private:
void OnFrameDelivered(const FrameCaptureCallback& callback, void OnFrameDelivered(const FrameCaptureCallback& callback,
const gfx::Rect& damage_rect, const SkBitmap& bitmap, const gfx::Rect& damage_rect,
content::ReadbackResponse response); const SkBitmap& bitmap,
content::ReadbackResponse response);
v8::Isolate* isolate_; v8::Isolate* isolate_;
content::RenderWidgetHostView* view_; content::RenderWidgetHostView* view_;

View file

@ -10,7 +10,6 @@
#include "atom/browser/api/event_emitter.h" #include "atom/browser/api/event_emitter.h"
#include "atom/common/key_weak_map.h" #include "atom/common/key_weak_map.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "native_mate/object_template_builder.h" #include "native_mate/object_template_builder.h"

View file

@ -7,8 +7,8 @@
#include <utility> #include <utility>
#include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/common/google_api_key.h" #include "atom/common/google_api_key.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/geolocation_provider.h" #include "content/public/browser/geolocation_provider.h"
namespace atom { namespace atom {
@ -33,21 +33,35 @@ AtomAccessTokenStore::~AtomAccessTokenStore() {
void AtomAccessTokenStore::LoadAccessTokens( void AtomAccessTokenStore::LoadAccessTokens(
const LoadAccessTokensCallback& callback) { const LoadAccessTokensCallback& callback) {
AccessTokenMap access_token_map; content::BrowserThread::PostTaskAndReply(
content::BrowserThread::UI,
// Equivelent to access_token_map[kGeolocationProviderURL]. FROM_HERE,
// Somehow base::string16 is causing compilation errors when used in a pair base::Bind(&AtomAccessTokenStore::GetRequestContextOnUIThread, this),
// of std::map on Linux, this can work around it. base::Bind(&AtomAccessTokenStore::RespondOnOriginatingThread,
std::pair<GURL, base::string16> token_pair; this, callback));
token_pair.first = GURL(kGeolocationProviderURL);
access_token_map.insert(token_pair);
auto browser_context = AtomBrowserMainParts::Get()->browser_context();
callback.Run(access_token_map, browser_context->url_request_context_getter());
} }
void AtomAccessTokenStore::SaveAccessToken(const GURL& server_url, void AtomAccessTokenStore::SaveAccessToken(const GURL& server_url,
const base::string16& access_token) { const base::string16& access_token) {
} }
void AtomAccessTokenStore::GetRequestContextOnUIThread() {
auto browser_context = AtomBrowserContext::From("", false);
request_context_getter_ = browser_context->GetRequestContext();
}
void AtomAccessTokenStore::RespondOnOriginatingThread(
const LoadAccessTokensCallback& callback) {
// Equivelent to access_token_map[kGeolocationProviderURL].
// Somehow base::string16 is causing compilation errors when used in a pair
// of std::map on Linux, this can work around it.
AccessTokenMap access_token_map;
std::pair<GURL, base::string16> token_pair;
token_pair.first = GURL(kGeolocationProviderURL);
access_token_map.insert(token_pair);
callback.Run(access_token_map, request_context_getter_.get());
request_context_getter_ = nullptr;
}
} // namespace atom } // namespace atom

View file

@ -9,12 +9,10 @@
namespace atom { namespace atom {
class AtomBrowserContext;
class AtomAccessTokenStore : public content::AccessTokenStore { class AtomAccessTokenStore : public content::AccessTokenStore {
public: public:
AtomAccessTokenStore(); AtomAccessTokenStore();
virtual ~AtomAccessTokenStore(); ~AtomAccessTokenStore();
// content::AccessTokenStore: // content::AccessTokenStore:
void LoadAccessTokens( void LoadAccessTokens(
@ -23,6 +21,11 @@ class AtomAccessTokenStore : public content::AccessTokenStore {
const base::string16& access_token) override; const base::string16& access_token) override;
private: private:
void GetRequestContextOnUIThread();
void RespondOnOriginatingThread(const LoadAccessTokensCallback& callback);
scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
DISALLOW_COPY_AND_ASSIGN(AtomAccessTokenStore); DISALLOW_COPY_AND_ASSIGN(AtomAccessTokenStore);
}; };

View file

@ -202,7 +202,7 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
void AtomBrowserClient::DidCreatePpapiPlugin( void AtomBrowserClient::DidCreatePpapiPlugin(
content::BrowserPpapiHost* host) { content::BrowserPpapiHost* host) {
host->GetPpapiHost()->AddHostFactoryFilter( host->GetPpapiHost()->AddHostFactoryFilter(
make_scoped_ptr(new chrome::ChromeBrowserPepperHostFactory(host))); base::WrapUnique(new chrome::ChromeBrowserPepperHostFactory(host)));
} }
content::QuotaPermissionContext* content::QuotaPermissionContext*
@ -287,20 +287,21 @@ brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts(
void AtomBrowserClient::WebNotificationAllowed( void AtomBrowserClient::WebNotificationAllowed(
int render_process_id, int render_process_id,
const base::Callback<void(bool)>& callback) { const base::Callback<void(bool, bool)>& callback) {
content::WebContents* web_contents = content::WebContents* web_contents =
WebContentsPreferences::GetWebContentsFromProcessID(render_process_id); WebContentsPreferences::GetWebContentsFromProcessID(render_process_id);
if (!web_contents) { if (!web_contents) {
callback.Run(false); callback.Run(false, false);
return; return;
} }
auto permission_helper = auto permission_helper =
WebContentsPermissionHelper::FromWebContents(web_contents); WebContentsPermissionHelper::FromWebContents(web_contents);
if (!permission_helper) { if (!permission_helper) {
callback.Run(false); callback.Run(false, false);
return; return;
} }
permission_helper->RequestWebNotificationPermission(callback); permission_helper->RequestWebNotificationPermission(
base::Bind(callback, web_contents->IsAudioMuted()));
} }
void AtomBrowserClient::RenderProcessHostDestroyed( void AtomBrowserClient::RenderProcessHostDestroyed(

View file

@ -100,7 +100,7 @@ class AtomBrowserClient : public brightray::BrowserClient,
const content::MainFunctionParams&) override; const content::MainFunctionParams&) override;
void WebNotificationAllowed( void WebNotificationAllowed(
int render_process_id, int render_process_id,
const base::Callback<void(bool)>& callback) override; const base::Callback<void(bool, bool)>& callback) override;
// content::RenderProcessHostObserver: // content::RenderProcessHostObserver:
void RenderProcessHostDestroyed(content::RenderProcessHost* host) override; void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;

View file

@ -63,21 +63,12 @@ std::string RemoveWhitespace(const std::string& str) {
} // namespace } // namespace
AtomBrowserContext::AtomBrowserContext(const std::string& partition, AtomBrowserContext::AtomBrowserContext(
bool in_memory) const std::string& partition, bool in_memory,
const base::DictionaryValue& options)
: brightray::BrowserContext(partition, in_memory), : brightray::BrowserContext(partition, in_memory),
cert_verifier_(new AtomCertVerifier),
network_delegate_(new AtomNetworkDelegate) { network_delegate_(new AtomNetworkDelegate) {
} // Construct user agent string.
AtomBrowserContext::~AtomBrowserContext() {
}
net::NetworkDelegate* AtomBrowserContext::CreateNetworkDelegate() {
return network_delegate_;
}
std::string AtomBrowserContext::GetUserAgent() {
Browser* browser = Browser::Get(); Browser* browser = Browser::Get();
std::string name = RemoveWhitespace(browser->GetName()); std::string name = RemoveWhitespace(browser->GetName());
std::string user_agent; std::string user_agent;
@ -91,7 +82,29 @@ std::string AtomBrowserContext::GetUserAgent() {
browser->GetVersion().c_str(), browser->GetVersion().c_str(),
CHROME_VERSION_STRING); CHROME_VERSION_STRING);
} }
return content::BuildUserAgentFromProduct(user_agent); user_agent_ = content::BuildUserAgentFromProduct(user_agent);
// Read options.
use_cache_ = true;
options.GetBoolean("cache", &use_cache_);
// Initialize Pref Registry in brightray.
InitPrefs();
}
AtomBrowserContext::~AtomBrowserContext() {
}
void AtomBrowserContext::SetUserAgent(const std::string& user_agent) {
user_agent_ = user_agent;
}
net::NetworkDelegate* AtomBrowserContext::CreateNetworkDelegate() {
return network_delegate_;
}
std::string AtomBrowserContext::GetUserAgent() {
return user_agent_;
} }
std::unique_ptr<net::URLRequestJobFactory> std::unique_ptr<net::URLRequestJobFactory>
@ -107,29 +120,29 @@ AtomBrowserContext::CreateURLRequestJobFactory(
protocol_handlers->clear(); protocol_handlers->clear();
job_factory->SetProtocolHandler( job_factory->SetProtocolHandler(
url::kDataScheme, make_scoped_ptr(new net::DataProtocolHandler)); url::kDataScheme, base::WrapUnique(new net::DataProtocolHandler));
job_factory->SetProtocolHandler( job_factory->SetProtocolHandler(
url::kFileScheme, make_scoped_ptr(new asar::AsarProtocolHandler( url::kFileScheme, base::WrapUnique(new asar::AsarProtocolHandler(
BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior( BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)))); base::SequencedWorkerPool::SKIP_ON_SHUTDOWN))));
job_factory->SetProtocolHandler( job_factory->SetProtocolHandler(
url::kHttpScheme, url::kHttpScheme,
make_scoped_ptr(new HttpProtocolHandler(url::kHttpScheme))); base::WrapUnique(new HttpProtocolHandler(url::kHttpScheme)));
job_factory->SetProtocolHandler( job_factory->SetProtocolHandler(
url::kHttpsScheme, url::kHttpsScheme,
make_scoped_ptr(new HttpProtocolHandler(url::kHttpsScheme))); base::WrapUnique(new HttpProtocolHandler(url::kHttpsScheme)));
job_factory->SetProtocolHandler( job_factory->SetProtocolHandler(
url::kWsScheme, url::kWsScheme,
make_scoped_ptr(new HttpProtocolHandler(url::kWsScheme))); base::WrapUnique(new HttpProtocolHandler(url::kWsScheme)));
job_factory->SetProtocolHandler( job_factory->SetProtocolHandler(
url::kWssScheme, url::kWssScheme,
make_scoped_ptr(new HttpProtocolHandler(url::kWssScheme))); base::WrapUnique(new HttpProtocolHandler(url::kWssScheme)));
auto host_resolver = auto host_resolver =
url_request_context_getter()->GetURLRequestContext()->host_resolver(); url_request_context_getter()->GetURLRequestContext()->host_resolver();
job_factory->SetProtocolHandler( job_factory->SetProtocolHandler(
url::kFtpScheme, url::kFtpScheme,
make_scoped_ptr(new net::FtpProtocolHandler( base::WrapUnique(new net::FtpProtocolHandler(
new net::FtpNetworkLayer(host_resolver)))); new net::FtpNetworkLayer(host_resolver))));
return std::move(job_factory); return std::move(job_factory);
@ -139,7 +152,7 @@ net::HttpCache::BackendFactory*
AtomBrowserContext::CreateHttpCacheBackendFactory( AtomBrowserContext::CreateHttpCacheBackendFactory(
const base::FilePath& base_path) { const base::FilePath& base_path) {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kDisableHttpCache)) if (!use_cache_ || command_line->HasSwitch(switches::kDisableHttpCache))
return new NoCacheBackend; return new NoCacheBackend;
else else
return brightray::BrowserContext::CreateHttpCacheBackendFactory(base_path); return brightray::BrowserContext::CreateHttpCacheBackendFactory(base_path);
@ -168,7 +181,7 @@ content::PermissionManager* AtomBrowserContext::GetPermissionManager() {
} }
std::unique_ptr<net::CertVerifier> AtomBrowserContext::CreateCertVerifier() { std::unique_ptr<net::CertVerifier> AtomBrowserContext::CreateCertVerifier() {
return make_scoped_ptr(cert_verifier_); return base::WrapUnique(new AtomCertVerifier);
} }
net::SSLConfigService* AtomBrowserContext::CreateSSLConfigService() { net::SSLConfigService* AtomBrowserContext::CreateSSLConfigService() {
@ -185,14 +198,15 @@ void AtomBrowserContext::RegisterPrefs(PrefRegistrySimple* pref_registry) {
pref_registry->RegisterDictionaryPref(prefs::kDevToolsFileSystemPaths); pref_registry->RegisterDictionaryPref(prefs::kDevToolsFileSystemPaths);
} }
} // namespace atom
namespace brightray {
// static // static
scoped_refptr<BrowserContext> BrowserContext::Create( scoped_refptr<AtomBrowserContext> AtomBrowserContext::From(
const std::string& partition, bool in_memory) { const std::string& partition, bool in_memory,
return make_scoped_refptr(new atom::AtomBrowserContext(partition, 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

View file

@ -12,15 +12,20 @@
namespace atom { namespace atom {
class AtomDownloadManagerDelegate; class AtomDownloadManagerDelegate;
class AtomCertVerifier;
class AtomNetworkDelegate; class AtomNetworkDelegate;
class AtomPermissionManager; class AtomPermissionManager;
class WebViewManager; class WebViewManager;
class AtomBrowserContext : public brightray::BrowserContext { class AtomBrowserContext : public brightray::BrowserContext {
public: public:
AtomBrowserContext(const std::string& partition, bool in_memory); // Get or create the BrowserContext according to its |partition| and
~AtomBrowserContext() override; // |in_memory|. The |options| will be passed to constructor when there is no
// existing BrowserContext.
static scoped_refptr<AtomBrowserContext> From(
const std::string& partition, bool in_memory,
const base::DictionaryValue& options = base::DictionaryValue());
void SetUserAgent(const std::string& user_agent);
// brightray::URLRequestContextGetter::Delegate: // brightray::URLRequestContextGetter::Delegate:
net::NetworkDelegate* CreateNetworkDelegate() override; net::NetworkDelegate* CreateNetworkDelegate() override;
@ -40,16 +45,21 @@ class AtomBrowserContext : public brightray::BrowserContext {
// brightray::BrowserContext: // brightray::BrowserContext:
void RegisterPrefs(PrefRegistrySimple* pref_registry) override; void RegisterPrefs(PrefRegistrySimple* pref_registry) override;
AtomCertVerifier* cert_verifier() const { return cert_verifier_; }
AtomNetworkDelegate* network_delegate() const { return network_delegate_; } AtomNetworkDelegate* network_delegate() const { return network_delegate_; }
protected:
AtomBrowserContext(const std::string& partition, bool in_memory,
const base::DictionaryValue& options);
~AtomBrowserContext() override;
private: private:
std::unique_ptr<AtomDownloadManagerDelegate> download_manager_delegate_; std::unique_ptr<AtomDownloadManagerDelegate> download_manager_delegate_;
std::unique_ptr<WebViewManager> guest_manager_; std::unique_ptr<WebViewManager> guest_manager_;
std::unique_ptr<AtomPermissionManager> permission_manager_; std::unique_ptr<AtomPermissionManager> permission_manager_;
std::string user_agent_;
bool use_cache_;
// Managed by brightray::BrowserContext. // Managed by brightray::BrowserContext.
AtomCertVerifier* cert_verifier_;
AtomNetworkDelegate* network_delegate_; AtomNetworkDelegate* network_delegate_;
DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext); DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext);

View file

@ -15,7 +15,7 @@
#include "atom/common/node_bindings.h" #include "atom/common/node_bindings.h"
#include "atom/common/node_includes.h" #include "atom/common/node_includes.h"
#include "base/command_line.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 "chrome/browser/browser_process.h"
#include "v8/include/v8-debug.h" #include "v8/include/v8-debug.h"
@ -32,7 +32,7 @@ void Erase(T* container, typename T::iterator iter) {
} }
// static // static
AtomBrowserMainParts* AtomBrowserMainParts::self_ = NULL; AtomBrowserMainParts* AtomBrowserMainParts::self_ = nullptr;
AtomBrowserMainParts::AtomBrowserMainParts() AtomBrowserMainParts::AtomBrowserMainParts()
: fake_browser_process_(new BrowserProcess), : fake_browser_process_(new BrowserProcess),
@ -124,6 +124,8 @@ void AtomBrowserMainParts::PostEarlyInitialization() {
} }
void AtomBrowserMainParts::PreMainMessageLoopRun() { void AtomBrowserMainParts::PreMainMessageLoopRun() {
js_env_->OnMessageLoopCreated();
// Run user's main script before most things get initialized, so we can have // Run user's main script before most things get initialized, so we can have
// a chance to setup everything. // a chance to setup everything.
node_bindings_->PrepareMessageLoop(); node_bindings_->PrepareMessageLoop();
@ -169,6 +171,8 @@ void AtomBrowserMainParts::PostMainMessageLoopStart() {
void AtomBrowserMainParts::PostMainMessageLoopRun() { void AtomBrowserMainParts::PostMainMessageLoopRun() {
brightray::BrowserMainParts::PostMainMessageLoopRun(); brightray::BrowserMainParts::PostMainMessageLoopRun();
js_env_->OnMessageLoopDestroying();
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
FreeAppDelegate(); FreeAppDelegate();
#endif #endif

View file

@ -43,7 +43,7 @@ void GracefulShutdownHandler(int signal) {
struct sigaction action; struct sigaction action;
memset(&action, 0, sizeof(action)); memset(&action, 0, sizeof(action));
action.sa_handler = SIG_DFL; action.sa_handler = SIG_DFL;
RAW_CHECK(sigaction(signal, &action, NULL) == 0); RAW_CHECK(sigaction(signal, &action, nullptr) == 0);
RAW_CHECK(g_pipe_pid == getpid()); RAW_CHECK(g_pipe_pid == getpid());
RAW_CHECK(g_shutdown_pipe_write_fd != -1); RAW_CHECK(g_shutdown_pipe_write_fd != -1);
@ -171,7 +171,7 @@ void AtomBrowserMainParts::HandleSIGCHLD() {
struct sigaction action; struct sigaction action;
memset(&action, 0, sizeof(action)); memset(&action, 0, sizeof(action));
action.sa_handler = SIGCHLDHandler; action.sa_handler = SIGCHLDHandler;
CHECK_EQ(sigaction(SIGCHLD, &action, NULL), 0); CHECK_EQ(sigaction(SIGCHLD, &action, nullptr), 0);
} }
void AtomBrowserMainParts::HandleShutdownSignals() { void AtomBrowserMainParts::HandleShutdownSignals() {
@ -211,15 +211,15 @@ void AtomBrowserMainParts::HandleShutdownSignals() {
struct sigaction action; struct sigaction action;
memset(&action, 0, sizeof(action)); memset(&action, 0, sizeof(action));
action.sa_handler = SIGTERMHandler; action.sa_handler = SIGTERMHandler;
CHECK_EQ(sigaction(SIGTERM, &action, NULL), 0); CHECK_EQ(sigaction(SIGTERM, &action, nullptr), 0);
// Also handle SIGINT - when the user terminates the browser via Ctrl+C. If // Also handle SIGINT - when the user terminates the browser via Ctrl+C. If
// the browser process is being debugged, GDB will catch the SIGINT first. // the browser process is being debugged, GDB will catch the SIGINT first.
action.sa_handler = SIGINTHandler; action.sa_handler = SIGINTHandler;
CHECK_EQ(sigaction(SIGINT, &action, NULL), 0); CHECK_EQ(sigaction(SIGINT, &action, nullptr), 0);
// And SIGHUP, for when the terminal disappears. On shutdown, many Linux // And SIGHUP, for when the terminal disappears. On shutdown, many Linux
// distros send SIGHUP, SIGTERM, and then SIGKILL. // distros send SIGHUP, SIGTERM, and then SIGKILL.
action.sa_handler = SIGHUPHandler; action.sa_handler = SIGHUPHandler;
CHECK_EQ(sigaction(SIGHUP, &action, NULL), 0); CHECK_EQ(sigaction(SIGHUP, &action, nullptr), 0);
} }
} // namespace atom } // namespace atom

View file

@ -85,6 +85,14 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
download_manager_->GetBrowserContext()); download_manager_->GetBrowserContext());
browser_context->prefs()->SetFilePath(prefs::kDownloadDefaultDirectory, browser_context->prefs()->SetFilePath(prefs::kDownloadDefaultDirectory,
path.DirName()); path.DirName());
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
api::DownloadItem* download_item = api::DownloadItem::FromWrappedClass(
isolate, item);
if (download_item)
download_item->SetSavePath(path);
} }
// Running the DownloadTargetCallback with an empty FilePath signals that the // Running the DownloadTargetCallback with an empty FilePath signals that the

View file

@ -7,6 +7,7 @@
#include "atom/browser/login_handler.h" #include "atom/browser/login_handler.h"
#include "atom/browser/web_contents_permission_helper.h" #include "atom/browser/web_contents_permission_helper.h"
#include "atom/common/platform_util.h" #include "atom/common/platform_util.h"
#include "base/strings/utf_string_conversions.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "net/base/escape.h" #include "net/base/escape.h"
#include "url/gurl.h" #include "url/gurl.h"
@ -20,7 +21,13 @@ namespace {
void OnOpenExternal(const GURL& escaped_url, void OnOpenExternal(const GURL& escaped_url,
bool allowed) { bool allowed) {
if (allowed) if (allowed)
platform_util::OpenExternal(escaped_url, true); platform_util::OpenExternal(
#if defined(OS_WIN)
base::UTF8ToUTF16(escaped_url.spec()),
#else
escaped_url,
#endif
true);
} }
void HandleExternalProtocolInUI( void HandleExternalProtocolInUI(

View file

@ -91,8 +91,14 @@ void AtomSecurityStateModelClient::GetVisibleSecurityState(
state->connection_status = ssl.connection_status; state->connection_status = ssl.connection_status;
state->security_bits = ssl.security_bits; state->security_bits = ssl.security_bits;
state->sct_verify_statuses.clear(); state->sct_verify_statuses.clear();
for (const auto& sct : ssl.signed_certificate_timestamp_ids) state->sct_verify_statuses.insert(state->sct_verify_statuses.end(),
state->sct_verify_statuses.push_back(sct.status); ssl.num_unknown_scts,
net::ct::SCT_STATUS_LOG_UNKNOWN);
state->sct_verify_statuses.insert(state->sct_verify_statuses.end(),
ssl.num_invalid_scts,
net::ct::SCT_STATUS_INVALID);
state->sct_verify_statuses.insert(state->sct_verify_statuses.end(),
ssl.num_valid_scts, net::ct::SCT_STATUS_OK);
state->displayed_mixed_content = state->displayed_mixed_content =
(ssl.content_status & content::SSLStatus::DISPLAYED_INSECURE_CONTENT) (ssl.content_status & content::SSLStatus::DISPLAYED_INSECURE_CONTENT)
? true ? true

View file

@ -50,11 +50,6 @@ void AtomSpeechRecognitionManagerDelegate::OnAudioLevelsChange(
int session_id, float volume, float noise_volume) { int session_id, float volume, float noise_volume) {
} }
void AtomSpeechRecognitionManagerDelegate::GetDiagnosticInformation(
bool* can_report_metrics, std::string* hardware_info) {
*can_report_metrics = false;
}
void AtomSpeechRecognitionManagerDelegate::CheckRecognitionIsAllowed( void AtomSpeechRecognitionManagerDelegate::CheckRecognitionIsAllowed(
int session_id, int session_id,
base::Callback<void(bool ask_user, bool is_allowed)> callback) { base::Callback<void(bool ask_user, bool is_allowed)> callback) {

View file

@ -36,8 +36,6 @@ class AtomSpeechRecognitionManagerDelegate
float noise_volume) override; float noise_volume) override;
// content::SpeechRecognitionManagerDelegate: // content::SpeechRecognitionManagerDelegate:
void GetDiagnosticInformation(bool* can_report_metrics,
std::string* hardware_info) override;
void CheckRecognitionIsAllowed( void CheckRecognitionIsAllowed(
int session_id, int session_id,
base::Callback<void(bool ask_user, bool is_allowed)> callback) override; base::Callback<void(bool ask_user, bool is_allowed)> callback) override;

View file

@ -17,6 +17,10 @@ void AutoUpdater::SetDelegate(Delegate* delegate) {
} }
#if !defined(OS_MACOSX) || defined(MAS_BUILD) #if !defined(OS_MACOSX) || defined(MAS_BUILD)
std::string AutoUpdater::GetFeedURL() {
return "";
}
void AutoUpdater::SetFeedURL(const std::string& url, void AutoUpdater::SetFeedURL(const std::string& url,
const HeaderMap& requestHeaders) { const HeaderMap& requestHeaders) {
} }

View file

@ -49,6 +49,7 @@ class AutoUpdater {
static Delegate* GetDelegate(); static Delegate* GetDelegate();
static void SetDelegate(Delegate* delegate); static void SetDelegate(Delegate* delegate);
static std::string GetFeedURL();
static void SetFeedURL(const std::string& url, static void SetFeedURL(const std::string& url,
const HeaderMap& requestHeaders); const HeaderMap& requestHeaders);
static void CheckForUpdates(); static void CheckForUpdates();

View file

@ -25,9 +25,14 @@ SQRLUpdater* g_updater = nil;
namespace { namespace {
bool g_update_available = false; bool g_update_available = false;
std::string update_url_ = "";
} }
std::string AutoUpdater::GetFeedURL() {
return update_url_;
}
// static // static
void AutoUpdater::SetFeedURL(const std::string& feed, void AutoUpdater::SetFeedURL(const std::string& feed,
const HeaderMap& requestHeaders) { const HeaderMap& requestHeaders) {
@ -35,6 +40,8 @@ void AutoUpdater::SetFeedURL(const std::string& feed,
if (!delegate) if (!delegate)
return; return;
update_url_ = feed;
NSURL* url = [NSURL URLWithString:base::SysUTF8ToNSString(feed)]; NSURL* url = [NSURL URLWithString:base::SysUTF8ToNSString(feed)];
NSMutableURLRequest* urlRequest = [NSMutableURLRequest requestWithURL:url]; NSMutableURLRequest* urlRequest = [NSMutableURLRequest requestWithURL:url];

View file

@ -118,6 +118,10 @@ void Browser::SetName(const std::string& name) {
name_override_ = name; name_override_ = name;
} }
int Browser::GetBadgeCount() {
return badge_count_;
}
bool Browser::OpenFile(const std::string& file_path) { bool Browser::OpenFile(const std::string& file_path) {
bool prevent_default = false; bool prevent_default = false;
FOR_EACH_OBSERVER(BrowserObserver, FOR_EACH_OBSERVER(BrowserObserver,
@ -151,6 +155,12 @@ void Browser::DidFinishLaunching() {
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnFinishLaunching()); FOR_EACH_OBSERVER(BrowserObserver, observers_, OnFinishLaunching());
} }
void Browser::OnAccessibilitySupportChanged() {
FOR_EACH_OBSERVER(BrowserObserver,
observers_,
OnAccessibilitySupportChanged());
}
void Browser::RequestLogin( void Browser::RequestLogin(
LoginHandler* login_handler, LoginHandler* login_handler,
std::unique_ptr<base::DictionaryValue> request_details) { std::unique_ptr<base::DictionaryValue> request_details) {

View file

@ -25,16 +25,13 @@ class DictionaryValue;
class FilePath; class FilePath;
} }
namespace ui {
class MenuModel;
}
namespace gfx { namespace gfx {
class Image; class Image;
} }
namespace atom { namespace atom {
class AtomMenuModel;
class LoginHandler; class LoginHandler;
// This class is used for control application-wide operations. // This class is used for control application-wide operations.
@ -87,6 +84,21 @@ class Browser : public WindowListObserver {
// Query the current state of default handler for a protocol. // Query the current state of default handler for a protocol.
bool IsDefaultProtocolClient(const std::string& protocol); bool IsDefaultProtocolClient(const std::string& protocol);
// Set/Get the badge count.
bool SetBadgeCount(int count);
int GetBadgeCount();
// Set/Get the login item settings of the app
struct LoginItemSettings {
bool open_at_login = false;
bool open_as_hidden = false;
bool restore_state = false;
bool opened_at_login = false;
bool opened_as_hidden = false;
};
void SetLoginItemSettings(LoginItemSettings settings);
LoginItemSettings GetLoginItemSettings();
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
// Hide the application. // Hide the application.
void Hide(); void Hide();
@ -126,7 +138,7 @@ class Browser : public WindowListObserver {
void DockShow(); void DockShow();
// Set docks' menu. // Set docks' menu.
void DockSetMenu(ui::MenuModel* model); void DockSetMenu(AtomMenuModel* model);
// Set docks' icon. // Set docks' icon.
void DockSetIcon(const gfx::Image& image); void DockSetIcon(const gfx::Image& image);
@ -149,7 +161,12 @@ class Browser : public WindowListObserver {
// one from app's name. // one from app's name.
// The returned string managed by Browser, and should not be modified. // The returned string managed by Browser, and should not be modified.
PCWSTR GetAppUserModelID(); PCWSTR GetAppUserModelID();
#endif #endif // defined(OS_WIN)
#if defined(OS_LINUX)
// Whether Unity launcher is running.
bool IsUnityRunning();
#endif // defined(OS_LINUX)
// Tell the application to open a file. // Tell the application to open a file.
bool OpenFile(const std::string& file_path); bool OpenFile(const std::string& file_path);
@ -165,6 +182,8 @@ class Browser : public WindowListObserver {
void WillFinishLaunching(); void WillFinishLaunching();
void DidFinishLaunching(); void DidFinishLaunching();
void OnAccessibilitySupportChanged();
// Request basic auth login. // Request basic auth login.
void RequestLogin(LoginHandler* login_handler, void RequestLogin(LoginHandler* login_handler,
std::unique_ptr<base::DictionaryValue> request_details); std::unique_ptr<base::DictionaryValue> request_details);
@ -216,6 +235,8 @@ class Browser : public WindowListObserver {
std::string version_override_; std::string version_override_;
std::string name_override_; std::string name_override_;
int badge_count_ = 0;
#if defined(OS_WIN) #if defined(OS_WIN)
base::string16 app_user_model_id_; base::string16 app_user_model_id_;
#endif #endif

View file

@ -10,6 +10,7 @@
#include "atom/browser/window_list.h" #include "atom/browser/window_list.h"
#include "atom/common/atom_version.h" #include "atom/common/atom_version.h"
#include "brightray/common/application_info.h" #include "brightray/common/application_info.h"
#include "chrome/browser/ui/libgtk2ui/unity_service.h"
namespace atom { namespace atom {
@ -46,6 +47,23 @@ bool Browser::IsDefaultProtocolClient(const std::string& protocol) {
return false; return false;
} }
bool Browser::SetBadgeCount(int count) {
if (IsUnityRunning()) {
unity::SetDownloadCount(count);
badge_count_ = count;
return true;
} else {
return false;
}
}
void Browser::SetLoginItemSettings(LoginItemSettings settings) {
}
Browser::LoginItemSettings Browser::GetLoginItemSettings() {
return LoginItemSettings();
}
std::string Browser::GetExecutableFileVersion() const { std::string Browser::GetExecutableFileVersion() const {
return brightray::GetApplicationVersion(); return brightray::GetApplicationVersion();
} }
@ -54,4 +72,8 @@ std::string Browser::GetExecutableFileProductName() const {
return brightray::GetApplicationName(); return brightray::GetApplicationName();
} }
bool Browser::IsUnityRunning() {
return unity::IsRunning();
}
} // namespace atom } // namespace atom

View file

@ -11,6 +11,8 @@
#include "atom/browser/window_list.h" #include "atom/browser/window_list.h"
#include "base/mac/bundle_locations.h" #include "base/mac/bundle_locations.h"
#include "base/mac/foundation_util.h" #include "base/mac/foundation_util.h"
#include "base/mac/mac_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/sys_string_conversions.h" #include "base/strings/sys_string_conversions.h"
#include "brightray/common/application_info.h" #include "brightray/common/application_info.h"
#include "net/base/mac/url_conversions.h" #include "net/base/mac/url_conversions.h"
@ -114,6 +116,12 @@ bool Browser::IsDefaultProtocolClient(const std::string& protocol) {
void Browser::SetAppUserModelID(const base::string16& name) { void Browser::SetAppUserModelID(const base::string16& name) {
} }
bool Browser::SetBadgeCount(int count) {
DockSetBadgeText(count != 0 ? base::IntToString(count) : "");
badge_count_ = count;
return true;
}
void Browser::SetUserActivity(const std::string& type, void Browser::SetUserActivity(const std::string& type,
const base::DictionaryValue& user_info, const base::DictionaryValue& user_info,
mate::Arguments* args) { mate::Arguments* args) {
@ -141,6 +149,23 @@ bool Browser::ContinueUserActivity(const std::string& type,
return prevent_default; return prevent_default;
} }
Browser::LoginItemSettings Browser::GetLoginItemSettings() {
LoginItemSettings settings;
settings.open_at_login = base::mac::CheckLoginItemStatus(
&settings.open_as_hidden);
settings.restore_state = base::mac::WasLaunchedAsLoginItemRestoreState();
settings.opened_at_login = base::mac::WasLaunchedAsLoginOrResumeItem();
settings.opened_as_hidden = base::mac::WasLaunchedAsHiddenLoginItem();
return settings;
}
void Browser::SetLoginItemSettings(LoginItemSettings settings) {
if (settings.open_at_login)
base::mac::AddToLoginItems(settings.open_as_hidden);
else
base::mac::RemoveFromLoginItems();
}
std::string Browser::GetExecutableFileVersion() const { std::string Browser::GetExecutableFileVersion() const {
return brightray::GetApplicationVersion(); return brightray::GetApplicationVersion();
} }
@ -209,7 +234,7 @@ void Browser::DockShow() {
} }
} }
void Browser::DockSetMenu(ui::MenuModel* model) { void Browser::DockSetMenu(AtomMenuModel* model) {
AtomApplicationDelegate* delegate = (AtomApplicationDelegate*)[NSApp delegate]; AtomApplicationDelegate* delegate = (AtomApplicationDelegate*)[NSApp delegate];
[delegate setApplicationDockMenu:model]; [delegate setApplicationDockMenu:model];
} }

View file

@ -52,6 +52,9 @@ class BrowserObserver {
virtual void OnLogin(LoginHandler* login_handler, virtual void OnLogin(LoginHandler* login_handler,
const base::DictionaryValue& request_details) {} const base::DictionaryValue& request_details) {}
// The browser's accessibility suppport has changed.
virtual void OnAccessibilitySupportChanged() {}
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
// The browser wants to resume a user activity via handoff. (macOS only) // The browser wants to resume a user activity via handoff. (macOS only)
virtual void OnContinueUserActivity( virtual void OnContinueUserActivity(

View file

@ -13,7 +13,6 @@
#include "base/base_paths.h" #include "base/base_paths.h"
#include "base/file_version_info.h" #include "base/file_version_info.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h" #include "base/path_service.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
@ -269,6 +268,43 @@ bool Browser::IsDefaultProtocolClient(const std::string& protocol) {
} }
} }
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() { PCWSTR Browser::GetAppUserModelID() {
if (app_user_model_id_.empty()) { if (app_user_model_id_.empty()) {
SetAppUserModelID(base::ReplaceStringPlaceholders( SetAppUserModelID(base::ReplaceStringPlaceholders(

View file

@ -94,7 +94,7 @@ FileSystem CreateFileSystemStruct(
} }
base::DictionaryValue* CreateFileSystemValue(const FileSystem& file_system) { base::DictionaryValue* CreateFileSystemValue(const FileSystem& file_system) {
base::DictionaryValue* file_system_value = new base::DictionaryValue(); auto* file_system_value = new base::DictionaryValue();
file_system_value->SetString("fileSystemName", file_system.file_system_name); file_system_value->SetString("fileSystemName", file_system.file_system_name);
file_system_value->SetString("rootURL", file_system.root_url); file_system_value->SetString("rootURL", file_system.root_url);
file_system_value->SetString("fileSystemPath", file_system.file_system_path); file_system_value->SetString("fileSystemPath", file_system.file_system_path);
@ -377,7 +377,7 @@ content::SecurityStyle CommonWebContentsDelegate::GetSecurityStyle(
void CommonWebContentsDelegate::DevToolsSaveToFile( void CommonWebContentsDelegate::DevToolsSaveToFile(
const std::string& url, const std::string& content, bool save_as) { const std::string& url, const std::string& content, bool save_as) {
base::FilePath path; base::FilePath path;
PathsMap::iterator it = saved_files_.find(url); auto it = saved_files_.find(url);
if (it != saved_files_.end() && !save_as) { if (it != saved_files_.end() && !save_as) {
path = it->second; path = it->second;
} else { } else {
@ -402,7 +402,7 @@ void CommonWebContentsDelegate::DevToolsSaveToFile(
void CommonWebContentsDelegate::DevToolsAppendToFile( void CommonWebContentsDelegate::DevToolsAppendToFile(
const std::string& url, const std::string& content) { const std::string& url, const std::string& content) {
PathsMap::iterator it = saved_files_.find(url); auto it = saved_files_.find(url);
if (it == saved_files_.end()) if (it == saved_files_.end())
return; return;
@ -435,8 +435,8 @@ void CommonWebContentsDelegate::DevToolsRequestFileSystems() {
} }
base::ListValue file_system_value; base::ListValue file_system_value;
for (size_t i = 0; i < file_systems.size(); ++i) for (const auto& file_system : file_systems)
file_system_value.Append(CreateFileSystemValue(file_systems[i])); file_system_value.Append(CreateFileSystemValue(file_system));
web_contents_->CallClientFunction("DevToolsAPI.fileSystemsLoaded", web_contents_->CallClientFunction("DevToolsAPI.fileSystemsLoaded",
&file_system_value, nullptr, nullptr); &file_system_value, nullptr, nullptr);
} }
@ -610,9 +610,8 @@ void CommonWebContentsDelegate::OnDevToolsSearchCompleted(
const std::string& file_system_path, const std::string& file_system_path,
const std::vector<std::string>& file_paths) { const std::vector<std::string>& file_paths) {
base::ListValue file_paths_value; base::ListValue file_paths_value;
for (std::vector<std::string>::const_iterator it(file_paths.begin()); for (const auto& file_path : file_paths) {
it != file_paths.end(); ++it) { file_paths_value.AppendString(file_path);
file_paths_value.AppendString(*it);
} }
base::FundamentalValue request_id_value(request_id); base::FundamentalValue request_id_value(request_id);
base::StringValue file_system_path_value(file_system_path); base::StringValue file_system_path_value(file_system_path);

View file

@ -27,7 +27,13 @@ void CommonWebContentsDelegate::HandleKeyboardEvent(
if (event.windowsKeyCode == ui::VKEY_ESCAPE && is_html_fullscreen()) if (event.windowsKeyCode == ui::VKEY_ESCAPE && is_html_fullscreen())
ExitFullscreenModeForTab(source); ExitFullscreenModeForTab(source);
if (event.os_event.window) // Send the event to the menu before sending it to the window
if (event.os_event.type == NSKeyDown &&
[[NSApp mainMenu] performKeyEquivalent:event.os_event])
return;
if (event.os_event.window &&
[event.os_event.window isKindOfClass:[EventDispatchingWindow class]])
[event.os_event.window redispatchKeyEvent:event.os_event]; [event.os_event.window redispatchKeyEvent:event.os_event];
} }

View file

@ -7,6 +7,7 @@
#include <string> #include <string>
#include "base/command_line.h" #include "base/command_line.h"
#include "base/message_loop/message_loop.h"
#include "content/public/common/content_switches.h" #include "content/public/common/content_switches.h"
#include "gin/array_buffer.h" #include "gin/array_buffer.h"
#include "gin/v8_initializer.h" #include "gin/v8_initializer.h"
@ -23,6 +24,14 @@ JavascriptEnvironment::JavascriptEnvironment()
context_scope_(v8::Local<v8::Context>::New(isolate_, context_)) { context_scope_(v8::Local<v8::Context>::New(isolate_, context_)) {
} }
void JavascriptEnvironment::OnMessageLoopCreated() {
isolate_holder_.AddRunMicrotasksObserver();
}
void JavascriptEnvironment::OnMessageLoopDestroying() {
isolate_holder_.RemoveRunMicrotasksObserver();
}
bool JavascriptEnvironment::Initialize() { bool JavascriptEnvironment::Initialize() {
auto cmd = base::CommandLine::ForCurrentProcess(); auto cmd = base::CommandLine::ForCurrentProcess();
if (cmd->HasSwitch("debug-brk")) { if (cmd->HasSwitch("debug-brk")) {

View file

@ -14,6 +14,9 @@ class JavascriptEnvironment {
public: public:
JavascriptEnvironment(); JavascriptEnvironment();
void OnMessageLoopCreated();
void OnMessageLoopDestroying();
v8::Isolate* isolate() const { return isolate_; } v8::Isolate* isolate() const { return isolate_; }
v8::Local<v8::Context> context() const { v8::Local<v8::Context> context() const {
return v8::Local<v8::Context>::New(isolate_, context_); return v8::Local<v8::Context>::New(isolate_, context_);

View file

@ -83,6 +83,8 @@
} else { } else {
ax_state->DisableAccessibility(); ax_state->DisableAccessibility();
} }
atom::Browser::Get()->OnAccessibilitySupportChanged();
} }
@end @end

View file

@ -11,9 +11,7 @@
base::scoped_nsobject<AtomMenuController> menu_controller_; base::scoped_nsobject<AtomMenuController> menu_controller_;
} }
- (id)init;
// Sets the menu that will be returned in "applicationDockMenu:". // Sets the menu that will be returned in "applicationDockMenu:".
- (void)setApplicationDockMenu:(ui::MenuModel*)model; - (void)setApplicationDockMenu:(atom::AtomMenuModel*)model;
@end @end

View file

@ -12,14 +12,9 @@
@implementation AtomApplicationDelegate @implementation AtomApplicationDelegate
- (id)init { - (void)setApplicationDockMenu:(atom::AtomMenuModel*)model {
self = [super init]; menu_controller_.reset([[AtomMenuController alloc] initWithModel:model
menu_controller_.reset([[AtomMenuController alloc] init]); useDefaultAccelerator:NO]);
return self;
}
- (void)setApplicationDockMenu:(ui::MenuModel*)model {
[menu_controller_ populateWithModel:model];
} }
- (void)applicationWillFinishLaunching:(NSNotification*)notify { - (void)applicationWillFinishLaunching:(NSNotification*)notify {
@ -34,7 +29,10 @@
} }
- (NSMenu*)applicationDockMenu:(NSApplication*)sender { - (NSMenu*)applicationDockMenu:(NSApplication*)sender {
return [menu_controller_ menu]; if (menu_controller_)
return [menu_controller_ menu];
else
return nil;
} }
- (BOOL)application:(NSApplication*)sender - (BOOL)application:(NSApplication*)sender

View file

@ -5,9 +5,9 @@
#ifndef ATOM_BROWSER_MAC_DICT_UTIL_H_ #ifndef ATOM_BROWSER_MAC_DICT_UTIL_H_
#define ATOM_BROWSER_MAC_DICT_UTIL_H_ #define ATOM_BROWSER_MAC_DICT_UTIL_H_
#import <Foundation/Foundation.h> #include <memory>
#include "base/memory/scoped_ptr.h" #import <Foundation/Foundation.h>
namespace base { namespace base {
class ListValue; class ListValue;

View file

@ -11,6 +11,7 @@
#include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h" #include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/browser.h" #include "atom/browser/browser.h"
#include "atom/browser/unresponsive_suppressor.h"
#include "atom/browser/window_list.h" #include "atom/browser/window_list.h"
#include "atom/common/api/api_messages.h" #include "atom/common/api/api_messages.h"
#include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/native_mate_converters/file_path_converter.h"
@ -37,9 +38,13 @@
#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/size_conversions.h" #include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/screen.h"
#include "ui/gl/gpu_switching_manager.h" #include "ui/gl/gpu_switching_manager.h"
#if defined(OS_LINUX) || defined(OS_WIN)
#include "content/public/common/renderer_preferences.h"
#include "ui/gfx/font_render_params.h"
#endif
DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::NativeWindowRelay); DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::NativeWindowRelay);
namespace atom { namespace atom {
@ -53,7 +58,6 @@ NativeWindow::NativeWindow(
transparent_(false), transparent_(false),
enable_larger_than_screen_(false), enable_larger_than_screen_(false),
is_closed_(false), is_closed_(false),
has_dialog_attached_(false),
sheet_offset_x_(0.0), sheet_offset_x_(0.0),
sheet_offset_y_(0.0), sheet_offset_y_(0.0),
aspect_ratio_(0.0), aspect_ratio_(0.0),
@ -68,6 +72,20 @@ NativeWindow::NativeWindow(
if (parent) if (parent)
options.Get("modal", &is_modal_); options.Get("modal", &is_modal_);
#if defined(OS_LINUX) || defined(OS_WIN)
auto* prefs = web_contents()->GetMutableRendererPrefs();
// Update font settings.
CR_DEFINE_STATIC_LOCAL(const gfx::FontRenderParams, params,
(gfx::GetFontRenderParams(gfx::FontRenderParamsQuery(), nullptr)));
prefs->should_antialias_text = params.antialiasing;
prefs->use_subpixel_positioning = params.subpixel_positioning;
prefs->hinting = params.hinting;
prefs->use_autohinter = params.autohinter;
prefs->use_bitmaps = params.use_bitmaps;
prefs->subpixel_rendering = params.subpixel_rendering;
#endif
// Tell the content module to initialize renderer widget with transparent // Tell the content module to initialize renderer widget with transparent
// mode. // mode.
ui::GpuSwitchingManager::SetTransparent(transparent_); ui::GpuSwitchingManager::SetTransparent(transparent_);
@ -210,7 +228,7 @@ gfx::Size NativeWindow::GetContentSize() {
void NativeWindow::SetSizeConstraints( void NativeWindow::SetSizeConstraints(
const extensions::SizeConstraints& window_constraints) { const extensions::SizeConstraints& window_constraints) {
extensions::SizeConstraints content_constraints; extensions::SizeConstraints content_constraints(GetContentSizeConstraints());
if (window_constraints.HasMaximumSize()) if (window_constraints.HasMaximumSize())
content_constraints.set_maximum_size( content_constraints.set_maximum_size(
WindowSizeToContentSize(window_constraints.GetMaximumSize())); WindowSizeToContentSize(window_constraints.GetMaximumSize()));
@ -291,11 +309,7 @@ bool NativeWindow::IsDocumentEdited() {
void NativeWindow::SetFocusable(bool focusable) { void NativeWindow::SetFocusable(bool focusable) {
} }
void NativeWindow::SetMenu(ui::MenuModel* menu) { void NativeWindow::SetMenu(AtomMenuModel* menu) {
}
bool NativeWindow::HasModalDialog() {
return has_dialog_attached_;
} }
void NativeWindow::SetParentWindow(NativeWindow* parent) { void NativeWindow::SetParentWindow(NativeWindow* parent) {
@ -315,39 +329,6 @@ bool NativeWindow::IsWebViewFocused() {
return host_view && host_view->HasFocus(); 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 =
gfx::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) { void NativeWindow::SetAutoHideMenuBar(bool auto_hide) {
} }
@ -394,7 +375,7 @@ void NativeWindow::RequestToClosePage() {
ScheduleUnresponsiveEvent(5000); ScheduleUnresponsiveEvent(5000);
if (web_contents()->NeedToFireBeforeUnload()) if (web_contents()->NeedToFireBeforeUnload())
web_contents()->DispatchBeforeUnload(false); web_contents()->DispatchBeforeUnload();
else else
web_contents()->Close(); web_contents()->Close();
} }
@ -624,7 +605,7 @@ void NativeWindow::ScheduleUnresponsiveEvent(int ms) {
void NativeWindow::NotifyWindowUnresponsive() { void NativeWindow::NotifyWindowUnresponsive() {
window_unresposive_closure_.Cancel(); window_unresposive_closure_.Cancel();
if (!is_closed_ && !HasModalDialog() && IsEnabled()) if (!is_closed_ && !IsUnresponsiveEventSuppressed() && IsEnabled())
FOR_EACH_OBSERVER(NativeWindowObserver, FOR_EACH_OBSERVER(NativeWindowObserver,
observers_, observers_,
OnRendererUnresponsive()); OnRendererUnresponsive());
@ -634,10 +615,4 @@ void NativeWindow::NotifyReadyToShow() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnReadyToShow()); FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnReadyToShow());
} }
void NativeWindow::OnCapturePageDone(const CapturePageCallback& callback,
const SkBitmap& bitmap,
content::ReadbackResponse response) {
callback.Run(bitmap);
}
} // namespace atom } // namespace atom

View file

@ -6,13 +6,14 @@
#define ATOM_BROWSER_NATIVE_WINDOW_H_ #define ATOM_BROWSER_NATIVE_WINDOW_H_
#include <map> #include <map>
#include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
#include "atom/browser/native_window_observer.h" #include "atom/browser/native_window_observer.h"
#include "atom/browser/ui/accelerator_util.h" #include "atom/browser/ui/accelerator_util.h"
#include "atom/browser/ui/atom_menu_model.h"
#include "base/cancelable_callback.h" #include "base/cancelable_callback.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/observer_list.h" #include "base/observer_list.h"
#include "base/supports_user_data.h" #include "base/supports_user_data.h"
@ -43,10 +44,6 @@ namespace mate {
class Dictionary; class Dictionary;
} }
namespace ui {
class MenuModel;
}
namespace atom { namespace atom {
struct DraggableRegion; struct DraggableRegion;
@ -54,28 +51,7 @@ struct DraggableRegion;
class NativeWindow : public base::SupportsUserData, class NativeWindow : public base::SupportsUserData,
public content::WebContentsObserver { public content::WebContentsObserver {
public: public:
using CapturePageCallback = base::Callback<void(const SkBitmap& bitmap)>; ~NativeWindow() override;
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();
// Create window with existing WebContents, the caller is responsible for // Create window with existing WebContents, the caller is responsible for
// managing the window's live. // managing the window's live.
@ -157,9 +133,9 @@ class NativeWindow : public base::SupportsUserData,
virtual void SetDocumentEdited(bool edited); virtual void SetDocumentEdited(bool edited);
virtual bool IsDocumentEdited(); virtual bool IsDocumentEdited();
virtual void SetIgnoreMouseEvents(bool ignore) = 0; virtual void SetIgnoreMouseEvents(bool ignore) = 0;
virtual void SetContentProtection(bool enable) = 0;
virtual void SetFocusable(bool focusable); virtual void SetFocusable(bool focusable);
virtual void SetMenu(ui::MenuModel* menu); virtual void SetMenu(AtomMenuModel* menu);
virtual bool HasModalDialog();
virtual void SetParentWindow(NativeWindow* parent); virtual void SetParentWindow(NativeWindow* parent);
virtual gfx::NativeWindow GetNativeWindow() = 0; virtual gfx::NativeWindow GetNativeWindow() = 0;
virtual gfx::AcceleratedWidget GetAcceleratedWidget() = 0; virtual gfx::AcceleratedWidget GetAcceleratedWidget() = 0;
@ -178,11 +154,6 @@ class NativeWindow : public base::SupportsUserData,
virtual void BlurWebView(); virtual void BlurWebView();
virtual bool IsWebViewFocused(); 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. // Toggle the menu bar.
virtual void SetAutoHideMenuBar(bool auto_hide); virtual void SetAutoHideMenuBar(bool auto_hide);
virtual bool IsMenuBarAutoHide(); virtual bool IsMenuBarAutoHide();
@ -254,10 +225,6 @@ class NativeWindow : public base::SupportsUserData,
SkRegion* draggable_region() const { return draggable_region_.get(); } SkRegion* draggable_region() const { return draggable_region_.get(); }
bool enable_larger_than_screen() const { return enable_larger_than_screen_; } 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_; } NativeWindow* parent() const { return parent_; }
bool is_modal() const { return is_modal_; } bool is_modal() const { return is_modal_; }
@ -295,11 +262,6 @@ class NativeWindow : public base::SupportsUserData,
// Dispatch ReadyToShow event to observers. // Dispatch ReadyToShow event to observers.
void NotifyReadyToShow(); void NotifyReadyToShow();
// Called when CapturePage has done.
void OnCapturePageDone(const CapturePageCallback& callback,
const SkBitmap& bitmap,
content::ReadbackResponse response);
// Whether window has standard frame. // Whether window has standard frame.
bool has_frame_; bool has_frame_;
@ -319,9 +281,6 @@ class NativeWindow : public base::SupportsUserData,
// The windows has been closed. // The windows has been closed.
bool is_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, // Closure that would be called when window is unresponsive when closing,
// it should be cancelled when we can prove that the window is responsive. // it should be cancelled when we can prove that the window is responsive.
base::CancelableClosure window_unresposive_closure_; base::CancelableClosure window_unresposive_closure_;

View file

@ -79,7 +79,7 @@ class NativeWindowMac : public NativeWindow {
void SetDocumentEdited(bool edited) override; void SetDocumentEdited(bool edited) override;
bool IsDocumentEdited() override; bool IsDocumentEdited() override;
void SetIgnoreMouseEvents(bool ignore) override; void SetIgnoreMouseEvents(bool ignore) override;
bool HasModalDialog() override; void SetContentProtection(bool enable) override;
void SetParentWindow(NativeWindow* parent) override; void SetParentWindow(NativeWindow* parent) override;
gfx::NativeWindow GetNativeWindow() override; gfx::NativeWindow GetNativeWindow() override;
gfx::AcceleratedWidget GetAcceleratedWidget() override; gfx::AcceleratedWidget GetAcceleratedWidget() override;

View file

@ -70,6 +70,7 @@ bool ScopedDisableResize::disable_resize_ = false;
@interface AtomNSWindowDelegate : NSObject<NSWindowDelegate> { @interface AtomNSWindowDelegate : NSObject<NSWindowDelegate> {
@private @private
atom::NativeWindowMac* shell_; atom::NativeWindowMac* shell_;
bool is_zooming_;
} }
- (id)initWithShell:(atom::NativeWindowMac*)shell; - (id)initWithShell:(atom::NativeWindowMac*)shell;
@end @end
@ -79,6 +80,7 @@ bool ScopedDisableResize::disable_resize_ = false;
- (id)initWithShell:(atom::NativeWindowMac*)shell { - (id)initWithShell:(atom::NativeWindowMac*)shell {
if ((self = [super init])) { if ((self = [super init])) {
shell_ = shell; shell_ = shell;
is_zooming_ = false;
} }
return self; return self;
} }
@ -172,16 +174,20 @@ bool ScopedDisableResize::disable_resize_ = false;
} }
- (BOOL)windowShouldZoom:(NSWindow*)window toFrame:(NSRect)newFrame { - (BOOL)windowShouldZoom:(NSWindow*)window toFrame:(NSRect)newFrame {
// Cocoa doen't have concept of maximize/unmaximize, so wee need to emulate is_zooming_ = true;
// them by calculating size change when zooming.
if (newFrame.size.width < [window frame].size.width ||
newFrame.size.height < [window frame].size.height)
shell_->NotifyWindowUnmaximize();
else
shell_->NotifyWindowMaximize();
return YES; return YES;
} }
- (void)windowDidEndLiveResize:(NSNotification*)notification {
if (is_zooming_) {
if (shell_->IsMaximized())
shell_->NotifyWindowMaximize();
else
shell_->NotifyWindowUnmaximize();
is_zooming_ = false;
}
}
- (void)windowWillEnterFullScreen:(NSNotification*)notification { - (void)windowWillEnterFullScreen:(NSNotification*)notification {
// Hide the native toolbar before entering fullscreen, so there is no visual // Hide the native toolbar before entering fullscreen, so there is no visual
// artifacts. // artifacts.
@ -199,6 +205,7 @@ bool ScopedDisableResize::disable_resize_ = false;
// have to set one, because title bar is visible here. // have to set one, because title bar is visible here.
NSWindow* window = shell_->GetNativeWindow(); NSWindow* window = shell_->GetNativeWindow();
if ((shell_->transparent() || !shell_->has_frame()) && if ((shell_->transparent() || !shell_->has_frame()) &&
base::mac::IsOSYosemiteOrLater() &&
// FIXME(zcbenz): Showing titlebar for hiddenInset window is weird under // FIXME(zcbenz): Showing titlebar for hiddenInset window is weird under
// fullscreen mode. // fullscreen mode.
shell_->title_bar_style() != atom::NativeWindowMac::HIDDEN_INSET) { shell_->title_bar_style() != atom::NativeWindowMac::HIDDEN_INSET) {
@ -223,6 +230,7 @@ bool ScopedDisableResize::disable_resize_ = false;
// Restore the titlebar visibility. // Restore the titlebar visibility.
NSWindow* window = shell_->GetNativeWindow(); NSWindow* window = shell_->GetNativeWindow();
if ((shell_->transparent() || !shell_->has_frame()) && if ((shell_->transparent() || !shell_->has_frame()) &&
base::mac::IsOSYosemiteOrLater() &&
shell_->title_bar_style() != atom::NativeWindowMac::HIDDEN_INSET) { shell_->title_bar_style() != atom::NativeWindowMac::HIDDEN_INSET) {
[window setTitleVisibility:NSWindowTitleHidden]; [window setTitleVisibility:NSWindowTitleHidden];
} }
@ -233,13 +241,6 @@ bool ScopedDisableResize::disable_resize_ = false;
} }
- (void)windowDidExitFullScreen:(NSNotification*)notification { - (void)windowDidExitFullScreen:(NSNotification*)notification {
// For certain versions of macOS the fullscreen button will automatically show
// after exiting fullscreen mode.
if (!shell_->has_frame()) {
NSWindow* window = shell_->GetNativeWindow();
[[window standardWindowButton:NSWindowFullScreenButton] setHidden:YES];
}
shell_->NotifyWindowLeaveFullScreen(); shell_->NotifyWindowLeaveFullScreen();
} }
@ -526,8 +527,10 @@ NativeWindowMac::NativeWindowMac(
[window_ setDisableKeyOrMainWindow:YES]; [window_ setDisableKeyOrMainWindow:YES];
if (transparent() || !has_frame()) { if (transparent() || !has_frame()) {
// Don't show title bar. if (base::mac::IsOSYosemiteOrLater()) {
[window_ setTitleVisibility:NSWindowTitleHidden]; // Don't show title bar.
[window_ setTitleVisibility:NSWindowTitleHidden];
}
// Remove non-transparent corners, see http://git.io/vfonD. // Remove non-transparent corners, see http://git.io/vfonD.
[window_ setOpaque:NO]; [window_ setOpaque:NO];
} }
@ -714,11 +717,6 @@ void NativeWindowMac::SetFullScreen(bool fullscreen) {
if (fullscreen == IsFullscreen()) if (fullscreen == IsFullscreen())
return; return;
if (!base::mac::IsOSLionOrLater()) {
LOG(ERROR) << "Fullscreen mode is only supported above Lion";
return;
}
[window_ toggleFullScreen:nil]; [window_ toggleFullScreen:nil];
} }
@ -727,13 +725,22 @@ bool NativeWindowMac::IsFullscreen() const {
} }
void NativeWindowMac::SetBounds(const gfx::Rect& bounds, bool animate) { void NativeWindowMac::SetBounds(const gfx::Rect& bounds, bool animate) {
NSRect cocoa_bounds = NSMakeRect(bounds.x(), 0, // Do nothing if in fullscreen mode.
bounds.width(), if (IsFullscreen())
bounds.height()); return;
// Check size constraints since setFrame does not check it.
gfx::Size size = bounds.size();
size.SetToMax(GetMinimumSize());
gfx::Size max_size = GetMaximumSize();
if (!max_size.IsEmpty())
size.SetToMin(max_size);
NSRect cocoa_bounds = NSMakeRect(bounds.x(), 0, size.width(), size.height());
// Flip coordinates based on the primary screen. // Flip coordinates based on the primary screen.
NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
cocoa_bounds.origin.y = cocoa_bounds.origin.y =
NSHeight([screen frame]) - bounds.height() - bounds.y(); NSHeight([screen frame]) - size.height() - bounds.y();
[window_ setFrame:cocoa_bounds display:YES animate:animate]; [window_ setFrame:cocoa_bounds display:YES animate:animate];
} }
@ -785,13 +792,13 @@ bool NativeWindowMac::IsResizable() {
void NativeWindowMac::SetAspectRatio(double aspect_ratio, void NativeWindowMac::SetAspectRatio(double aspect_ratio,
const gfx::Size& extra_size) { const gfx::Size& extra_size) {
NativeWindow::SetAspectRatio(aspect_ratio, extra_size); NativeWindow::SetAspectRatio(aspect_ratio, extra_size);
// Reset the behaviour to default if aspect_ratio is set to 0 or less. // Reset the behaviour to default if aspect_ratio is set to 0 or less.
if (aspect_ratio > 0.0) if (aspect_ratio > 0.0)
[window_ setAspectRatio:NSMakeSize(aspect_ratio, 1.0)]; [window_ setAspectRatio:NSMakeSize(aspect_ratio, 1.0)];
else else
[window_ setResizeIncrements:NSMakeSize(1.0, 1.0)]; [window_ setResizeIncrements:NSMakeSize(1.0, 1.0)];
} }
void NativeWindowMac::SetMovable(bool movable) { void NativeWindowMac::SetMovable(bool movable) {
@ -852,6 +859,11 @@ void NativeWindowMac::Center() {
} }
void NativeWindowMac::SetTitle(const std::string& title) { void NativeWindowMac::SetTitle(const std::string& title) {
// For macOS <= 10.9, the setTitleVisibility API is not available, we have
// to avoid calling setTitle for frameless window.
if (!base::mac::IsOSYosemiteOrLater() && (transparent() || !has_frame()))
return;
[window_ setTitle:base::SysUTF8ToNSString(title)]; [window_ setTitle:base::SysUTF8ToNSString(title)];
} }
@ -935,8 +947,9 @@ void NativeWindowMac::SetIgnoreMouseEvents(bool ignore) {
[window_ setIgnoresMouseEvents:ignore]; [window_ setIgnoresMouseEvents:ignore];
} }
bool NativeWindowMac::HasModalDialog() { void NativeWindowMac::SetContentProtection(bool enable) {
return [window_ attachedSheet] != nil; [window_ setSharingType:enable ? NSWindowSharingNone
: NSWindowSharingReadOnly];
} }
void NativeWindowMac::SetParentWindow(NativeWindow* parent) { void NativeWindowMac::SetParentWindow(NativeWindow* parent) {
@ -1057,7 +1070,10 @@ void NativeWindowMac::UpdateDraggableRegions(
void NativeWindowMac::InstallView() { void NativeWindowMac::InstallView() {
// Make sure the bottom corner is rounded: http://crbug.com/396264. // Make sure the bottom corner is rounded: http://crbug.com/396264.
[[window_ contentView] setWantsLayer:YES]; // But do not enable it on OS X 10.9 for transparent window, otherwise a
// semi-transparent frame would show.
if (!(transparent() && base::mac::IsOSMavericks()))
[[window_ contentView] setWantsLayer:YES];
NSView* view = inspectable_web_contents()->GetView()->GetNativeView(); NSView* view = inspectable_web_contents()->GetView()->GetNativeView();
if (has_frame()) { if (has_frame()) {
@ -1077,6 +1093,9 @@ void NativeWindowMac::InstallView() {
[view setFrame:[content_view_ bounds]]; [view setFrame:[content_view_ bounds]];
[content_view_ addSubview:view]; [content_view_ addSubview:view];
// The fullscreen button should always be hidden for frameless window.
[[window_ standardWindowButton:NSWindowFullScreenButton] setHidden:YES];
if (title_bar_style_ != NORMAL) if (title_bar_style_ != NORMAL)
return; return;

View file

@ -51,7 +51,9 @@
#include "atom/browser/ui/win/atom_desktop_window_tree_host_win.h" #include "atom/browser/ui/win/atom_desktop_window_tree_host_win.h"
#include "skia/ext/skia_utils_win.h" #include "skia/ext/skia_utils_win.h"
#include "ui/base/win/shell.h" #include "ui/base/win/shell.h"
#include "ui/gfx/win/dpi.h" #include "ui/display/win/screen_win.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
#endif #endif
@ -135,6 +137,10 @@ NativeWindowViews::NativeWindowViews(
menu_bar_autohide_(false), menu_bar_autohide_(false),
menu_bar_visible_(false), menu_bar_visible_(false),
menu_bar_alt_pressed_(false), menu_bar_alt_pressed_(false),
#if defined(OS_WIN)
enabled_a11y_support_(false),
thick_frame_(true),
#endif
keyboard_event_handler_(new views::UnhandledKeyboardEventHandler), keyboard_event_handler_(new views::UnhandledKeyboardEventHandler),
disable_count_(0), disable_count_(0),
use_content_size_(false), use_content_size_(false),
@ -152,6 +158,11 @@ NativeWindowViews::NativeWindowViews(
options.Get(options::kResizable, &resizable_); options.Get(options::kResizable, &resizable_);
options.Get(options::kMinimizable, &minimizable_); options.Get(options::kMinimizable, &minimizable_);
options.Get(options::kMaximizable, &maximizable_); options.Get(options::kMaximizable, &maximizable_);
// Transparent window must not have thick frame.
options.Get("thickFrame", &thick_frame_);
if (transparent())
thick_frame_ = false;
#endif #endif
if (enable_larger_than_screen()) if (enable_larger_than_screen())
@ -214,6 +225,9 @@ NativeWindowViews::NativeWindowViews(
bool fullscreen = false; bool fullscreen = false;
options.Get(options::kFullscreen, &fullscreen); options.Get(options::kFullscreen, &fullscreen);
std::string window_type;
options.Get(options::kType, &window_type);
#if defined(USE_X11) #if defined(USE_X11)
// Start monitoring window states. // Start monitoring window states.
window_state_watcher_.reset(new WindowStateWatcher(this)); window_state_watcher_.reset(new WindowStateWatcher(this));
@ -243,9 +257,6 @@ NativeWindowViews::NativeWindowViews(
state_atom_list.push_back(GetAtom("_NET_WM_STATE_FULLSCREEN")); state_atom_list.push_back(GetAtom("_NET_WM_STATE_FULLSCREEN"));
} }
std::string window_type;
options.Get(options::kType, &window_type);
if (parent) { if (parent) {
SetParentWindow(parent); SetParentWindow(parent);
// Force using dialog type for child window. // Force using dialog type for child window.
@ -269,13 +280,6 @@ NativeWindowViews::NativeWindowViews(
AddChildView(web_view_); AddChildView(web_view_);
#if defined(OS_WIN) #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()) { if (!has_frame()) {
// Set Window style so that we get a minimize and maximize animation when // Set Window style so that we get a minimize and maximize animation when
// frameless. // frameless.
@ -287,17 +291,18 @@ NativeWindowViews::NativeWindowViews(
if (maximizable_) if (maximizable_)
frame_style |= WS_MAXIMIZEBOX; frame_style |= WS_MAXIMIZEBOX;
// We should not show a frame for transparent window. // We should not show a frame for transparent window.
if (transparent()) if (!thick_frame_)
frame_style &= ~(WS_THICKFRAME | WS_CAPTION); frame_style &= ~(WS_THICKFRAME | WS_CAPTION);
::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, frame_style); ::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, frame_style);
} }
if (transparent()) { LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE);
// Transparent window on Windows has to have WS_EX_COMPOSITED style. // Window without thick frame has to have WS_EX_COMPOSITED style.
LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE); if (!thick_frame_)
ex_style |= WS_EX_COMPOSITED; 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 #endif
// TODO(zcbenz): This was used to force using native frame on Windows 2003, we // TODO(zcbenz): This was used to force using native frame on Windows 2003, we
@ -315,6 +320,15 @@ NativeWindowViews::NativeWindowViews(
window_->CenterWindow(size); window_->CenterWindow(size);
Layout(); 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() { NativeWindowViews::~NativeWindowViews() {
@ -335,6 +349,10 @@ void NativeWindowViews::CloseImmediately() {
} }
void NativeWindowViews::Focus(bool focus) { void NativeWindowViews::Focus(bool focus) {
// For hidden window focus() should do nothing.
if (!IsVisible())
return;
if (focus) { if (focus) {
#if defined(OS_WIN) #if defined(OS_WIN)
window_->Activate(); window_->Activate();
@ -406,6 +424,17 @@ bool NativeWindowViews::IsEnabled() {
} }
void NativeWindowViews::Maximize() { 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 =
display::Screen::GetScreen()->GetDisplayNearestPoint(GetPosition());
SetBounds(display.work_area(), false);
return;
}
#endif
if (IsVisible()) if (IsVisible())
window_->Maximize(); window_->Maximize();
else else
@ -414,6 +443,13 @@ void NativeWindowViews::Maximize() {
} }
void NativeWindowViews::Unmaximize() { void NativeWindowViews::Unmaximize() {
#if defined(OS_WIN)
if (!thick_frame_) {
SetBounds(restore_bounds_, false);
return;
}
#endif
window_->Restore(); window_->Restore();
} }
@ -450,6 +486,20 @@ void NativeWindowViews::SetFullScreen(bool fullscreen) {
last_window_state_ = ui::SHOW_STATE_NORMAL; last_window_state_ = ui::SHOW_STATE_NORMAL;
NotifyWindowLeaveFullScreen(); NotifyWindowLeaveFullScreen();
} }
// For window without WS_THICKFRAME style, we can not call SetFullscreen().
if (!thick_frame_) {
if (fullscreen) {
restore_bounds_ = GetBounds();
auto display =
display::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 // We set the new value after notifying, so we can handle the size event
// correctly. // correctly.
window_->SetFullscreen(fullscreen); window_->SetFullscreen(fullscreen);
@ -459,6 +509,12 @@ void NativeWindowViews::SetFullScreen(bool fullscreen) {
else else
window_->native_widget_private()->ShowWithWindowState( window_->native_widget_private()->ShowWithWindowState(
ui::SHOW_STATE_FULLSCREEN); ui::SHOW_STATE_FULLSCREEN);
// Auto-hide menubar when in fullscreen.
if (fullscreen)
SetMenuBarVisibility(false);
else
SetMenuBarVisibility(!menu_bar_autohide_);
#endif #endif
} }
@ -466,8 +522,7 @@ bool NativeWindowViews::IsFullscreen() const {
return window_->IsFullscreen(); return window_->IsFullscreen();
} }
void NativeWindowViews::SetBounds(const gfx::Rect& bounds, void NativeWindowViews::SetBounds(const gfx::Rect& bounds, bool animate) {
bool animate = false) {
#if defined(USE_X11) #if defined(USE_X11)
// On Linux the minimum and maximum size should be updated with window size // On Linux the minimum and maximum size should be updated with window size
// when window is not resizable. // when window is not resizable.
@ -513,7 +568,7 @@ void NativeWindowViews::SetContentSizeConstraints(
void NativeWindowViews::SetResizable(bool resizable) { void NativeWindowViews::SetResizable(bool resizable) {
#if defined(OS_WIN) #if defined(OS_WIN)
if (!transparent()) if (thick_frame_)
FlipWindowStyle(GetAcceleratedWidget(), resizable, WS_THICKFRAME); FlipWindowStyle(GetAcceleratedWidget(), resizable, WS_THICKFRAME);
#elif defined(USE_X11) #elif defined(USE_X11)
if (resizable != resizable_) { if (resizable != resizable_) {
@ -536,7 +591,11 @@ void NativeWindowViews::SetResizable(bool resizable) {
bool NativeWindowViews::IsResizable() { bool NativeWindowViews::IsResizable() {
#if defined(OS_WIN) #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 #else
return CanResize(); return CanResize();
#endif #endif
@ -728,6 +787,13 @@ void NativeWindowViews::SetIgnoreMouseEvents(bool ignore) {
#endif #endif
} }
void NativeWindowViews::SetContentProtection(bool enable) {
#if defined(OS_WIN)
DWORD affinity = enable ? WDA_MONITOR : WDA_NONE;
::SetWindowDisplayAffinity(GetAcceleratedWidget(), affinity);
#endif
}
void NativeWindowViews::SetFocusable(bool focusable) { void NativeWindowViews::SetFocusable(bool focusable) {
#if defined(OS_WIN) #if defined(OS_WIN)
LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE); LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE);
@ -741,7 +807,7 @@ void NativeWindowViews::SetFocusable(bool focusable) {
#endif #endif
} }
void NativeWindowViews::SetMenu(ui::MenuModel* menu_model) { void NativeWindowViews::SetMenu(AtomMenuModel* menu_model) {
if (menu_model == nullptr) { if (menu_model == nullptr) {
// Remove accelerators // Remove accelerators
accelerator_table_.clear(); accelerator_table_.clear();
@ -1086,9 +1152,11 @@ gfx::Size NativeWindowViews::ContentSizeToWindowSize(const gfx::Size& size) {
gfx::Size window_size(size); gfx::Size window_size(size);
#if defined(OS_WIN) #if defined(OS_WIN)
gfx::Rect dpi_bounds = HWND hwnd = GetAcceleratedWidget();
gfx::Rect(gfx::Point(), gfx::win::DIPToScreenSize(size)); gfx::Rect dpi_bounds = gfx::Rect(
gfx::Rect window_bounds = gfx::win::ScreenToDIPRect( 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_->non_client_view()->GetWindowBoundsForClientBounds(dpi_bounds));
window_size = window_bounds.size(); window_size = window_bounds.size();
#endif #endif
@ -1104,16 +1172,16 @@ gfx::Size NativeWindowViews::WindowSizeToContentSize(const gfx::Size& size) {
gfx::Size content_size(size); gfx::Size content_size(size);
#if defined(OS_WIN) #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; RECT rect;
SetRectEmpty(&rect); SetRectEmpty(&rect);
HWND hwnd = GetAcceleratedWidget();
DWORD style = ::GetWindowLong(hwnd, GWL_STYLE); DWORD style = ::GetWindowLong(hwnd, GWL_STYLE);
DWORD ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE); DWORD ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
AdjustWindowRectEx(&rect, style, FALSE, ex_style); AdjustWindowRectEx(&rect, style, FALSE, ex_style);
content_size.set_width(content_size.width() - (rect.right - rect.left)); content_size.set_width(content_size.width() - (rect.right - rect.left));
content_size.set_height(content_size.height() - (rect.bottom - rect.top)); 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 #endif
if (menu_bar_ && menu_bar_visible_) if (menu_bar_ && menu_bar_visible_)
@ -1175,7 +1243,7 @@ bool NativeWindowViews::AcceleratorPressed(const ui::Accelerator& accelerator) {
&accelerator_table_, accelerator); &accelerator_table_, accelerator);
} }
void NativeWindowViews::RegisterAccelerators(ui::MenuModel* menu_model) { void NativeWindowViews::RegisterAccelerators(AtomMenuModel* menu_model) {
// Clear previous accelerators. // Clear previous accelerators.
views::FocusManager* focus_manager = GetFocusManager(); views::FocusManager* focus_manager = GetFocusManager();
accelerator_table_.clear(); accelerator_table_.clear();

View file

@ -96,8 +96,9 @@ class NativeWindowViews : public NativeWindow,
void SetHasShadow(bool has_shadow) override; void SetHasShadow(bool has_shadow) override;
bool HasShadow() override; bool HasShadow() override;
void SetIgnoreMouseEvents(bool ignore) override; void SetIgnoreMouseEvents(bool ignore) override;
void SetContentProtection(bool enable) override;
void SetFocusable(bool focusable) override; void SetFocusable(bool focusable) override;
void SetMenu(ui::MenuModel* menu_model) override; void SetMenu(AtomMenuModel* menu_model) override;
void SetParentWindow(NativeWindow* parent) override; void SetParentWindow(NativeWindow* parent) override;
gfx::NativeWindow GetNativeWindow() override; gfx::NativeWindow GetNativeWindow() override;
void SetOverlayIcon(const gfx::Image& overlay, void SetOverlayIcon(const gfx::Image& overlay,
@ -175,7 +176,7 @@ class NativeWindowViews : public NativeWindow,
bool AcceleratorPressed(const ui::Accelerator& accelerator) override; bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
// Register accelerators supported by the menu model. // Register accelerators supported by the menu model.
void RegisterAccelerators(ui::MenuModel* menu_model); void RegisterAccelerators(AtomMenuModel* menu_model);
// Returns the restore state for the window. // Returns the restore state for the window.
ui::WindowShowState GetRestoredState(); ui::WindowShowState GetRestoredState();
@ -211,7 +212,7 @@ class NativeWindowViews : public NativeWindow,
// to receive the wrong size (#2498). To circumvent that, we keep tabs on the // to receive the wrong size (#2498). To circumvent that, we keep tabs on the
// size of the window while in the normal state (not maximized, minimized or // size of the window while in the normal state (not maximized, minimized or
// fullscreen), so we restore it correctly. // fullscreen), so we restore it correctly.
gfx::Size last_normal_size_; gfx::Rect last_normal_bounds_;
// In charge of running taskbar related APIs. // In charge of running taskbar related APIs.
TaskbarHost taskbar_host_; TaskbarHost taskbar_host_;
@ -219,6 +220,12 @@ class NativeWindowViews : public NativeWindow,
// If true we have enabled a11y // If true we have enabled a11y
bool enabled_a11y_support_; bool enabled_a11y_support_;
// Whether to show the WS_THICKFRAME style.
bool thick_frame_;
// The bounds of window before maximize/fullscreen.
gfx::Rect restore_bounds_;
// The icons of window and taskbar. // The icons of window and taskbar.
base::win::ScopedHICON window_icon_; base::win::ScopedHICON window_icon_;
base::win::ScopedHICON app_icon_; base::win::ScopedHICON app_icon_;

View file

@ -2,6 +2,7 @@
// Use of this source code is governed by the MIT license that can be // Use of this source code is governed by the MIT license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "atom/browser/browser.h"
#include "atom/browser/native_window_views.h" #include "atom/browser/native_window_views.h"
#include "content/public/browser/browser_accessibility_state.h" #include "content/public/browser/browser_accessibility_state.h"
@ -98,6 +99,7 @@ bool NativeWindowViews::PreHandleMSG(
if (axState && !axState->IsAccessibleBrowser()) { if (axState && !axState->IsAccessibleBrowser()) {
axState->OnScreenReaderDetected(); axState->OnScreenReaderDetected();
enabled_a11y_support_ = true; enabled_a11y_support_ = true;
Browser::Get()->OnAccessibilitySupportChanged();
} }
} }
@ -119,7 +121,10 @@ bool NativeWindowViews::PreHandleMSG(
::GetWindowRect(GetAcceleratedWidget(), (LPRECT)l_param); ::GetWindowRect(GetAcceleratedWidget(), (LPRECT)l_param);
return false; return false;
} }
case WM_MOVE: {
last_normal_bounds_ = GetBounds();
return false;
}
default: default:
return false; return false;
} }
@ -140,7 +145,7 @@ void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) {
case SIZE_RESTORED: case SIZE_RESTORED:
if (last_window_state_ == ui::SHOW_STATE_NORMAL) { if (last_window_state_ == ui::SHOW_STATE_NORMAL) {
// Window was resized so we save it's new size. // Window was resized so we save it's new size.
last_normal_size_ = GetSize(); last_normal_bounds_ = GetBounds();
} else { } else {
switch (last_window_state_) { switch (last_window_state_) {
case ui::SHOW_STATE_MAXIMIZED: case ui::SHOW_STATE_MAXIMIZED:
@ -148,7 +153,7 @@ void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) {
// When the window is restored we resize it to the previous known // When the window is restored we resize it to the previous known
// normal size. // normal size.
NativeWindow::SetSize(last_normal_size_); SetBounds(last_normal_bounds_, false);
NotifyWindowUnmaximize(); NotifyWindowUnmaximize();
break; break;
@ -161,7 +166,7 @@ void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) {
// When the window is restored we resize it to the previous known // When the window is restored we resize it to the previous known
// normal size. // normal size.
NativeWindow::SetSize(last_normal_size_); SetBounds(last_normal_bounds_, false);
NotifyWindowRestore(); NotifyWindowRestore();
} }

View file

@ -22,7 +22,7 @@ net::URLRequestJob* AsarProtocolHandler::MaybeCreateJob(
net::NetworkDelegate* network_delegate) const { net::NetworkDelegate* network_delegate) const {
base::FilePath full_path; base::FilePath full_path;
net::FileURLToFilePath(request->url(), &full_path); net::FileURLToFilePath(request->url(), &full_path);
URLRequestAsarJob* job = new URLRequestAsarJob(request, network_delegate); auto* job = new URLRequestAsarJob(request, network_delegate);
job->Initialize(file_task_runner_, full_path); job->Initialize(file_task_runner_, full_path);
return job; return job;
} }

View file

@ -111,7 +111,7 @@ void URLRequestAsarJob::Start() {
if (rv != net::ERR_IO_PENDING) if (rv != net::ERR_IO_PENDING)
DidOpen(rv); DidOpen(rv);
} else if (type_ == TYPE_FILE) { } else if (type_ == TYPE_FILE) {
FileMetaInfo* meta_info = new FileMetaInfo(); auto* meta_info = new FileMetaInfo();
file_task_runner_->PostTaskAndReply( file_task_runner_->PostTaskAndReply(
FROM_HERE, FROM_HERE,
base::Bind(&URLRequestAsarJob::FetchMetaInfo, file_path_, base::Bind(&URLRequestAsarJob::FetchMetaInfo, file_path_,
@ -180,10 +180,10 @@ bool URLRequestAsarJob::IsRedirectResponse(GURL* location,
#endif #endif
} }
net::Filter* URLRequestAsarJob::SetupFilter() const { std::unique_ptr<net::Filter> URLRequestAsarJob::SetupFilter() const {
// Bug 9936 - .svgz files needs to be decompressed. // Bug 9936 - .svgz files needs to be decompressed.
return base::LowerCaseEqualsASCII(file_path_.Extension(), ".svgz") return base::LowerCaseEqualsASCII(file_path_.Extension(), ".svgz")
? net::Filter::GZipFactory() : NULL; ? net::Filter::GZipFactory() : nullptr;
} }
bool URLRequestAsarJob::GetMimeType(std::string* mime_type) const { bool URLRequestAsarJob::GetMimeType(std::string* mime_type) const {
@ -224,7 +224,7 @@ int URLRequestAsarJob::GetResponseCode() const {
void URLRequestAsarJob::GetResponseInfo(net::HttpResponseInfo* info) { void URLRequestAsarJob::GetResponseInfo(net::HttpResponseInfo* info) {
std::string status("HTTP/1.1 200 OK"); 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); headers->AddHeader(atom::kCORSHeader);
info->headers = headers; info->headers = headers;
@ -338,7 +338,7 @@ void URLRequestAsarJob::DidRead(scoped_refptr<net::IOBuffer> buf, int result) {
DCHECK_GE(remaining_bytes_, 0); DCHECK_GE(remaining_bytes_, 0);
} }
buf = NULL; buf = nullptr;
ReadRawDataComplete(result); ReadRawDataComplete(result);
} }

View file

@ -56,7 +56,7 @@ class URLRequestAsarJob : public net::URLRequestJob {
void Kill() override; void Kill() override;
int ReadRawData(net::IOBuffer* buf, int buf_size) override; int ReadRawData(net::IOBuffer* buf, int buf_size) override;
bool IsRedirectResponse(GURL* location, int* http_status_code) override; bool IsRedirectResponse(GURL* location, int* http_status_code) override;
net::Filter* SetupFilter() const override; std::unique_ptr<net::Filter> SetupFilter() const override;
bool GetMimeType(std::string* mime_type) const override; bool GetMimeType(std::string* mime_type) const override;
void SetExtraRequestHeaders(const net::HttpRequestHeaders& headers) override; void SetExtraRequestHeaders(const net::HttpRequestHeaders& headers) override;
int GetResponseCode() const override; int GetResponseCode() const override;

View file

@ -36,7 +36,6 @@ AtomCertVerifier::~AtomCertVerifier() {
} }
void AtomCertVerifier::SetVerifyProc(const VerifyProc& proc) { void AtomCertVerifier::SetVerifyProc(const VerifyProc& proc) {
base::AutoLock auto_lock(lock_);
verify_proc_ = proc; verify_proc_ = proc;
} }
@ -52,20 +51,14 @@ int AtomCertVerifier::Verify(
const net::BoundNetLog& net_log) { const net::BoundNetLog& net_log) {
DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK_CURRENTLY_ON(BrowserThread::IO);
VerifyProc proc; if (verify_proc_.is_null())
{
base::AutoLock auto_lock(lock_);
proc = verify_proc_;
}
if (proc.is_null())
return default_cert_verifier_->Verify( return default_cert_verifier_->Verify(
cert, hostname, ocsp_response, flags, crl_set, verify_result, callback, cert, hostname, ocsp_response, flags, crl_set, verify_result, callback,
out_req, net_log); out_req, net_log);
BrowserThread::PostTask( BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE, BrowserThread::UI, FROM_HERE,
base::Bind(proc, hostname, make_scoped_refptr(cert), base::Bind(verify_proc_, hostname, make_scoped_refptr(cert),
base::Bind(OnResult, verify_result, callback))); base::Bind(OnResult, verify_result, callback)));
return net::ERR_IO_PENDING; return net::ERR_IO_PENDING;
} }

View file

@ -5,10 +5,9 @@
#ifndef ATOM_BROWSER_NET_ATOM_CERT_VERIFIER_H_ #ifndef ATOM_BROWSER_NET_ATOM_CERT_VERIFIER_H_
#define ATOM_BROWSER_NET_ATOM_CERT_VERIFIER_H_ #define ATOM_BROWSER_NET_ATOM_CERT_VERIFIER_H_
#include <memory>
#include <string> #include <string>
#include "base/memory/ref_counted.h"
#include "base/synchronization/lock.h"
#include "net/cert/cert_verifier.h" #include "net/cert/cert_verifier.h"
namespace atom { namespace atom {
@ -39,7 +38,6 @@ class AtomCertVerifier : public net::CertVerifier {
bool SupportsOCSPStapling() override; bool SupportsOCSPStapling() override;
private: private:
base::Lock lock_;
VerifyProc verify_proc_; VerifyProc verify_proc_;
std::unique_ptr<net::CertVerifier> default_cert_verifier_; std::unique_ptr<net::CertVerifier> default_cert_verifier_;

View file

@ -20,14 +20,14 @@ typedef net::URLRequestJobFactory::ProtocolHandler ProtocolHandler;
AtomURLRequestJobFactory::AtomURLRequestJobFactory() {} AtomURLRequestJobFactory::AtomURLRequestJobFactory() {}
AtomURLRequestJobFactory::~AtomURLRequestJobFactory() { AtomURLRequestJobFactory::~AtomURLRequestJobFactory() {
STLDeleteValues(&protocol_handler_map_); Clear();
} }
bool AtomURLRequestJobFactory::SetProtocolHandler( bool AtomURLRequestJobFactory::SetProtocolHandler(
const std::string& scheme, const std::string& scheme,
std::unique_ptr<ProtocolHandler> protocol_handler) { std::unique_ptr<ProtocolHandler> protocol_handler) {
if (!protocol_handler) { if (!protocol_handler) {
ProtocolHandlerMap::iterator it = protocol_handler_map_.find(scheme); auto it = protocol_handler_map_.find(scheme);
if (it == protocol_handler_map_.end()) if (it == protocol_handler_map_.end())
return false; return false;
@ -66,7 +66,7 @@ ProtocolHandler* AtomURLRequestJobFactory::GetProtocolHandler(
const std::string& scheme) const { const std::string& scheme) const {
DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK_CURRENTLY_ON(BrowserThread::IO);
ProtocolHandlerMap::const_iterator it = protocol_handler_map_.find(scheme); auto it = protocol_handler_map_.find(scheme);
if (it == protocol_handler_map_.end()) if (it == protocol_handler_map_.end())
return nullptr; return nullptr;
return it->second; return it->second;
@ -77,13 +77,17 @@ bool AtomURLRequestJobFactory::HasProtocolHandler(
return ContainsKey(protocol_handler_map_, scheme); return ContainsKey(protocol_handler_map_, scheme);
} }
void AtomURLRequestJobFactory::Clear() {
STLDeleteValues(&protocol_handler_map_);
}
net::URLRequestJob* AtomURLRequestJobFactory::MaybeCreateJobWithProtocolHandler( net::URLRequestJob* AtomURLRequestJobFactory::MaybeCreateJobWithProtocolHandler(
const std::string& scheme, const std::string& scheme,
net::URLRequest* request, net::URLRequest* request,
net::NetworkDelegate* network_delegate) const { net::NetworkDelegate* network_delegate) const {
DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK_CURRENTLY_ON(BrowserThread::IO);
ProtocolHandlerMap::const_iterator it = protocol_handler_map_.find(scheme); auto it = protocol_handler_map_.find(scheme);
if (it == protocol_handler_map_.end()) if (it == protocol_handler_map_.end())
return nullptr; return nullptr;
return it->second->MaybeCreateJob(request, network_delegate); return it->second->MaybeCreateJob(request, network_delegate);

View file

@ -39,6 +39,9 @@ class AtomURLRequestJobFactory : public net::URLRequestJobFactory {
// Whether the protocol handler is registered by the job factory. // Whether the protocol handler is registered by the job factory.
bool HasProtocolHandler(const std::string& scheme) const; bool HasProtocolHandler(const std::string& scheme) const;
// Clear all protocol handlers.
void Clear();
// URLRequestJobFactory implementation // URLRequestJobFactory implementation
net::URLRequestJob* MaybeCreateJobWithProtocolHandler( net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
const std::string& scheme, const std::string& scheme,

View file

@ -40,7 +40,7 @@ void URLRequestAsyncAsarJob::StartAsync(std::unique_ptr<base::Value> options) {
void URLRequestAsyncAsarJob::GetResponseInfo(net::HttpResponseInfo* info) { void URLRequestAsyncAsarJob::GetResponseInfo(net::HttpResponseInfo* info) {
std::string status("HTTP/1.1 200 OK"); std::string status("HTTP/1.1 200 OK");
net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status); auto* headers = new net::HttpResponseHeaders(status);
headers->AddHeader(kCORSHeader); headers->AddHeader(kCORSHeader);
info->headers = headers; info->headers = headers;

View file

@ -72,7 +72,7 @@ void URLRequestBufferJob::GetResponseInfo(net::HttpResponseInfo* info) {
status.append(" "); status.append(" ");
status.append(net::GetHttpReasonPhrase(status_code_)); status.append(net::GetHttpReasonPhrase(status_code_));
status.append("\0\0", 2); status.append("\0\0", 2);
net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status); auto* headers = new net::HttpResponseHeaders(status);
headers->AddHeader(kCORSHeader); headers->AddHeader(kCORSHeader);

View file

@ -7,6 +7,7 @@
#include <algorithm> #include <algorithm>
#include <string> #include <string>
#include "base/memory/ptr_util.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "native_mate/dictionary.h" #include "native_mate/dictionary.h"
#include "net/base/io_buffer.h" #include "net/base/io_buffer.h"
@ -132,7 +133,7 @@ void URLRequestFetchJob::StartAsync(std::unique_ptr<base::Value> options) {
request_type = GetRequestType(method); request_type = GetRequestType(method);
fetcher_ = net::URLFetcher::Create(formated_url, request_type, this); fetcher_ = net::URLFetcher::Create(formated_url, request_type, this);
fetcher_->SaveResponseWithWriter(make_scoped_ptr(new ResponsePiper(this))); fetcher_->SaveResponseWithWriter(base::WrapUnique(new ResponsePiper(this)));
// A request context getter is passed by the user. // A request context getter is passed by the user.
if (url_request_context_getter_) if (url_request_context_getter_)

View file

@ -31,7 +31,7 @@ void URLRequestStringJob::StartAsync(std::unique_ptr<base::Value> options) {
void URLRequestStringJob::GetResponseInfo(net::HttpResponseInfo* info) { void URLRequestStringJob::GetResponseInfo(net::HttpResponseInfo* info) {
std::string status("HTTP/1.1 200 OK"); std::string status("HTTP/1.1 200 OK");
net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status); auto* headers = new net::HttpResponseHeaders(status);
headers->AddHeader(kCORSHeader); headers->AddHeader(kCORSHeader);

View file

@ -5,9 +5,9 @@
#ifndef ATOM_BROWSER_NODE_DEBUGGER_H_ #ifndef ATOM_BROWSER_NODE_DEBUGGER_H_
#define ATOM_BROWSER_NODE_DEBUGGER_H_ #define ATOM_BROWSER_NODE_DEBUGGER_H_
#include <memory>
#include <string> #include <string>
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/threading/thread.h" #include "base/threading/thread.h"
#include "net/test/embedded_test_server/stream_listen_socket.h" #include "net/test/embedded_test_server/stream_listen_socket.h"

View file

@ -4,11 +4,13 @@
#include "atom/browser/relauncher.h" #include "atom/browser/relauncher.h"
#include <fcntl.h>
#include <signal.h> #include <signal.h>
#include <sys/prctl.h> #include <sys/prctl.h>
#include <sys/signalfd.h> #include <sys/signalfd.h>
#include "base/files/file_util.h" #include "base/files/file_util.h"
#include "base/files/scoped_file.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/posix/eintr_wrapper.h" #include "base/posix/eintr_wrapper.h"
#include "base/process/launch.h" #include "base/process/launch.h"
@ -55,9 +57,17 @@ void RelauncherSynchronizeWithParent() {
int LaunchProgram(const StringVector& relauncher_args, int LaunchProgram(const StringVector& relauncher_args,
const StringVector& argv) { const StringVector& argv) {
// Redirect the stdout of child process to /dev/null, otherwise after
// relaunch the child process will raise exception when writing to stdout.
base::ScopedFD devnull(HANDLE_EINTR(open("/dev/null", O_WRONLY)));
base::FileHandleMappingVector no_stdout;
no_stdout.push_back(std::make_pair(devnull.get(), STDERR_FILENO));
no_stdout.push_back(std::make_pair(devnull.get(), STDOUT_FILENO));
base::LaunchOptions options; base::LaunchOptions options;
options.allow_new_privs = true; options.allow_new_privs = true;
options.new_process_group = true; // detach options.new_process_group = true; // detach
options.fds_to_remap = &no_stdout;
base::Process process = base::LaunchProcess(argv, options); base::Process process = base::LaunchProcess(argv, options);
return process.IsValid() ? 0 : 1; return process.IsValid() ? 0 : 1;
} }

View file

@ -43,7 +43,7 @@ void RelauncherSynchronizeWithParent() {
struct kevent change = { 0 }; struct kevent change = { 0 };
EV_SET(&change, parent_pid, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, NULL); EV_SET(&change, parent_pid, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, NULL);
if (kevent(kq.get(), &change, 1, NULL, 0, NULL) == -1) { if (kevent(kq.get(), &change, 1, nullptr, 0, nullptr) == -1) {
PLOG(ERROR) << "kevent (add)"; PLOG(ERROR) << "kevent (add)";
return; return;
} }
@ -58,7 +58,7 @@ void RelauncherSynchronizeWithParent() {
// write above to complete. The parent process is now free to exit. Wait for // write above to complete. The parent process is now free to exit. Wait for
// that to happen. // that to happen.
struct kevent event; struct kevent event;
int events = kevent(kq.get(), NULL, 0, &event, 1, NULL); int events = kevent(kq.get(), nullptr, 0, &event, 1, nullptr);
if (events != 1) { if (events != 1) {
if (events < 0) { if (events < 0) {
PLOG(ERROR) << "kevent (monitor)"; PLOG(ERROR) << "kevent (monitor)";
@ -79,8 +79,16 @@ void RelauncherSynchronizeWithParent() {
int LaunchProgram(const StringVector& relauncher_args, int LaunchProgram(const StringVector& relauncher_args,
const StringVector& argv) { const StringVector& argv) {
// Redirect the stdout of child process to /dev/null, otherwise after
// relaunch the child process will raise exception when writing to stdout.
base::ScopedFD devnull(HANDLE_EINTR(open("/dev/null", O_WRONLY)));
base::FileHandleMappingVector no_stdout;
no_stdout.push_back(std::make_pair(devnull.get(), STDERR_FILENO));
no_stdout.push_back(std::make_pair(devnull.get(), STDOUT_FILENO));
base::LaunchOptions options; base::LaunchOptions options;
options.new_process_group = true; // detach options.new_process_group = true; // detach
options.fds_to_remap = &no_stdout;
base::Process process = base::LaunchProcess(argv, options); base::Process process = base::LaunchProcess(argv, options);
return process.IsValid() ? 0 : 1; return process.IsValid() ? 0 : 1;
} }

View file

@ -17,9 +17,9 @@
<key>CFBundleIconFile</key> <key>CFBundleIconFile</key>
<string>electron.icns</string> <string>electron.icns</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.2.3</string> <string>1.3.1</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>1.2.3</string> <string>1.3.1</string>
<key>LSApplicationCategoryType</key> <key>LSApplicationCategoryType</key>
<string>public.app-category.developer-tools</string> <string>public.app-category.developer-tools</string>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 368 KiB

Before After
Before After

View file

@ -56,8 +56,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,2,3,0 FILEVERSION 1,3,1,0
PRODUCTVERSION 1,2,3,0 PRODUCTVERSION 1,3,1,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -74,12 +74,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "GitHub, Inc." VALUE "CompanyName", "GitHub, Inc."
VALUE "FileDescription", "Electron" VALUE "FileDescription", "Electron"
VALUE "FileVersion", "1.2.3" VALUE "FileVersion", "1.3.1"
VALUE "InternalName", "electron.exe" VALUE "InternalName", "electron.exe"
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
VALUE "OriginalFilename", "electron.exe" VALUE "OriginalFilename", "electron.exe"
VALUE "ProductName", "Electron" VALUE "ProductName", "Electron"
VALUE "ProductVersion", "1.2.3" VALUE "ProductVersion", "1.3.1"
VALUE "SquirrelAwareVersion", "1" VALUE "SquirrelAwareVersion", "1"
END END
END END

View file

@ -14,7 +14,6 @@
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h" #include "base/strings/string_split.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "ui/base/models/simple_menu_model.h"
namespace accelerator_util { namespace accelerator_util {
@ -31,9 +30,9 @@ bool StringToAccelerator(const std::string& shortcut,
// Now, parse it into an accelerator. // Now, parse it into an accelerator.
int modifiers = ui::EF_NONE; int modifiers = ui::EF_NONE;
ui::KeyboardCode key = ui::VKEY_UNKNOWN; ui::KeyboardCode key = ui::VKEY_UNKNOWN;
for (size_t i = 0; i < tokens.size(); i++) { for (const auto& token : tokens) {
bool shifted = false; bool shifted = false;
ui::KeyboardCode code = atom::KeyboardCodeFromStr(tokens[i], &shifted); ui::KeyboardCode code = atom::KeyboardCodeFromStr(token, &shifted);
if (shifted) if (shifted)
modifiers |= ui::EF_SHIFT_DOWN; modifiers |= ui::EF_SHIFT_DOWN;
switch (code) { switch (code) {
@ -69,16 +68,17 @@ bool StringToAccelerator(const std::string& shortcut,
return true; return true;
} }
void GenerateAcceleratorTable(AcceleratorTable* table, ui::MenuModel* model) { void GenerateAcceleratorTable(AcceleratorTable* table,
atom::AtomMenuModel* model) {
int count = model->GetItemCount(); int count = model->GetItemCount();
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
ui::MenuModel::ItemType type = model->GetTypeAt(i); atom::AtomMenuModel::ItemType type = model->GetTypeAt(i);
if (type == ui::MenuModel::TYPE_SUBMENU) { if (type == atom::AtomMenuModel::TYPE_SUBMENU) {
ui::MenuModel* submodel = model->GetSubmenuModelAt(i); auto submodel = model->GetSubmenuModelAt(i);
GenerateAcceleratorTable(table, submodel); GenerateAcceleratorTable(table, submodel);
} else { } else {
ui::Accelerator accelerator; ui::Accelerator accelerator;
if (model->GetAcceleratorAt(i, &accelerator)) { if (model->GetAcceleratorAtWithParams(i, true, &accelerator)) {
MenuItem item = { i, model }; MenuItem item = { i, model };
(*table)[accelerator] = item; (*table)[accelerator] = item;
} }

View file

@ -8,15 +8,12 @@
#include <map> #include <map>
#include <string> #include <string>
#include "atom/browser/ui/atom_menu_model.h"
#include "ui/base/accelerators/accelerator.h" #include "ui/base/accelerators/accelerator.h"
namespace ui {
class MenuModel;
}
namespace accelerator_util { namespace accelerator_util {
typedef struct { int position; ui::MenuModel* model; } MenuItem; typedef struct { int position; atom::AtomMenuModel* model; } MenuItem;
typedef std::map<ui::Accelerator, MenuItem> AcceleratorTable; typedef std::map<ui::Accelerator, MenuItem> AcceleratorTable;
// Parse a string as an accelerator. // Parse a string as an accelerator.
@ -27,7 +24,8 @@ bool StringToAccelerator(const std::string& description,
void SetPlatformAccelerator(ui::Accelerator* accelerator); void SetPlatformAccelerator(ui::Accelerator* accelerator);
// Generate a table that contains memu model's accelerators and command ids. // Generate a table that contains memu model's accelerators and command ids.
void GenerateAcceleratorTable(AcceleratorTable* table, ui::MenuModel* model); void GenerateAcceleratorTable(AcceleratorTable* table,
atom::AtomMenuModel* model);
// Trigger command from the accelerators table. // Trigger command from the accelerators table.
bool TriggerAcceleratorTableCommand(AcceleratorTable* table, bool TriggerAcceleratorTableCommand(AcceleratorTable* table,

View file

@ -29,6 +29,10 @@ void SetPlatformAccelerator(ui::Accelerator* accelerator) {
modifiers ^= NSShiftKeyMask; modifiers ^= NSShiftKeyMask;
} }
if (character == NSDeleteFunctionKey) {
character = NSDeleteCharacter;
}
NSString* characters = NSString* characters =
[[[NSString alloc] initWithCharacters:&character length:1] autorelease]; [[[NSString alloc] initWithCharacters:&character length:1] autorelease];

View file

@ -17,19 +17,37 @@ AtomMenuModel::~AtomMenuModel() {
} }
void AtomMenuModel::SetRole(int index, const base::string16& role) { void AtomMenuModel::SetRole(int index, const base::string16& role) {
roles_[index] = role; int command_id = GetCommandIdAt(index);
roles_[command_id] = role;
} }
base::string16 AtomMenuModel::GetRoleAt(int index) { base::string16 AtomMenuModel::GetRoleAt(int index) {
if (ContainsKey(roles_, index)) int command_id = GetCommandIdAt(index);
return roles_[index]; if (ContainsKey(roles_, command_id))
return roles_[command_id];
else else
return base::string16(); return base::string16();
} }
bool AtomMenuModel::GetAcceleratorAtWithParams(
int index,
bool use_default_accelerator,
ui::Accelerator* accelerator) const {
if (delegate_) {
return delegate_->GetAcceleratorForCommandIdWithParams(
GetCommandIdAt(index), use_default_accelerator, accelerator);
}
return false;
}
void AtomMenuModel::MenuClosed() { void AtomMenuModel::MenuClosed() {
ui::SimpleMenuModel::MenuClosed(); ui::SimpleMenuModel::MenuClosed();
FOR_EACH_OBSERVER(Observer, observers_, MenuClosed()); FOR_EACH_OBSERVER(Observer, observers_, MenuClosed());
} }
AtomMenuModel* AtomMenuModel::GetSubmenuModelAt(int index) {
return static_cast<AtomMenuModel*>(
ui::SimpleMenuModel::GetSubmenuModelAt(index));
}
} // namespace atom } // namespace atom

View file

@ -17,6 +17,19 @@ class AtomMenuModel : public ui::SimpleMenuModel {
class Delegate : public ui::SimpleMenuModel::Delegate { class Delegate : public ui::SimpleMenuModel::Delegate {
public: public:
virtual ~Delegate() {} virtual ~Delegate() {}
virtual bool GetAcceleratorForCommandIdWithParams(
int command_id,
bool use_default_accelerator,
ui::Accelerator* accelerator) const = 0;
private:
// ui::SimpleMenuModel::Delegate:
bool GetAcceleratorForCommandId(int command_id,
ui::Accelerator* accelerator) {
return GetAcceleratorForCommandIdWithParams(
command_id, false, accelerator);
}
}; };
class Observer { class Observer {
@ -35,14 +48,20 @@ class AtomMenuModel : public ui::SimpleMenuModel {
void SetRole(int index, const base::string16& role); void SetRole(int index, const base::string16& role);
base::string16 GetRoleAt(int index); base::string16 GetRoleAt(int index);
bool GetAcceleratorAtWithParams(int index,
bool use_default_accelerator,
ui::Accelerator* accelerator) const;
// ui::SimpleMenuModel: // ui::SimpleMenuModel:
void MenuClosed() override; void MenuClosed() override;
using SimpleMenuModel::GetSubmenuModelAt;
AtomMenuModel* GetSubmenuModelAt(int index);
private: private:
Delegate* delegate_; // weak ref. Delegate* delegate_; // weak ref.
std::map<int, base::string16> roles_; std::map<int, base::string16> roles_; // command id -> role
base::ObserverList<Observer> observers_; base::ObserverList<Observer> observers_;
DISALLOW_COPY_AND_ASSIGN(AtomMenuModel); DISALLOW_COPY_AND_ASSIGN(AtomMenuModel);

View file

@ -11,8 +11,8 @@
#include "base/mac/scoped_nsobject.h" #include "base/mac/scoped_nsobject.h"
#include "base/strings/string16.h" #include "base/strings/string16.h"
namespace ui { namespace atom {
class MenuModel; class AtomMenuModel;
} }
// A controller for the cross-platform menu model. The menu that's created // A controller for the cross-platform menu model. The menu that's created
@ -23,24 +23,20 @@ class MenuModel;
// as it only maintains weak references. // as it only maintains weak references.
@interface AtomMenuController : NSObject<NSMenuDelegate> { @interface AtomMenuController : NSObject<NSMenuDelegate> {
@protected @protected
ui::MenuModel* model_; // weak atom::AtomMenuModel* model_; // weak
base::scoped_nsobject<NSMenu> menu_; base::scoped_nsobject<NSMenu> menu_;
BOOL isMenuOpen_; BOOL isMenuOpen_;
BOOL useDefaultAccelerator_;
} }
@property(nonatomic, assign) ui::MenuModel* model; @property(nonatomic, assign) atom::AtomMenuModel* model;
// NIB-based initializer. This does not create a menu. Clients can set the
// properties of the object and the menu will be created upon the first call to
// |-menu|. Note that the menu will be immutable after creation.
- (id)init;
// Builds a NSMenu from the pre-built model (must not be nil). Changes made // Builds a NSMenu from the pre-built model (must not be nil). Changes made
// to the contents of the model after calling this will not be noticed. // to the contents of the model after calling this will not be noticed.
- (id)initWithModel:(ui::MenuModel*)model; - (id)initWithModel:(atom::AtomMenuModel*)model useDefaultAccelerator:(BOOL)use;
// Populate current NSMenu with |model|. // Populate current NSMenu with |model|.
- (void)populateWithModel:(ui::MenuModel*)model; - (void)populateWithModel:(atom::AtomMenuModel*)model;
// Programmatically close the constructed menu. // Programmatically close the constructed menu.
- (void)cancel; - (void)cancel;

Some files were not shown because too many files have changed in this diff Show more