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-kr`](http://www.meetup.com/electron-kr/) *(한국)* 커뮤니티
- [`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) 프로젝트에
커뮤니티가 운영중인 유용한 예시 애플리케이션과 도구, 리소스가 있으니 참고하기 바랍니다.

View file

@ -72,6 +72,8 @@ forums
- [`electron-br`](https://electron-br.slack.com) *(Brazilian Portuguese)*
- [`electron-kr`](http://www.meetup.com/electron-kr/) *(Korean)*
- [`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)
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 "content/public/app/sandbox_helper_win.h"
#include "sandbox/win/src/sandbox_types.h"
#include "ui/gfx/win/dpi.h"
#elif defined(OS_LINUX) // defined(OS_WIN)
#include "atom/app/atom_main_delegate.h" // NOLINT
#include "content/public/app/content_main.h"

View file

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

View file

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

View file

@ -32,6 +32,7 @@
#include "base/strings/string_util.h"
#include "brightray/browser/brightray_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/gpu_data_manager.h"
#include "content/public/browser/render_frame_host.h"
@ -71,6 +72,30 @@ struct Converter<Browser::UserTask> {
};
#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
@ -254,6 +279,10 @@ void App::OnFinishLaunching() {
Emit("ready");
}
void App::OnAccessibilitySupportChanged() {
Emit("accessibility-support-changed", IsAccessibilitySupportEnabled());
}
#if defined(OS_MACOSX)
void App::OnContinueUserActivity(
bool* prevent_default,
@ -459,14 +488,20 @@ void App::DisableHardwareAcceleration(mate::Arguments* args) {
content::GpuDataManager::GetInstance()->DisableHardwareAcceleration();
}
bool App::IsAccessibilitySupportEnabled() {
auto ax_state = content::BrowserAccessibilityState::GetInstance();
return ax_state->IsAccessibleBrowser();
}
#if defined(USE_NSS_CERTS)
void App::ImportCertificate(
const base::DictionaryValue& options,
const net::CompletionCallback& callback) {
auto browser_context = AtomBrowserMainParts::Get()->browser_context();
auto browser_context = AtomBrowserContext::From("", false);
if (!certificate_manager_model_) {
std::unique_ptr<base::DictionaryValue> copy = options.CreateDeepCopy();
CertificateManagerModel::Create(browser_context,
CertificateManagerModel::Create(
browser_context.get(),
base::Bind(&App::OnCertificateManagerModelCreated,
base::Unretained(this),
base::Passed(&copy),
@ -519,6 +554,12 @@ void App::BuildPrototype(
base::Bind(&Browser::SetAsDefaultProtocolClient, browser))
.SetMethod("removeAsDefaultProtocolClient",
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)
.SetMethod("hide", base::Bind(&Browser::Hide, browser))
.SetMethod("show", base::Bind(&Browser::Show, browser))
@ -528,8 +569,11 @@ void App::BuildPrototype(
base::Bind(&Browser::GetCurrentActivityType, browser))
#endif
#if defined(OS_WIN)
.SetMethod("setUserTasks",
base::Bind(&Browser::SetUserTasks, browser))
.SetMethod("setUserTasks", base::Bind(&Browser::SetUserTasks, browser))
#endif
#if defined(OS_LINUX)
.SetMethod("isUnityRunning",
base::Bind(&Browser::IsUnityRunning, browser))
#endif
.SetMethod("setPath", &App::SetPath)
.SetMethod("getPath", &App::GetPath)
@ -541,6 +585,8 @@ void App::BuildPrototype(
.SetMethod("makeSingleInstance", &App::MakeSingleInstance)
.SetMethod("releaseSingleInstance", &App::ReleaseSingleInstance)
.SetMethod("relaunch", &App::Relaunch)
.SetMethod("isAccessibilitySupportEnabled",
&App::IsAccessibilitySupportEnabled)
.SetMethod("disableHardwareAcceleration",
&App::DisableHardwareAcceleration);
}

View file

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

View file

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

View file

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

View file

@ -4,6 +4,7 @@
#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/gurl_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)
return v8::Null(isolate);
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
Cookies::Cookies(v8::Isolate* isolate,
content::BrowserContext* browser_context)
: request_context_getter_(browser_context->GetRequestContext()) {
AtomBrowserContext* browser_context)
: request_context_getter_(browser_context->url_request_context_getter()) {
Init(isolate);
}
@ -241,7 +242,7 @@ void Cookies::Set(const base::DictionaryValue& details,
// static
mate::Handle<Cookies> Cookies::Create(
v8::Isolate* isolate,
content::BrowserContext* browser_context) {
AtomBrowserContext* browser_context) {
return mate::CreateHandle(isolate, new Cookies(isolate, browser_context));
}

View file

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

View file

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

View file

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

View file

@ -5,6 +5,7 @@
#import "atom/browser/api/atom_api_menu_mac.h"
#include "atom/browser/native_window.h"
#include "atom/browser/unresponsive_suppressor.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/sys_string_conversions.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;
base::scoped_nsobject<AtomMenuController> menu_controller(
[[AtomMenuController alloc] initWithModel:model_.get()]);
[[AtomMenuController alloc] initWithModel:model_.get()
useDefaultAccelerator:NO]);
NSMenu* menu = [menu_controller menu];
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)
position.x = position.x - [menu size].width;
// Don't emit unresponsive event when showing menu.
atom::UnresponsiveSuppressor suppressor;
// Show the menu.
[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) {
MenuMac* menu = static_cast<MenuMac*>(base_menu);
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]];
// 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/native_window_views.h"
#include "atom/browser/unresponsive_suppressor.h"
#include "content/public/browser/render_widget_host_view.h"
#include "ui/gfx/screen.h"
#include "ui/display/screen.h"
#include "ui/views/controls/menu/menu_runner.h"
namespace atom {
@ -30,12 +31,15 @@ void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item) {
// (-1, -1) means showing on mouse location.
gfx::Point location;
if (x == -1 || y == -1) {
location = gfx::Screen::GetScreen()->GetCursorScreenPoint();
location = display::Screen::GetScreen()->GetCursorScreenPoint();
} else {
gfx::Point origin = view->GetViewBounds().origin();
location = gfx::Point(origin.x() + x, origin.y() + y);
}
// Don't emit unresponsive event when showing menu.
atom::UnresponsiveSuppressor suppressor;
// Show the menu.
views::MenuRunner menu_runner(
model(),

View file

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

View file

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

View file

@ -6,6 +6,7 @@
#include "atom/browser/atom_browser_client.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/browser.h"
#include "atom/browser/net/url_request_async_asar_job.h"
#include "atom/browser/net/url_request_buffer_job.h"
#include "atom/browser/net/url_request_fetch_job.h"
@ -26,13 +27,30 @@ namespace atom {
namespace api {
namespace {
// Clear protocol handlers in IO thread.
void ClearJobFactoryInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter) {
auto job_factory = static_cast<AtomURLRequestJobFactory*>(
request_context_getter->job_factory());
job_factory->Clear();
}
} // namespace
Protocol::Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context)
: request_context_getter_(static_cast<brightray::URLRequestContextGetter*>(
browser_context->GetRequestContext())),
: request_context_getter_(browser_context->GetRequestContext()),
weak_factory_(this) {
Init(isolate);
}
Protocol::~Protocol() {
content::BrowserThread::PostTask(
content::BrowserThread::IO, FROM_HERE,
base::Bind(ClearJobFactoryInIO, request_context_getter_));
}
void Protocol::RegisterServiceWorkerSchemes(
const std::vector<std::string>& schemes) {
atom::AtomBrowserClient::SetCustomServiceWorkerSchemes(schemes);
@ -174,7 +192,13 @@ void Protocol::BuildPrototype(
namespace {
void RegisterStandardSchemes(
const std::vector<std::string>& schemes) {
const std::vector<std::string>& schemes, mate::Arguments* args) {
if (atom::Browser::Get()->is_ready()) {
args->ThrowError("protocol.registerStandardSchemes should be called before "
"app is ready");
return;
}
auto policy = content::ChildProcessSecurityPolicy::GetInstance();
for (const auto& scheme : schemes) {
url::AddStandardScheme(scheme.c_str(), url::SCHEME_WITHOUT_PORT);

View file

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

View file

@ -12,7 +12,9 @@
#include "base/bind.h"
#include "native_mate/dictionary.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"
@ -34,20 +36,20 @@ typename T::iterator FindById(T* container, int id) {
// Convert the changed_metrics bitmask to string array.
std::vector<std::string> MetricsToArray(uint32_t metrics) {
std::vector<std::string> array;
if (metrics & gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS)
if (metrics & display::DisplayObserver::DISPLAY_METRIC_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");
if (metrics & gfx::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR)
if (metrics & display::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR)
array.push_back("scaleFactor");
if (metrics & gfx::DisplayObserver::DISPLAY_METRIC_ROTATION)
if (metrics & display::DisplayObserver::DISPLAY_METRIC_ROTATION)
array.push_back("rotation");
return array;
}
} // namespace
Screen::Screen(v8::Isolate* isolate, gfx::Screen* screen)
Screen::Screen(v8::Isolate* isolate, display::Screen* screen)
: screen_(screen) {
screen_->AddObserver(this);
Init(isolate);
@ -61,31 +63,31 @@ gfx::Point Screen::GetCursorScreenPoint() {
return screen_->GetCursorScreenPoint();
}
gfx::Display Screen::GetPrimaryDisplay() {
display::Display Screen::GetPrimaryDisplay() {
return screen_->GetPrimaryDisplay();
}
std::vector<gfx::Display> Screen::GetAllDisplays() {
std::vector<display::Display> 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);
}
gfx::Display Screen::GetDisplayMatching(const gfx::Rect& match_rect) {
display::Display Screen::GetDisplayMatching(const gfx::Rect& 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);
}
void Screen::OnDisplayRemoved(const gfx::Display& old_display) {
void Screen::OnDisplayRemoved(const display::Display& 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) {
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);
}
gfx::Screen* screen = gfx::Screen::GetScreen();
display::Screen* screen = display::Screen::GetScreen();
if (!screen) {
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
isolate, "Failed to get screen information")));

View file

@ -9,7 +9,8 @@
#include "atom/browser/api/event_emitter.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 {
class Point;
@ -22,7 +23,7 @@ namespace atom {
namespace api {
class Screen : public mate::EventEmitter<Screen>,
public gfx::DisplayObserver {
public display::DisplayObserver {
public:
static v8::Local<v8::Value> Create(v8::Isolate* isolate);
@ -30,23 +31,23 @@ class Screen : public mate::EventEmitter<Screen>,
v8::Local<v8::ObjectTemplate> prototype);
protected:
Screen(v8::Isolate* isolate, gfx::Screen* screen);
Screen(v8::Isolate* isolate, display::Screen* screen);
~Screen() override;
gfx::Point GetCursorScreenPoint();
gfx::Display GetPrimaryDisplay();
std::vector<gfx::Display> GetAllDisplays();
gfx::Display GetDisplayNearestPoint(const gfx::Point& point);
gfx::Display GetDisplayMatching(const gfx::Rect& match_rect);
display::Display GetPrimaryDisplay();
std::vector<display::Display> GetAllDisplays();
display::Display GetDisplayNearestPoint(const gfx::Point& point);
display::Display GetDisplayMatching(const gfx::Rect& match_rect);
// gfx::DisplayObserver:
void OnDisplayAdded(const gfx::Display& new_display) override;
void OnDisplayRemoved(const gfx::Display& old_display) override;
void OnDisplayMetricsChanged(const gfx::Display& display,
// display::DisplayObserver:
void OnDisplayAdded(const display::Display& new_display) override;
void OnDisplayRemoved(const display::Display& old_display) override;
void OnDisplayMetricsChanged(const display::Display& display,
uint32_t changed_metrics) override;
private:
gfx::Screen* screen_;
display::Screen* 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_protocol.h"
#include "atom/browser/api/atom_api_web_request.h"
#include "atom/browser/browser.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/atom_permission_manager.h"
@ -20,13 +21,14 @@
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/net_converter.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "atom/common/node_includes.h"
#include "base/files/file_path.h"
#include "base/guid.h"
#include "components/prefs/pref_service.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/thread_task_runner_handle.h"
#include "base/threading/thread_task_runner_handle.h"
#include "brightray/browser/net/devtools_network_conditions.h"
#include "brightray/browser/net/devtools_network_controller_handle.h"
#include "chrome/common/pref_names.h"
@ -41,8 +43,10 @@
#include "net/http/http_auth_preferences.h"
#include "net/proxy/proxy_service.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_getter.h"
#include "ui/base/l10n/l10n_util.h"
using content::BrowserThread;
using content::StoragePartition;
@ -93,6 +97,15 @@ uint32_t GetQuotaMask(const std::vector<std::string>& quota_types) {
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 mate {
@ -120,7 +133,7 @@ struct Converter<net::ProxyConfig> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
net::ProxyConfig* out) {
std::string proxy_rules;
std::string proxy_rules, proxy_bypass_rules;
GURL pac_url;
mate::Dictionary options;
// Fallback to previous API when passed String.
@ -130,6 +143,7 @@ struct Converter<net::ProxyConfig> {
} else if (ConvertFromV8(isolate, val, &options)) {
options.Get("pacScript", &pac_url);
options.Get("proxyRules", &proxy_rules);
options.Get("proxyBypassRules", &proxy_bypass_rules);
} else {
return false;
}
@ -139,6 +153,7 @@ struct Converter<net::ProxyConfig> {
out->set_pac_url(pac_url);
} else {
out->proxy_rules().ParseFromString(proxy_rules);
out->proxy_rules().bypass_rules.ParseFromString(proxy_bypass_rules);
}
return true;
}
@ -152,6 +167,8 @@ namespace api {
namespace {
const char kPersistPrefix[] = "persist:";
// The wrapSession funtion which is implemented in JavaScript
using WrapSessionCallback = base::Callback<void(v8::Local<v8::Value>)>;
WrapSessionCallback g_wrap_session;
@ -164,7 +181,7 @@ class ResolveProxyHelper {
: callback_(callback),
original_thread_(base::ThreadTaskRunnerHandle::Get()) {
scoped_refptr<net::URLRequestContextGetter> context_getter =
browser_context->GetRequestContext();
browser_context->url_request_context_getter();
context_getter->GetNetworkTaskRunner()->PostTask(
FROM_HERE,
base::Bind(&ResolveProxyHelper::ResolveProxy,
@ -230,10 +247,10 @@ void OnGetBackend(disk_cache::Backend** backend_ptr,
} else if (action == Session::CacheAction::STATS) {
base::StringPairs stats;
(*backend_ptr)->GetStats(&stats);
for (size_t i = 0; i < stats.size(); ++i) {
if (stats[i].first == "Current size") {
for (const auto& stat : stats) {
if (stat.first == "Current size") {
int current_size;
base::StringToInt(stats[i].second, &current_size);
base::StringToInt(stat.second, &current_size);
RunCallbackInUI(callback, current_size);
break;
}
@ -255,7 +272,7 @@ void DoCacheActionInIO(
// Call GetBackend and make the backend's ptr accessable in OnGetBackend.
using BackendPtr = disk_cache::Backend*;
BackendPtr* backend_ptr = new BackendPtr(nullptr);
auto* backend_ptr = new BackendPtr(nullptr);
net::CompletionCallback on_get_backend =
base::Bind(&OnGetBackend, base::Owned(backend_ptr), action, callback);
int rv = http_cache->GetBackend(backend_ptr, on_get_backend);
@ -267,13 +284,21 @@ void SetProxyInIO(net::URLRequestContextGetter* getter,
const net::ProxyConfig& config,
const base::Closure& callback) {
auto proxy_service = getter->GetURLRequestContext()->proxy_service();
proxy_service->ResetConfigService(make_scoped_ptr(
proxy_service->ResetConfigService(base::WrapUnique(
new net::ProxyConfigServiceFixed(config)));
// Refetches and applies the new pac script if provided.
proxy_service->ForceReloadProxyConfig();
RunCallbackInUI(callback);
}
void SetCertVerifyProcInIO(
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
const AtomCertVerifier::VerifyProc& proc) {
auto request_context = context_getter->GetURLRequestContext();
static_cast<AtomCertVerifier*>(request_context->cert_verifier())->
SetVerifyProc(proc);
}
void ClearHostResolverCacheInIO(
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
const base::Closure& callback) {
@ -300,6 +325,11 @@ void AllowNTLMCredentialsForDomainsInIO(
}
}
void OnClearStorageDataDone(const base::Closure& callback) {
if (!callback.is_null())
callback.Run();
}
} // namespace
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) {
// clearStorageData([options, ]callback)
// clearStorageData([options, callback])
ClearStorageDataOptions options;
args->GetNext(&options);
base::Closure callback;
if (!args->GetNext(&callback)) {
args->ThrowError();
return;
}
args->GetNext(&options);
args->GetNext(&callback);
auto storage_partition =
content::BrowserContext::GetStoragePartition(browser_context(), nullptr);
storage_partition->ClearData(
options.storage_types, options.quota_types, options.origin,
content::StoragePartition::OriginMatcherFunction(),
base::Time(), base::Time::Max(), callback);
base::Time(), base::Time::Max(),
base::Bind(&OnClearStorageDataDone, callback));
}
void Session::FlushStorageData() {
@ -423,7 +451,10 @@ void Session::SetCertVerifyProc(v8::Local<v8::Value> val,
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,
@ -455,6 +486,23 @@ void Session::AllowNTLMCredentialsForDomains(const std::string& 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) {
if (cookies_.IsEmpty()) {
auto handle = atom::api::Cookies::Create(isolate, browser_context());
@ -494,10 +542,19 @@ mate::Handle<Session> Session::CreateFrom(
// static
mate::Handle<Session> Session::FromPartition(
v8::Isolate* isolate, const std::string& partition, bool in_memory) {
auto browser_context = brightray::BrowserContext::From(partition, in_memory);
return CreateFrom(isolate,
static_cast<AtomBrowserContext*>(browser_context.get()));
v8::Isolate* isolate, const std::string& partition,
const base::DictionaryValue& options) {
scoped_refptr<AtomBrowserContext> browser_context;
if (partition.empty()) {
browser_context = AtomBrowserContext::From("", false, options);
} else if (base::StartsWith(partition, kPersistPrefix,
base::CompareCase::SENSITIVE)) {
std::string name = partition.substr(8);
browser_context = AtomBrowserContext::From(name, false, options);
} else {
browser_context = AtomBrowserContext::From(partition, true, options);
}
return CreateFrom(isolate, browser_context.get());
}
// static
@ -520,6 +577,8 @@ void Session::BuildPrototype(v8::Isolate* isolate,
.SetMethod("clearHostResolverCache", &Session::ClearHostResolverCache)
.SetMethod("allowNTLMCredentialsForDomains",
&Session::AllowNTLMCredentialsForDomains)
.SetMethod("setUserAgent", &Session::SetUserAgent)
.SetMethod("getUserAgent", &Session::GetUserAgent)
.SetProperty("cookies", &Session::Cookies)
.SetProperty("protocol", &Session::Protocol)
.SetProperty("webRequest", &Session::WebRequest);
@ -535,11 +594,23 @@ void SetWrapSession(const WrapSessionCallback& callback) {
namespace {
v8::Local<v8::Value> FromPartition(
const std::string& partition, mate::Arguments* args) {
if (!atom::Browser::Get()->is_ready()) {
args->ThrowError("Session can only be received when app is ready");
return v8::Null(args->isolate());
}
base::DictionaryValue options;
args->GetNext(&options);
return atom::api::Session::FromPartition(
args->isolate(), partition, options).ToV8();
}
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.SetMethod("fromPartition", &atom::api::Session::FromPartition);
dict.SetMethod("fromPartition", &FromPartition);
dict.SetMethod("_setWrapSession", &atom::api::SetWrapSession);
}

View file

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

View file

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

View file

@ -26,17 +26,18 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences> {
static void BuildPrototype(v8::Isolate* isolate,
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)
bool IsAeroGlassEnabled();
#elif defined(OS_MACOSX)
using NotificationCallback = base::Callback<
void(const std::string&, const base::DictionaryValue&)>;
int SubscribeNotification(const std::string& name,
const NotificationCallback& callback);
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,
const std::string& type);
#endif
@ -46,6 +47,13 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences> {
explicit SystemPreferences(v8::Isolate* isolate);
~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:
DISALLOW_COPY_AND_ASSIGN(SystemPreferences);
};

View file

@ -30,34 +30,59 @@ std::map<int, id> g_id_map;
int SystemPreferences::SubscribeNotification(
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++;
__block NotificationCallback copied_callback = callback;
g_id_map[request_id] = [[NSDistributedNotificationCenter defaultCenter]
addObserverForName:base::SysUTF8ToNSString(name)
object:nil
queue:nil
usingBlock:^(NSNotification* notification) {
std::unique_ptr<base::DictionaryValue> user_info =
NSDictionaryToDictionaryValue(notification.userInfo);
if (user_info) {
copied_callback.Run(
base::SysNSStringToUTF8(notification.name),
*user_info);
} else {
copied_callback.Run(
base::SysNSStringToUTF8(notification.name),
base::DictionaryValue());
}
NSNotificationCenter* center = is_local ?
[NSNotificationCenter defaultCenter] :
[NSDistributedNotificationCenter defaultCenter];
g_id_map[request_id] = [center
addObserverForName:base::SysUTF8ToNSString(name)
object:nil
queue:nil
usingBlock:^(NSNotification* notification) {
std::unique_ptr<base::DictionaryValue> user_info =
NSDictionaryToDictionaryValue(notification.userInfo);
if (user_info) {
copied_callback.Run(
base::SysNSStringToUTF8(notification.name),
*user_info);
} else {
copied_callback.Run(
base::SysNSStringToUTF8(notification.name),
base::DictionaryValue());
}
}
];
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);
if (iter != g_id_map.end()) {
id observer = iter->second;
[[NSDistributedNotificationCenter defaultCenter] removeObserver:observer];
NSNotificationCenter* center = is_local ?
[NSNotificationCenter defaultCenter] :
[NSDistributedNotificationCenter defaultCenter];
[center removeObserver:observer];
g_id_map.erase(iter);
}
}

View file

@ -8,7 +8,6 @@
#include "atom/browser/api/atom_api_menu.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/native_mate_converters/gfx_converter.h"
#include "atom/common/native_mate_converters/image_converter.h"
@ -16,9 +15,47 @@
#include "atom/common/node_includes.h"
#include "native_mate/constructor.h"
#include "native_mate/dictionary.h"
#include "ui/events/event_constants.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 api {
@ -30,6 +67,8 @@ Tray::Tray(v8::Isolate* isolate, mate::Handle<NativeImage> image)
}
Tray::~Tray() {
// Destroy the native tray in next tick.
base::MessageLoop::current()->DeleteSoon(FROM_HERE, tray_icon_.release());
}
// static
@ -44,24 +83,15 @@ mate::WrappableBase* Tray::New(v8::Isolate* isolate,
}
void Tray::OnClicked(const gfx::Rect& bounds, int modifiers) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
EmitCustomEvent("click",
ModifiersToObject(isolate(), modifiers), bounds);
EmitWithFlags("click", modifiers, bounds);
}
void Tray::OnDoubleClicked(const gfx::Rect& bounds, int modifiers) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
EmitCustomEvent("double-click",
ModifiersToObject(isolate(), modifiers), bounds);
EmitWithFlags("double-click", modifiers, bounds);
}
void Tray::OnRightClicked(const gfx::Rect& bounds, int modifiers) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
EmitCustomEvent("right-click",
ModifiersToObject(isolate(), modifiers), bounds);
EmitWithFlags("right-click", modifiers, bounds);
}
void Tray::OnBalloonShow() {
@ -84,6 +114,10 @@ void Tray::OnDropFiles(const std::vector<std::string>& files) {
Emit("drop-files", files);
}
void Tray::OnDropText(const std::string& text) {
Emit("drop-text", text);
}
void Tray::OnDragEntered() {
Emit("drag-enter");
}
@ -121,8 +155,8 @@ void Tray::SetTitle(const std::string& title) {
tray_icon_->SetTitle(title);
}
void Tray::SetHighlightMode(bool highlight) {
tray_icon_->SetHighlightMode(highlight);
void Tray::SetHighlightMode(TrayIcon::HighlightMode mode) {
tray_icon_->SetHighlightMode(mode);
}
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());
}
v8::Local<v8::Object> Tray::ModifiersToObject(v8::Isolate* isolate,
int modifiers) {
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();
gfx::Rect Tray::GetBounds() {
return tray_icon_->GetBounds();
}
// static
@ -181,7 +209,8 @@ void Tray::BuildPrototype(v8::Isolate* isolate,
.SetMethod("setHighlightMode", &Tray::SetHighlightMode)
.SetMethod("displayBalloon", &Tray::DisplayBalloon)
.SetMethod("popUpContextMenu", &Tray::PopUpContextMenu)
.SetMethod("setContextMenu", &Tray::SetContextMenu);
.SetMethod("setContextMenu", &Tray::SetContextMenu)
.SetMethod("getBounds", &Tray::GetBounds);
}
} // namespace api

View file

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

View file

@ -17,6 +17,7 @@
#include "atom/browser/lib/bluetooth_chooser.h"
#include "atom/browser/native_window.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_preferences.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/navigation_details.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/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
@ -61,11 +63,10 @@
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.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 "third_party/WebKit/public/web/WebInputEvent.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"
@ -76,15 +77,6 @@ struct PrintSettings {
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 mate {
@ -248,6 +240,13 @@ content::ServiceWorkerContext* 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
WebContents::WebContents(v8::Isolate* isolate,
@ -287,16 +286,11 @@ WebContents::WebContents(v8::Isolate* isolate,
std::string partition;
mate::Handle<api::Session> session;
if (options.Get("session", &session)) {
} else if (options.Get("partition", &partition) && !partition.empty()) {
bool in_memory = true;
if (base::StartsWith(partition, "persist:", base::CompareCase::SENSITIVE)) {
in_memory = false;
partition = partition.substr(8);
}
session = Session::FromPartition(isolate, partition, in_memory);
} else if (options.Get("partition", &partition)) {
session = Session::FromPartition(isolate, partition);
} else {
// Use the default session if not specified.
session = Session::FromPartition(isolate, "", false);
session = Session::FromPartition(isolate, "");
}
session_.Reset(isolate, session.ToV8());
@ -610,17 +604,6 @@ void WebContents::DidFinishLoad(content::RenderFrameHost* render_frame_host,
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,
const GURL& url,
int error_code,
@ -664,13 +647,27 @@ void WebContents::DidGetRedirectForResourceRequest(
details.headers.get());
}
void WebContents::DidNavigateMainFrame(
const content::LoadCommittedDetails& details,
const content::FrameNavigateParams& params) {
if (details.is_navigation_to_different_page())
Emit("did-navigate", params.url);
else if (details.is_in_page)
Emit("did-navigate-in-page", params.url);
void WebContents::DidFinishNavigation(
content::NavigationHandle* navigation_handle) {
bool is_main_frame = navigation_handle->IsInMainFrame();
if (navigation_handle->HasCommitted() && !navigation_handle->IsErrorPage()) {
auto url = navigation_handle->GetURL();
bool is_in_page = navigation_handle->IsSamePage();
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,
@ -684,10 +681,10 @@ void WebContents::TitleWasSet(content::NavigationEntry* entry,
void WebContents::DidUpdateFaviconURL(
const std::vector<content::FaviconURL>& urls) {
std::set<GURL> unique_urls;
for (auto iter = urls.begin(); iter != urls.end(); ++iter) {
if (iter->icon_type != content::FaviconURL::FAVICON)
for (const auto& iter : urls) {
if (iter.icon_type != content::FaviconURL::FAVICON)
continue;
const GURL& url = iter->icon_url;
const GURL& url = iter.icon_url;
if (url.is_valid())
unique_urls.insert(url);
}
@ -736,6 +733,7 @@ bool WebContents::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(AtomViewHostMsg_Message, OnRendererMessage)
IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_Message_Sync,
OnRendererMessageSync)
IPC_MESSAGE_HANDLER(AtomViewHostMsg_DidCommitCompositorFrame, OnViewPainted)
IPC_MESSAGE_HANDLER_CODE(ViewHostMsg_SetCursor, OnCursorChange,
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:
// 1. call webContents.destory();
// 1. call webContents.destroy();
// 2. garbage collection;
// 3. user closes the window of webContents;
// For webview only #1 will happen, for BrowserWindow both #1 and #3 may
@ -788,6 +786,13 @@ WebContents::Type WebContents::GetType() const {
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 {
return GetID() == web_contents->GetID();
}
@ -811,7 +816,7 @@ void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) {
std::string user_agent;
if (options.Get("userAgent", &user_agent))
SetUserAgent(user_agent);
web_contents()->SetUserAgentOverride(user_agent);
std::string extra_headers;
if (options.Get("extraHeaders", &extra_headers))
@ -898,14 +903,9 @@ bool WebContents::IsCrashed() const {
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);
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() {
@ -1146,6 +1146,12 @@ void WebContents::ShowDefinitionForSelection() {
#endif
}
void WebContents::CopyImageAt(int x, int y) {
const auto host = web_contents()->GetRenderViewHost();
if (host)
host->CopyImageAt(x, y);
}
void WebContents::Focus() {
web_contents()->Focus();
}
@ -1194,15 +1200,14 @@ void WebContents::SendInputEvent(v8::Isolate* isolate,
isolate, "Invalid event object")));
}
void WebContents::BeginFrameSubscription(
mate::Arguments* args) {
FrameSubscriber::FrameCaptureCallback callback;
void WebContents::BeginFrameSubscription(mate::Arguments* args) {
bool only_dirty = false;
FrameSubscriber::FrameCaptureCallback callback;
args->GetNext(&only_dirty);
if (!args->GetNext(&callback)) {
args->GetNext(&only_dirty);
if (!args->GetNext(&callback))
args->ThrowTypeError("'callback' must be defined");
args->ThrowError();
return;
}
const auto view = web_contents()->GetRenderWidgetHostView();
@ -1219,6 +1224,74 @@ void WebContents::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) {
content::WebCursor::CursorInfo 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) {
if (guest_delegate_)
guest_delegate_->SetSize(params);
@ -1338,6 +1415,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
.SetMethod("beginFrameSubscription",
&WebContents::BeginFrameSubscription)
.SetMethod("endFrameSubscription", &WebContents::EndFrameSubscription)
.SetMethod("startDrag", &WebContents::StartDrag)
.SetMethod("setSize", &WebContents::SetSize)
.SetMethod("isGuest", &WebContents::IsGuest)
.SetMethod("getType", &WebContents::GetType)
@ -1353,6 +1431,9 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
.SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace)
.SetMethod("showDefinitionForSelection",
&WebContents::ShowDefinitionForSelection)
.SetMethod("copyImageAt", &WebContents::CopyImageAt)
.SetMethod("capturePage", &WebContents::CapturePage)
.SetMethod("isFocused", &WebContents::IsFocused)
.SetProperty("id", &WebContents::ID)
.SetProperty("session", &WebContents::Session)
.SetProperty("hostWebContents", &WebContents::HostWebContents)

View file

@ -67,6 +67,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
int GetID() const;
Type GetType() const;
bool IsFocused() const;
bool Equal(const WebContents* web_contents) const;
void LoadURL(const GURL& url, const mate::Dictionary& options);
void DownloadURL(const GURL& url);
@ -81,7 +82,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
void GoForward();
void GoToOffset(int offset);
bool IsCrashed() const;
void SetUserAgent(const std::string& user_agent);
void SetUserAgent(const std::string& user_agent, mate::Arguments* args);
std::string GetUserAgent();
void InsertCSS(const std::string& css);
bool SavePage(const base::FilePath& full_file_path,
@ -125,6 +126,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
uint32_t FindInPage(mate::Arguments* args);
void StopFindInPage(content::StopFindAction action);
void ShowDefinitionForSelection();
void CopyImageAt(int x, int y);
// Focus.
void Focus();
@ -142,6 +144,13 @@ class WebContents : public mate::TrackableObject<WebContents>,
void BeginFrameSubscription(mate::Arguments* args);
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>.
void SetSize(const SetSizeParams& params);
bool IsGuest() const;
@ -237,11 +246,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
int error_code,
const base::string16& error_description,
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 DidStopLoading() override;
void DidGetResourceResponseStart(
@ -249,9 +253,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
void DidGetRedirectForResourceRequest(
content::RenderFrameHost* render_frame_host,
const content::ResourceRedirectDetails& details) override;
void DidNavigateMainFrame(
const content::LoadCommittedDetails& details,
const content::FrameNavigateParams& params) override;
void DidFinishNavigation(
content::NavigationHandle* navigation_handle) override;
bool OnMessageReceived(const IPC::Message& message) override;
void WebContentsDestroyed() override;
void NavigationEntryCommitted(
@ -292,6 +295,9 @@ class WebContents : public mate::TrackableObject<WebContents>,
const base::ListValue& args,
IPC::Message* message);
// Called when the hosted view gets graphical updates.
void OnViewPainted();
v8::Global<v8::Value> session_;
v8::Global<v8::Value> devtools_web_contents_;
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 {
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.
v8::Local<v8::Value> ToBuffer(v8::Isolate* isolate, void* val, int 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,
parent.IsEmpty() ? nullptr : parent->window_.get()));
web_contents->SetOwnerWindow(window_.get());
window_->InitFromOptions(options);
window_->AddObserver(this);
AttachAsUserData(window_.get());
#if defined(TOOLKIT_VIEWS)
// Sets the window icon.
@ -116,6 +104,10 @@ Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) {
if (options.Get(options::kIcon, &icon))
SetIcon(icon);
#endif
window_->InitFromOptions(options);
window_->AddObserver(this);
AttachAsUserData(window_.get());
}
Window::~Window() {
@ -572,23 +564,12 @@ void Window::SetIgnoreMouseEvents(bool ignore) {
return window_->SetIgnoreMouseEvents(ignore);
}
void Window::SetFocusable(bool focusable) {
return window_->SetFocusable(focusable);
void Window::SetContentProtection(bool enable) {
return window_->SetContentProtection(enable);
}
void Window::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;
}
window_->CapturePage(
rect, base::Bind(&OnCapturePageDone, args->isolate(), callback));
void Window::SetFocusable(bool focusable) {
return window_->SetFocusable(focusable);
}
void Window::SetProgressBar(double progress) {
@ -668,6 +649,12 @@ bool Window::IsWindowMessageHooked(UINT message) {
void Window::UnhookAllWindowMessages() {
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
#if defined(TOOLKIT_VIEWS)
@ -833,11 +820,11 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("setDocumentEdited", &Window::SetDocumentEdited)
.SetMethod("isDocumentEdited", &Window::IsDocumentEdited)
.SetMethod("setIgnoreMouseEvents", &Window::SetIgnoreMouseEvents)
.SetMethod("setContentProtection", &Window::SetContentProtection)
.SetMethod("setFocusable", &Window::SetFocusable)
.SetMethod("focusOnWebView", &Window::FocusOnWebView)
.SetMethod("blurWebView", &Window::BlurWebView)
.SetMethod("isWebViewFocused", &Window::IsWebViewFocused)
.SetMethod("capturePage", &Window::CapturePage)
.SetMethod("setProgressBar", &Window::SetProgressBar)
.SetMethod("setOverlayIcon", &Window::SetOverlayIcon)
.SetMethod("setThumbarButtons", &Window::SetThumbarButtons)
@ -855,6 +842,7 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("isWindowMessageHooked", &Window::IsWindowMessageHooked)
.SetMethod("unhookWindowMessage", &Window::UnhookWindowMessage)
.SetMethod("unhookAllWindowMessages", &Window::UnhookAllWindowMessages)
.SetMethod("setThumbnailClip", &Window::SetThumbnailClip)
#endif
#if defined(TOOLKIT_VIEWS)
.SetMethod("setIcon", &Window::SetIcon)

View file

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

View file

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

View file

@ -8,6 +8,7 @@
#include "native_mate/arguments.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "ui/events/event_constants.h"
namespace mate {
@ -65,6 +66,15 @@ v8::Local<v8::Object> CreateCustomEvent(
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 mate

View file

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

View file

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

View file

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

View file

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

View file

@ -7,8 +7,8 @@
#include <utility>
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/common/google_api_key.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/geolocation_provider.h"
namespace atom {
@ -33,21 +33,35 @@ AtomAccessTokenStore::~AtomAccessTokenStore() {
void AtomAccessTokenStore::LoadAccessTokens(
const LoadAccessTokensCallback& callback) {
AccessTokenMap access_token_map;
// 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.
std::pair<GURL, base::string16> token_pair;
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());
content::BrowserThread::PostTaskAndReply(
content::BrowserThread::UI,
FROM_HERE,
base::Bind(&AtomAccessTokenStore::GetRequestContextOnUIThread, this),
base::Bind(&AtomAccessTokenStore::RespondOnOriginatingThread,
this, callback));
}
void AtomAccessTokenStore::SaveAccessToken(const GURL& server_url,
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

View file

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

View file

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

View file

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

View file

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

View file

@ -12,15 +12,20 @@
namespace atom {
class AtomDownloadManagerDelegate;
class AtomCertVerifier;
class AtomNetworkDelegate;
class AtomPermissionManager;
class WebViewManager;
class AtomBrowserContext : public brightray::BrowserContext {
public:
AtomBrowserContext(const std::string& partition, bool in_memory);
~AtomBrowserContext() override;
// Get or create the BrowserContext according to its |partition| and
// |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:
net::NetworkDelegate* CreateNetworkDelegate() override;
@ -40,16 +45,21 @@ class AtomBrowserContext : public brightray::BrowserContext {
// brightray::BrowserContext:
void RegisterPrefs(PrefRegistrySimple* pref_registry) override;
AtomCertVerifier* cert_verifier() const { return cert_verifier_; }
AtomNetworkDelegate* network_delegate() const { return network_delegate_; }
protected:
AtomBrowserContext(const std::string& partition, bool in_memory,
const base::DictionaryValue& options);
~AtomBrowserContext() override;
private:
std::unique_ptr<AtomDownloadManagerDelegate> download_manager_delegate_;
std::unique_ptr<WebViewManager> guest_manager_;
std::unique_ptr<AtomPermissionManager> permission_manager_;
std::string user_agent_;
bool use_cache_;
// Managed by brightray::BrowserContext.
AtomCertVerifier* cert_verifier_;
AtomNetworkDelegate* network_delegate_;
DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext);

View file

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

View file

@ -43,7 +43,7 @@ void GracefulShutdownHandler(int signal) {
struct sigaction action;
memset(&action, 0, sizeof(action));
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_shutdown_pipe_write_fd != -1);
@ -171,7 +171,7 @@ void AtomBrowserMainParts::HandleSIGCHLD() {
struct sigaction action;
memset(&action, 0, sizeof(action));
action.sa_handler = SIGCHLDHandler;
CHECK_EQ(sigaction(SIGCHLD, &action, NULL), 0);
CHECK_EQ(sigaction(SIGCHLD, &action, nullptr), 0);
}
void AtomBrowserMainParts::HandleShutdownSignals() {
@ -211,15 +211,15 @@ void AtomBrowserMainParts::HandleShutdownSignals() {
struct sigaction action;
memset(&action, 0, sizeof(action));
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
// the browser process is being debugged, GDB will catch the SIGINT first.
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
// distros send SIGHUP, SIGTERM, and then SIGKILL.
action.sa_handler = SIGHUPHandler;
CHECK_EQ(sigaction(SIGHUP, &action, NULL), 0);
CHECK_EQ(sigaction(SIGHUP, &action, nullptr), 0);
}
} // namespace atom

View file

@ -85,6 +85,14 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
download_manager_->GetBrowserContext());
browser_context->prefs()->SetFilePath(prefs::kDownloadDefaultDirectory,
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

View file

@ -7,6 +7,7 @@
#include "atom/browser/login_handler.h"
#include "atom/browser/web_contents_permission_helper.h"
#include "atom/common/platform_util.h"
#include "base/strings/utf_string_conversions.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/escape.h"
#include "url/gurl.h"
@ -20,7 +21,13 @@ namespace {
void OnOpenExternal(const GURL& escaped_url,
bool 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(

View file

@ -91,8 +91,14 @@ void AtomSecurityStateModelClient::GetVisibleSecurityState(
state->connection_status = ssl.connection_status;
state->security_bits = ssl.security_bits;
state->sct_verify_statuses.clear();
for (const auto& sct : ssl.signed_certificate_timestamp_ids)
state->sct_verify_statuses.push_back(sct.status);
state->sct_verify_statuses.insert(state->sct_verify_statuses.end(),
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 =
(ssl.content_status & content::SSLStatus::DISPLAYED_INSECURE_CONTENT)
? true

View file

@ -50,11 +50,6 @@ void AtomSpeechRecognitionManagerDelegate::OnAudioLevelsChange(
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(
int session_id,
base::Callback<void(bool ask_user, bool is_allowed)> callback) {

View file

@ -36,8 +36,6 @@ class AtomSpeechRecognitionManagerDelegate
float noise_volume) override;
// content::SpeechRecognitionManagerDelegate:
void GetDiagnosticInformation(bool* can_report_metrics,
std::string* hardware_info) override;
void CheckRecognitionIsAllowed(
int session_id,
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)
std::string AutoUpdater::GetFeedURL() {
return "";
}
void AutoUpdater::SetFeedURL(const std::string& url,
const HeaderMap& requestHeaders) {
}

View file

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

View file

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

View file

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

View file

@ -25,16 +25,13 @@ class DictionaryValue;
class FilePath;
}
namespace ui {
class MenuModel;
}
namespace gfx {
class Image;
}
namespace atom {
class AtomMenuModel;
class LoginHandler;
// 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.
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)
// Hide the application.
void Hide();
@ -126,7 +138,7 @@ class Browser : public WindowListObserver {
void DockShow();
// Set docks' menu.
void DockSetMenu(ui::MenuModel* model);
void DockSetMenu(AtomMenuModel* model);
// Set docks' icon.
void DockSetIcon(const gfx::Image& image);
@ -149,7 +161,12 @@ class Browser : public WindowListObserver {
// one from app's name.
// The returned string managed by Browser, and should not be modified.
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.
bool OpenFile(const std::string& file_path);
@ -165,6 +182,8 @@ class Browser : public WindowListObserver {
void WillFinishLaunching();
void DidFinishLaunching();
void OnAccessibilitySupportChanged();
// Request basic auth login.
void RequestLogin(LoginHandler* login_handler,
std::unique_ptr<base::DictionaryValue> request_details);
@ -216,6 +235,8 @@ class Browser : public WindowListObserver {
std::string version_override_;
std::string name_override_;
int badge_count_ = 0;
#if defined(OS_WIN)
base::string16 app_user_model_id_;
#endif

View file

@ -10,6 +10,7 @@
#include "atom/browser/window_list.h"
#include "atom/common/atom_version.h"
#include "brightray/common/application_info.h"
#include "chrome/browser/ui/libgtk2ui/unity_service.h"
namespace atom {
@ -46,6 +47,23 @@ bool Browser::IsDefaultProtocolClient(const std::string& protocol) {
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 {
return brightray::GetApplicationVersion();
}
@ -54,4 +72,8 @@ std::string Browser::GetExecutableFileProductName() const {
return brightray::GetApplicationName();
}
bool Browser::IsUnityRunning() {
return unity::IsRunning();
}
} // namespace atom

View file

@ -11,6 +11,8 @@
#include "atom/browser/window_list.h"
#include "base/mac/bundle_locations.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 "brightray/common/application_info.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) {
}
bool Browser::SetBadgeCount(int count) {
DockSetBadgeText(count != 0 ? base::IntToString(count) : "");
badge_count_ = count;
return true;
}
void Browser::SetUserActivity(const std::string& type,
const base::DictionaryValue& user_info,
mate::Arguments* args) {
@ -141,6 +149,23 @@ bool Browser::ContinueUserActivity(const std::string& type,
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 {
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];
[delegate setApplicationDockMenu:model];
}

View file

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

View file

@ -13,7 +13,6 @@
#include "base/base_paths.h"
#include "base/file_version_info.h"
#include "base/files/file_path.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
@ -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() {
if (app_user_model_id_.empty()) {
SetAppUserModelID(base::ReplaceStringPlaceholders(

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -5,9 +5,9 @@
#ifndef 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 {
class ListValue;

View file

@ -11,6 +11,7 @@
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/browser.h"
#include "atom/browser/unresponsive_suppressor.h"
#include "atom/browser/window_list.h"
#include "atom/common/api/api_messages.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
@ -37,9 +38,13 @@
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/screen.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);
namespace atom {
@ -53,7 +58,6 @@ NativeWindow::NativeWindow(
transparent_(false),
enable_larger_than_screen_(false),
is_closed_(false),
has_dialog_attached_(false),
sheet_offset_x_(0.0),
sheet_offset_y_(0.0),
aspect_ratio_(0.0),
@ -68,6 +72,20 @@ NativeWindow::NativeWindow(
if (parent)
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
// mode.
ui::GpuSwitchingManager::SetTransparent(transparent_);
@ -210,7 +228,7 @@ gfx::Size NativeWindow::GetContentSize() {
void NativeWindow::SetSizeConstraints(
const extensions::SizeConstraints& window_constraints) {
extensions::SizeConstraints content_constraints;
extensions::SizeConstraints content_constraints(GetContentSizeConstraints());
if (window_constraints.HasMaximumSize())
content_constraints.set_maximum_size(
WindowSizeToContentSize(window_constraints.GetMaximumSize()));
@ -291,11 +309,7 @@ bool NativeWindow::IsDocumentEdited() {
void NativeWindow::SetFocusable(bool focusable) {
}
void NativeWindow::SetMenu(ui::MenuModel* menu) {
}
bool NativeWindow::HasModalDialog() {
return has_dialog_attached_;
void NativeWindow::SetMenu(AtomMenuModel* menu) {
}
void NativeWindow::SetParentWindow(NativeWindow* parent) {
@ -315,39 +329,6 @@ bool NativeWindow::IsWebViewFocused() {
return host_view && host_view->HasFocus();
}
void NativeWindow::CapturePage(const gfx::Rect& rect,
const CapturePageCallback& callback) {
const auto view = web_contents()->GetRenderWidgetHostView();
const auto host = view ? view->GetRenderWidgetHost() : nullptr;
if (!view || !host) {
callback.Run(SkBitmap());
return;
}
// Capture full page if user doesn't specify a |rect|.
const gfx::Size view_size = rect.IsEmpty() ? view->GetViewBounds().size() :
rect.size();
// By default, the requested bitmap size is the view size in screen
// coordinates. However, if there's more pixel detail available on the
// current system, increase the requested bitmap size to capture it all.
gfx::Size bitmap_size = view_size;
const gfx::NativeView native_view = view->GetNativeView();
const float scale =
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) {
}
@ -394,7 +375,7 @@ void NativeWindow::RequestToClosePage() {
ScheduleUnresponsiveEvent(5000);
if (web_contents()->NeedToFireBeforeUnload())
web_contents()->DispatchBeforeUnload(false);
web_contents()->DispatchBeforeUnload();
else
web_contents()->Close();
}
@ -624,7 +605,7 @@ void NativeWindow::ScheduleUnresponsiveEvent(int ms) {
void NativeWindow::NotifyWindowUnresponsive() {
window_unresposive_closure_.Cancel();
if (!is_closed_ && !HasModalDialog() && IsEnabled())
if (!is_closed_ && !IsUnresponsiveEventSuppressed() && IsEnabled())
FOR_EACH_OBSERVER(NativeWindowObserver,
observers_,
OnRendererUnresponsive());
@ -634,10 +615,4 @@ void NativeWindow::NotifyReadyToShow() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnReadyToShow());
}
void NativeWindow::OnCapturePageDone(const CapturePageCallback& callback,
const SkBitmap& bitmap,
content::ReadbackResponse response) {
callback.Run(bitmap);
}
} // namespace atom

View file

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

View file

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

View file

@ -70,6 +70,7 @@ bool ScopedDisableResize::disable_resize_ = false;
@interface AtomNSWindowDelegate : NSObject<NSWindowDelegate> {
@private
atom::NativeWindowMac* shell_;
bool is_zooming_;
}
- (id)initWithShell:(atom::NativeWindowMac*)shell;
@end
@ -79,6 +80,7 @@ bool ScopedDisableResize::disable_resize_ = false;
- (id)initWithShell:(atom::NativeWindowMac*)shell {
if ((self = [super init])) {
shell_ = shell;
is_zooming_ = false;
}
return self;
}
@ -172,16 +174,20 @@ bool ScopedDisableResize::disable_resize_ = false;
}
- (BOOL)windowShouldZoom:(NSWindow*)window toFrame:(NSRect)newFrame {
// Cocoa doen't have concept of maximize/unmaximize, so wee need to emulate
// 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();
is_zooming_ = true;
return YES;
}
- (void)windowDidEndLiveResize:(NSNotification*)notification {
if (is_zooming_) {
if (shell_->IsMaximized())
shell_->NotifyWindowMaximize();
else
shell_->NotifyWindowUnmaximize();
is_zooming_ = false;
}
}
- (void)windowWillEnterFullScreen:(NSNotification*)notification {
// Hide the native toolbar before entering fullscreen, so there is no visual
// artifacts.
@ -199,6 +205,7 @@ bool ScopedDisableResize::disable_resize_ = false;
// have to set one, because title bar is visible here.
NSWindow* window = shell_->GetNativeWindow();
if ((shell_->transparent() || !shell_->has_frame()) &&
base::mac::IsOSYosemiteOrLater() &&
// FIXME(zcbenz): Showing titlebar for hiddenInset window is weird under
// fullscreen mode.
shell_->title_bar_style() != atom::NativeWindowMac::HIDDEN_INSET) {
@ -223,6 +230,7 @@ bool ScopedDisableResize::disable_resize_ = false;
// Restore the titlebar visibility.
NSWindow* window = shell_->GetNativeWindow();
if ((shell_->transparent() || !shell_->has_frame()) &&
base::mac::IsOSYosemiteOrLater() &&
shell_->title_bar_style() != atom::NativeWindowMac::HIDDEN_INSET) {
[window setTitleVisibility:NSWindowTitleHidden];
}
@ -233,13 +241,6 @@ bool ScopedDisableResize::disable_resize_ = false;
}
- (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();
}
@ -526,8 +527,10 @@ NativeWindowMac::NativeWindowMac(
[window_ setDisableKeyOrMainWindow:YES];
if (transparent() || !has_frame()) {
// Don't show title bar.
[window_ setTitleVisibility:NSWindowTitleHidden];
if (base::mac::IsOSYosemiteOrLater()) {
// Don't show title bar.
[window_ setTitleVisibility:NSWindowTitleHidden];
}
// Remove non-transparent corners, see http://git.io/vfonD.
[window_ setOpaque:NO];
}
@ -714,11 +717,6 @@ void NativeWindowMac::SetFullScreen(bool fullscreen) {
if (fullscreen == IsFullscreen())
return;
if (!base::mac::IsOSLionOrLater()) {
LOG(ERROR) << "Fullscreen mode is only supported above Lion";
return;
}
[window_ toggleFullScreen:nil];
}
@ -727,13 +725,22 @@ bool NativeWindowMac::IsFullscreen() const {
}
void NativeWindowMac::SetBounds(const gfx::Rect& bounds, bool animate) {
NSRect cocoa_bounds = NSMakeRect(bounds.x(), 0,
bounds.width(),
bounds.height());
// Do nothing if in fullscreen mode.
if (IsFullscreen())
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.
NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
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];
}
@ -785,13 +792,13 @@ bool NativeWindowMac::IsResizable() {
void NativeWindowMac::SetAspectRatio(double aspect_ratio,
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.
if (aspect_ratio > 0.0)
[window_ setAspectRatio:NSMakeSize(aspect_ratio, 1.0)];
else
[window_ setResizeIncrements:NSMakeSize(1.0, 1.0)];
// Reset the behaviour to default if aspect_ratio is set to 0 or less.
if (aspect_ratio > 0.0)
[window_ setAspectRatio:NSMakeSize(aspect_ratio, 1.0)];
else
[window_ setResizeIncrements:NSMakeSize(1.0, 1.0)];
}
void NativeWindowMac::SetMovable(bool movable) {
@ -852,6 +859,11 @@ void NativeWindowMac::Center() {
}
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)];
}
@ -935,8 +947,9 @@ void NativeWindowMac::SetIgnoreMouseEvents(bool ignore) {
[window_ setIgnoresMouseEvents:ignore];
}
bool NativeWindowMac::HasModalDialog() {
return [window_ attachedSheet] != nil;
void NativeWindowMac::SetContentProtection(bool enable) {
[window_ setSharingType:enable ? NSWindowSharingNone
: NSWindowSharingReadOnly];
}
void NativeWindowMac::SetParentWindow(NativeWindow* parent) {
@ -1057,7 +1070,10 @@ void NativeWindowMac::UpdateDraggableRegions(
void NativeWindowMac::InstallView() {
// 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();
if (has_frame()) {
@ -1077,6 +1093,9 @@ void NativeWindowMac::InstallView() {
[view setFrame:[content_view_ bounds]];
[content_view_ addSubview:view];
// The fullscreen button should always be hidden for frameless window.
[[window_ standardWindowButton:NSWindowFullScreenButton] setHidden:YES];
if (title_bar_style_ != NORMAL)
return;

View file

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

View file

@ -96,8 +96,9 @@ class NativeWindowViews : public NativeWindow,
void SetHasShadow(bool has_shadow) override;
bool HasShadow() override;
void SetIgnoreMouseEvents(bool ignore) override;
void SetContentProtection(bool enable) override;
void SetFocusable(bool focusable) override;
void SetMenu(ui::MenuModel* menu_model) override;
void SetMenu(AtomMenuModel* menu_model) override;
void SetParentWindow(NativeWindow* parent) override;
gfx::NativeWindow GetNativeWindow() override;
void SetOverlayIcon(const gfx::Image& overlay,
@ -175,7 +176,7 @@ class NativeWindowViews : public NativeWindow,
bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
// 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.
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
// size of the window while in the normal state (not maximized, minimized or
// fullscreen), so we restore it correctly.
gfx::Size last_normal_size_;
gfx::Rect last_normal_bounds_;
// In charge of running taskbar related APIs.
TaskbarHost taskbar_host_;
@ -219,6 +220,12 @@ class NativeWindowViews : public NativeWindow,
// If true we have enabled a11y
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.
base::win::ScopedHICON window_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
// found in the LICENSE file.
#include "atom/browser/browser.h"
#include "atom/browser/native_window_views.h"
#include "content/public/browser/browser_accessibility_state.h"
@ -98,6 +99,7 @@ bool NativeWindowViews::PreHandleMSG(
if (axState && !axState->IsAccessibleBrowser()) {
axState->OnScreenReaderDetected();
enabled_a11y_support_ = true;
Browser::Get()->OnAccessibilitySupportChanged();
}
}
@ -119,7 +121,10 @@ bool NativeWindowViews::PreHandleMSG(
::GetWindowRect(GetAcceleratedWidget(), (LPRECT)l_param);
return false;
}
case WM_MOVE: {
last_normal_bounds_ = GetBounds();
return false;
}
default:
return false;
}
@ -140,7 +145,7 @@ void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) {
case SIZE_RESTORED:
if (last_window_state_ == ui::SHOW_STATE_NORMAL) {
// Window was resized so we save it's new size.
last_normal_size_ = GetSize();
last_normal_bounds_ = GetBounds();
} else {
switch (last_window_state_) {
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
// normal size.
NativeWindow::SetSize(last_normal_size_);
SetBounds(last_normal_bounds_, false);
NotifyWindowUnmaximize();
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
// normal size.
NativeWindow::SetSize(last_normal_size_);
SetBounds(last_normal_bounds_, false);
NotifyWindowRestore();
}

View file

@ -22,7 +22,7 @@ net::URLRequestJob* AsarProtocolHandler::MaybeCreateJob(
net::NetworkDelegate* network_delegate) const {
base::FilePath 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);
return job;
}

View file

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

View file

@ -56,7 +56,7 @@ class URLRequestAsarJob : public net::URLRequestJob {
void Kill() override;
int ReadRawData(net::IOBuffer* buf, int buf_size) 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;
void SetExtraRequestHeaders(const net::HttpRequestHeaders& headers) override;
int GetResponseCode() const override;

View file

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

View file

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

View file

@ -20,14 +20,14 @@ typedef net::URLRequestJobFactory::ProtocolHandler ProtocolHandler;
AtomURLRequestJobFactory::AtomURLRequestJobFactory() {}
AtomURLRequestJobFactory::~AtomURLRequestJobFactory() {
STLDeleteValues(&protocol_handler_map_);
Clear();
}
bool AtomURLRequestJobFactory::SetProtocolHandler(
const std::string& scheme,
std::unique_ptr<ProtocolHandler> 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())
return false;
@ -66,7 +66,7 @@ ProtocolHandler* AtomURLRequestJobFactory::GetProtocolHandler(
const std::string& scheme) const {
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())
return nullptr;
return it->second;
@ -77,13 +77,17 @@ bool AtomURLRequestJobFactory::HasProtocolHandler(
return ContainsKey(protocol_handler_map_, scheme);
}
void AtomURLRequestJobFactory::Clear() {
STLDeleteValues(&protocol_handler_map_);
}
net::URLRequestJob* AtomURLRequestJobFactory::MaybeCreateJobWithProtocolHandler(
const std::string& scheme,
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const {
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())
return nullptr;
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.
bool HasProtocolHandler(const std::string& scheme) const;
// Clear all protocol handlers.
void Clear();
// URLRequestJobFactory implementation
net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
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) {
std::string status("HTTP/1.1 200 OK");
net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status);
auto* headers = new net::HttpResponseHeaders(status);
headers->AddHeader(kCORSHeader);
info->headers = headers;

View file

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

View file

@ -7,6 +7,7 @@
#include <algorithm>
#include <string>
#include "base/memory/ptr_util.h"
#include "base/strings/string_util.h"
#include "native_mate/dictionary.h"
#include "net/base/io_buffer.h"
@ -132,7 +133,7 @@ void URLRequestFetchJob::StartAsync(std::unique_ptr<base::Value> options) {
request_type = GetRequestType(method);
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.
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) {
std::string status("HTTP/1.1 200 OK");
net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status);
auto* headers = new net::HttpResponseHeaders(status);
headers->AddHeader(kCORSHeader);

View file

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

View file

@ -4,11 +4,13 @@
#include "atom/browser/relauncher.h"
#include <fcntl.h>
#include <signal.h>
#include <sys/prctl.h>
#include <sys/signalfd.h>
#include "base/files/file_util.h"
#include "base/files/scoped_file.h"
#include "base/logging.h"
#include "base/posix/eintr_wrapper.h"
#include "base/process/launch.h"
@ -55,9 +57,17 @@ void RelauncherSynchronizeWithParent() {
int LaunchProgram(const StringVector& relauncher_args,
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;
options.allow_new_privs = true;
options.new_process_group = true; // detach
options.fds_to_remap = &no_stdout;
base::Process process = base::LaunchProcess(argv, options);
return process.IsValid() ? 0 : 1;
}

View file

@ -43,7 +43,7 @@ void RelauncherSynchronizeWithParent() {
struct kevent change = { 0 };
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)";
return;
}
@ -58,7 +58,7 @@ void RelauncherSynchronizeWithParent() {
// write above to complete. The parent process is now free to exit. Wait for
// that to happen.
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 < 0) {
PLOG(ERROR) << "kevent (monitor)";
@ -79,8 +79,16 @@ void RelauncherSynchronizeWithParent() {
int LaunchProgram(const StringVector& relauncher_args,
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;
options.new_process_group = true; // detach
options.fds_to_remap = &no_stdout;
base::Process process = base::LaunchProcess(argv, options);
return process.IsValid() ? 0 : 1;
}

View file

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 368 KiB

View file

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

View file

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

View file

@ -8,15 +8,12 @@
#include <map>
#include <string>
#include "atom/browser/ui/atom_menu_model.h"
#include "ui/base/accelerators/accelerator.h"
namespace ui {
class MenuModel;
}
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;
// Parse a string as an accelerator.
@ -27,7 +24,8 @@ bool StringToAccelerator(const std::string& description,
void SetPlatformAccelerator(ui::Accelerator* accelerator);
// 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.
bool TriggerAcceleratorTableCommand(AcceleratorTable* table,

View file

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

View file

@ -17,19 +17,37 @@ AtomMenuModel::~AtomMenuModel() {
}
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) {
if (ContainsKey(roles_, index))
return roles_[index];
int command_id = GetCommandIdAt(index);
if (ContainsKey(roles_, command_id))
return roles_[command_id];
else
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() {
ui::SimpleMenuModel::MenuClosed();
FOR_EACH_OBSERVER(Observer, observers_, MenuClosed());
}
AtomMenuModel* AtomMenuModel::GetSubmenuModelAt(int index) {
return static_cast<AtomMenuModel*>(
ui::SimpleMenuModel::GetSubmenuModelAt(index));
}
} // namespace atom

View file

@ -17,6 +17,19 @@ class AtomMenuModel : public ui::SimpleMenuModel {
class Delegate : public ui::SimpleMenuModel::Delegate {
public:
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 {
@ -35,14 +48,20 @@ class AtomMenuModel : public ui::SimpleMenuModel {
void SetRole(int index, const base::string16& role);
base::string16 GetRoleAt(int index);
bool GetAcceleratorAtWithParams(int index,
bool use_default_accelerator,
ui::Accelerator* accelerator) const;
// ui::SimpleMenuModel:
void MenuClosed() override;
using SimpleMenuModel::GetSubmenuModelAt;
AtomMenuModel* GetSubmenuModelAt(int index);
private:
Delegate* delegate_; // weak ref.
std::map<int, base::string16> roles_;
std::map<int, base::string16> roles_; // command id -> role
base::ObserverList<Observer> observers_;
DISALLOW_COPY_AND_ASSIGN(AtomMenuModel);

View file

@ -11,8 +11,8 @@
#include "base/mac/scoped_nsobject.h"
#include "base/strings/string16.h"
namespace ui {
class MenuModel;
namespace atom {
class AtomMenuModel;
}
// 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.
@interface AtomMenuController : NSObject<NSMenuDelegate> {
@protected
ui::MenuModel* model_; // weak
atom::AtomMenuModel* model_; // weak
base::scoped_nsobject<NSMenu> menu_;
BOOL isMenuOpen_;
BOOL useDefaultAccelerator_;
}
@property(nonatomic, assign) ui::MenuModel* 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;
@property(nonatomic, assign) atom::AtomMenuModel* model;
// 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.
- (id)initWithModel:(ui::MenuModel*)model;
- (id)initWithModel:(atom::AtomMenuModel*)model useDefaultAccelerator:(BOOL)use;
// Populate current NSMenu with |model|.
- (void)populateWithModel:(ui::MenuModel*)model;
- (void)populateWithModel:(atom::AtomMenuModel*)model;
// Programmatically close the constructed menu.
- (void)cancel;

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