Merge branch 'master' into chrome52

This commit is contained in:
Cheng Zhao 2016-07-21 05:34:36 -06:00
commit b57665330c
203 changed files with 2352 additions and 1220 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -46,8 +46,10 @@ class Menu : public mate::TrackableObject<Menu>,
bool IsCommandIdChecked(int command_id) const override; bool IsCommandIdChecked(int command_id) const override;
bool IsCommandIdEnabled(int command_id) const override; bool IsCommandIdEnabled(int command_id) const override;
bool IsCommandIdVisible(int command_id) const override; bool IsCommandIdVisible(int command_id) const override;
bool GetAcceleratorForCommandId(int command_id, bool GetAcceleratorForCommandIdWithParams(
ui::Accelerator* accelerator) override; int command_id,
bool use_default_accelerator,
ui::Accelerator* accelerator) const override;
void ExecuteCommand(int command_id, int event_flags) override; void ExecuteCommand(int command_id, int event_flags) override;
void MenuWillShow(ui::SimpleMenuModel* source) override; void MenuWillShow(ui::SimpleMenuModel* source) override;
@ -89,7 +91,7 @@ class Menu : public mate::TrackableObject<Menu>,
base::Callback<bool(int)> is_checked_; base::Callback<bool(int)> is_checked_;
base::Callback<bool(int)> is_enabled_; base::Callback<bool(int)> is_enabled_;
base::Callback<bool(int)> is_visible_; base::Callback<bool(int)> is_visible_;
base::Callback<v8::Local<v8::Value>(int)> get_accelerator_; base::Callback<v8::Local<v8::Value>(int, bool)> get_accelerator_;
base::Callback<void(v8::Local<v8::Value>, int)> execute_command_; base::Callback<void(v8::Local<v8::Value>, int)> execute_command_;
base::Callback<void()> menu_will_show_; base::Callback<void()> menu_will_show_;

View file

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

View file

@ -5,6 +5,7 @@
#include "atom/browser/api/atom_api_menu_views.h" #include "atom/browser/api/atom_api_menu_views.h"
#include "atom/browser/native_window_views.h" #include "atom/browser/native_window_views.h"
#include "atom/browser/unresponsive_suppressor.h"
#include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/render_widget_host_view.h"
#include "ui/display/screen.h" #include "ui/display/screen.h"
#include "ui/views/controls/menu/menu_runner.h" #include "ui/views/controls/menu/menu_runner.h"
@ -36,6 +37,9 @@ void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item) {
location = gfx::Point(origin.x() + x, origin.y() + y); location = gfx::Point(origin.x() + x, origin.y() + y);
} }
// Don't emit unresponsive event when showing menu.
atom::UnresponsiveSuppressor suppressor;
// Show the menu. // Show the menu.
views::MenuRunner menu_runner( views::MenuRunner menu_runner(
model(), model(),

View file

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

View file

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

View file

@ -11,6 +11,7 @@
#include "atom/browser/api/atom_api_download_item.h" #include "atom/browser/api/atom_api_download_item.h"
#include "atom/browser/api/atom_api_protocol.h" #include "atom/browser/api/atom_api_protocol.h"
#include "atom/browser/api/atom_api_web_request.h" #include "atom/browser/api/atom_api_web_request.h"
#include "atom/browser/browser.h"
#include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h" #include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/atom_permission_manager.h" #include "atom/browser/atom_permission_manager.h"
@ -20,6 +21,7 @@
#include "atom/common/native_mate_converters/gurl_converter.h" #include "atom/common/native_mate_converters/gurl_converter.h"
#include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/net_converter.h" #include "atom/common/native_mate_converters/net_converter.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "atom/common/node_includes.h" #include "atom/common/node_includes.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/guid.h" #include "base/guid.h"
@ -163,6 +165,8 @@ namespace api {
namespace { namespace {
const char kPersistPrefix[] = "persist:";
// The wrapSession funtion which is implemented in JavaScript // The wrapSession funtion which is implemented in JavaScript
using WrapSessionCallback = base::Callback<void(v8::Local<v8::Value>)>; using WrapSessionCallback = base::Callback<void(v8::Local<v8::Value>)>;
WrapSessionCallback g_wrap_session; WrapSessionCallback g_wrap_session;
@ -241,10 +245,10 @@ void OnGetBackend(disk_cache::Backend** backend_ptr,
} else if (action == Session::CacheAction::STATS) { } else if (action == Session::CacheAction::STATS) {
base::StringPairs stats; base::StringPairs stats;
(*backend_ptr)->GetStats(&stats); (*backend_ptr)->GetStats(&stats);
for (size_t i = 0; i < stats.size(); ++i) { for (const auto& stat : stats) {
if (stats[i].first == "Current size") { if (stat.first == "Current size") {
int current_size; int current_size;
base::StringToInt(stats[i].second, &current_size); base::StringToInt(stat.second, &current_size);
RunCallbackInUI(callback, current_size); RunCallbackInUI(callback, current_size);
break; break;
} }
@ -266,7 +270,7 @@ void DoCacheActionInIO(
// Call GetBackend and make the backend's ptr accessable in OnGetBackend. // Call GetBackend and make the backend's ptr accessable in OnGetBackend.
using BackendPtr = disk_cache::Backend*; using BackendPtr = disk_cache::Backend*;
BackendPtr* backend_ptr = new BackendPtr(nullptr); auto* backend_ptr = new BackendPtr(nullptr);
net::CompletionCallback on_get_backend = net::CompletionCallback on_get_backend =
base::Bind(&OnGetBackend, base::Owned(backend_ptr), action, callback); base::Bind(&OnGetBackend, base::Owned(backend_ptr), action, callback);
int rv = http_cache->GetBackend(backend_ptr, on_get_backend); int rv = http_cache->GetBackend(backend_ptr, on_get_backend);
@ -285,6 +289,14 @@ void SetProxyInIO(net::URLRequestContextGetter* getter,
RunCallbackInUI(callback); RunCallbackInUI(callback);
} }
void SetCertVerifyProcInIO(
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
const AtomCertVerifier::VerifyProc& proc) {
auto request_context = context_getter->GetURLRequestContext();
static_cast<AtomCertVerifier*>(request_context->cert_verifier())->
SetVerifyProc(proc);
}
void ClearHostResolverCacheInIO( void ClearHostResolverCacheInIO(
const scoped_refptr<net::URLRequestContextGetter>& context_getter, const scoped_refptr<net::URLRequestContextGetter>& context_getter,
const base::Closure& callback) { const base::Closure& callback) {
@ -311,6 +323,11 @@ void AllowNTLMCredentialsForDomainsInIO(
} }
} }
void OnClearStorageDataDone(const base::Closure& callback) {
if (!callback.is_null())
callback.Run();
}
} // namespace } // namespace
Session::Session(v8::Isolate* isolate, AtomBrowserContext* browser_context) Session::Session(v8::Isolate* isolate, AtomBrowserContext* browser_context)
@ -360,21 +377,19 @@ void Session::DoCacheAction(const net::CompletionCallback& callback) {
} }
void Session::ClearStorageData(mate::Arguments* args) { void Session::ClearStorageData(mate::Arguments* args) {
// clearStorageData([options, ]callback) // clearStorageData([options, callback])
ClearStorageDataOptions options; ClearStorageDataOptions options;
args->GetNext(&options);
base::Closure callback; base::Closure callback;
if (!args->GetNext(&callback)) { args->GetNext(&options);
args->ThrowError(); args->GetNext(&callback);
return;
}
auto storage_partition = auto storage_partition =
content::BrowserContext::GetStoragePartition(browser_context(), nullptr); content::BrowserContext::GetStoragePartition(browser_context(), nullptr);
storage_partition->ClearData( storage_partition->ClearData(
options.storage_types, options.quota_types, options.origin, options.storage_types, options.quota_types, options.origin,
content::StoragePartition::OriginMatcherFunction(), content::StoragePartition::OriginMatcherFunction(),
base::Time(), base::Time::Max(), callback); base::Time(), base::Time::Max(),
base::Bind(&OnClearStorageDataDone, callback));
} }
void Session::FlushStorageData() { void Session::FlushStorageData() {
@ -434,7 +449,10 @@ void Session::SetCertVerifyProc(v8::Local<v8::Value> val,
return; return;
} }
browser_context_->cert_verifier()->SetVerifyProc(proc); BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&SetCertVerifyProcInIO,
make_scoped_refptr(browser_context_->GetRequestContext()),
proc));
} }
void Session::SetPermissionRequestHandler(v8::Local<v8::Value> val, void Session::SetPermissionRequestHandler(v8::Local<v8::Value> val,
@ -522,10 +540,19 @@ mate::Handle<Session> Session::CreateFrom(
// static // static
mate::Handle<Session> Session::FromPartition( mate::Handle<Session> Session::FromPartition(
v8::Isolate* isolate, const std::string& partition, bool in_memory) { v8::Isolate* isolate, const std::string& partition,
auto browser_context = brightray::BrowserContext::From(partition, in_memory); const base::DictionaryValue& options) {
return CreateFrom(isolate, scoped_refptr<AtomBrowserContext> browser_context;
static_cast<AtomBrowserContext*>(browser_context.get())); if (partition.empty()) {
browser_context = AtomBrowserContext::From("", false, options);
} else if (base::StartsWith(partition, kPersistPrefix,
base::CompareCase::SENSITIVE)) {
std::string name = partition.substr(8);
browser_context = AtomBrowserContext::From(name, false, options);
} else {
browser_context = AtomBrowserContext::From(partition, true, options);
}
return CreateFrom(isolate, browser_context.get());
} }
// static // static
@ -565,11 +592,23 @@ void SetWrapSession(const WrapSessionCallback& callback) {
namespace { namespace {
v8::Local<v8::Value> FromPartition(
const std::string& partition, mate::Arguments* args) {
if (!atom::Browser::Get()->is_ready()) {
args->ThrowError("Session can only be received when app is ready");
return v8::Null(args->isolate());
}
base::DictionaryValue options;
args->GetNext(&options);
return atom::api::Session::FromPartition(
args->isolate(), partition, options).ToV8();
}
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused, void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) { v8::Local<v8::Context> context, void* priv) {
v8::Isolate* isolate = context->GetIsolate(); v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports); mate::Dictionary dict(isolate, exports);
dict.SetMethod("fromPartition", &atom::api::Session::FromPartition); dict.SetMethod("fromPartition", &FromPartition);
dict.SetMethod("_setWrapSession", &atom::api::SetWrapSession); dict.SetMethod("_setWrapSession", &atom::api::SetWrapSession);
} }

View file

@ -8,6 +8,7 @@
#include <string> #include <string>
#include "atom/browser/api/trackable_object.h" #include "atom/browser/api/trackable_object.h"
#include "base/values.h"
#include "content/public/browser/download_manager.h" #include "content/public/browser/download_manager.h"
#include "native_mate/handle.h" #include "native_mate/handle.h"
#include "net/base/completion_callback.h" #include "net/base/completion_callback.h"
@ -47,9 +48,10 @@ class Session: public mate::TrackableObject<Session>,
static mate::Handle<Session> CreateFrom( static mate::Handle<Session> CreateFrom(
v8::Isolate* isolate, AtomBrowserContext* browser_context); v8::Isolate* isolate, AtomBrowserContext* browser_context);
// Gets the Session of |partition| and |in_memory|. // Gets the Session of |partition|.
static mate::Handle<Session> FromPartition( static mate::Handle<Session> FromPartition(
v8::Isolate* isolate, const std::string& partition, bool in_memory); v8::Isolate* isolate, const std::string& partition,
const base::DictionaryValue& options = base::DictionaryValue());
AtomBrowserContext* browser_context() const { return browser_context_.get(); } AtomBrowserContext* browser_context() const { return browser_context_.get(); }

View file

@ -29,6 +29,8 @@ Tray::Tray(v8::Isolate* isolate, mate::Handle<NativeImage> image)
} }
Tray::~Tray() { Tray::~Tray() {
// Destroy the native tray in next tick.
base::MessageLoop::current()->DeleteSoon(FROM_HERE, tray_icon_.release());
} }
// static // static
@ -74,6 +76,10 @@ void Tray::OnDropFiles(const std::vector<std::string>& files) {
Emit("drop-files", files); Emit("drop-files", files);
} }
void Tray::OnDropText(const std::string& text) {
Emit("drop-text", text);
}
void Tray::OnDragEntered() { void Tray::OnDragEntered() {
Emit("drag-enter"); Emit("drag-enter");
} }

View file

@ -53,6 +53,7 @@ class Tray : public mate::TrackableObject<Tray>,
void OnBalloonClosed() override; void OnBalloonClosed() override;
void OnDrop() override; void OnDrop() override;
void OnDropFiles(const std::vector<std::string>& files) override; void OnDropFiles(const std::vector<std::string>& files) override;
void OnDropText(const std::string& text) override;
void OnDragEntered() override; void OnDragEntered() override;
void OnDragExited() override; void OnDragExited() override;
void OnDragEnded() override; void OnDragEnded() override;

View file

@ -47,6 +47,7 @@
#include "content/public/browser/native_web_keyboard_event.h" #include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/browser/navigation_details.h" #include "content/public/browser/navigation_details.h"
#include "content/public/browser/navigation_entry.h" #include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/plugin_service.h" #include "content/public/browser/plugin_service.h"
#include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h" #include "content/public/browser/render_process_host.h"
@ -65,6 +66,7 @@
#include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context.h"
#include "third_party/WebKit/public/web/WebInputEvent.h" #include "third_party/WebKit/public/web/WebInputEvent.h"
#include "third_party/WebKit/public/web/WebFindOptions.h" #include "third_party/WebKit/public/web/WebFindOptions.h"
#include "ui/gfx/screen.h"
#include "atom/common/node_includes.h" #include "atom/common/node_includes.h"
@ -238,6 +240,13 @@ content::ServiceWorkerContext* GetServiceWorkerContext(
return storage_partition->GetServiceWorkerContext(); return storage_partition->GetServiceWorkerContext();
} }
// Called when CapturePage is done.
void OnCapturePageDone(base::Callback<void(const gfx::Image&)> callback,
const SkBitmap& bitmap,
content::ReadbackResponse response) {
callback.Run(gfx::Image::CreateFrom1xBitmap(bitmap));
}
} // namespace } // namespace
WebContents::WebContents(v8::Isolate* isolate, WebContents::WebContents(v8::Isolate* isolate,
@ -277,16 +286,11 @@ WebContents::WebContents(v8::Isolate* isolate,
std::string partition; std::string partition;
mate::Handle<api::Session> session; mate::Handle<api::Session> session;
if (options.Get("session", &session)) { if (options.Get("session", &session)) {
} else if (options.Get("partition", &partition) && !partition.empty()) { } else if (options.Get("partition", &partition)) {
bool in_memory = true; session = Session::FromPartition(isolate, partition);
if (base::StartsWith(partition, "persist:", base::CompareCase::SENSITIVE)) {
in_memory = false;
partition = partition.substr(8);
}
session = Session::FromPartition(isolate, partition, in_memory);
} else { } else {
// Use the default session if not specified. // Use the default session if not specified.
session = Session::FromPartition(isolate, "", false); session = Session::FromPartition(isolate, "");
} }
session_.Reset(isolate, session.ToV8()); session_.Reset(isolate, session.ToV8());
@ -600,20 +604,6 @@ void WebContents::DidFinishLoad(content::RenderFrameHost* render_frame_host,
Emit("did-finish-load"); Emit("did-finish-load");
} }
void WebContents::DidFailProvisionalLoad(
content::RenderFrameHost* render_frame_host,
const GURL& url,
int code,
const base::string16& description,
bool was_ignored_by_handler) {
bool is_main_frame = !render_frame_host->GetParent();
Emit("did-fail-provisional-load", code, description, url, is_main_frame);
// 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::DidFailLoad(content::RenderFrameHost* render_frame_host, void WebContents::DidFailLoad(content::RenderFrameHost* render_frame_host,
const GURL& url, const GURL& url,
int error_code, int error_code,
@ -657,13 +647,27 @@ void WebContents::DidGetRedirectForResourceRequest(
details.headers.get()); details.headers.get());
} }
void WebContents::DidNavigateMainFrame( void WebContents::DidFinishNavigation(
const content::LoadCommittedDetails& details, content::NavigationHandle* navigation_handle) {
const content::FrameNavigateParams& params) { bool is_main_frame = navigation_handle->IsInMainFrame();
if (details.is_navigation_to_different_page()) if (navigation_handle->HasCommitted() && !navigation_handle->IsErrorPage()) {
Emit("did-navigate", params.url); auto url = navigation_handle->GetURL();
else if (details.is_in_page) bool is_in_page = navigation_handle->IsSamePage();
Emit("did-navigate-in-page", params.url); if (is_main_frame && !is_in_page) {
Emit("did-navigate", url);
} else if (is_in_page) {
Emit("did-navigate-in-page", url);
}
} else {
auto url = navigation_handle->GetURL();
int code = navigation_handle->GetNetErrorCode();
auto description = net::ErrorToShortString(code);
Emit("did-fail-provisional-load", code, description, url, is_main_frame);
// Do not emit "did-fail-load" for canceled requests.
if (code != net::ERR_ABORTED)
Emit("did-fail-load", code, description, url, is_main_frame);
}
} }
void WebContents::TitleWasSet(content::NavigationEntry* entry, void WebContents::TitleWasSet(content::NavigationEntry* entry,
@ -677,10 +681,10 @@ void WebContents::TitleWasSet(content::NavigationEntry* entry,
void WebContents::DidUpdateFaviconURL( void WebContents::DidUpdateFaviconURL(
const std::vector<content::FaviconURL>& urls) { const std::vector<content::FaviconURL>& urls) {
std::set<GURL> unique_urls; std::set<GURL> unique_urls;
for (auto iter = urls.begin(); iter != urls.end(); ++iter) { for (const auto& iter : urls) {
if (iter->icon_type != content::FaviconURL::FAVICON) if (iter.icon_type != content::FaviconURL::FAVICON)
continue; continue;
const GURL& url = iter->icon_url; const GURL& url = iter.icon_url;
if (url.is_valid()) if (url.is_valid())
unique_urls.insert(url); unique_urls.insert(url);
} }
@ -781,6 +785,13 @@ WebContents::Type WebContents::GetType() const {
return type_; return type_;
} }
#if !defined(OS_MACOSX)
bool WebContents::IsFocused() const {
auto view = web_contents()->GetRenderWidgetHostView();
return view && view->HasFocus();
}
#endif
bool WebContents::Equal(const WebContents* web_contents) const { bool WebContents::Equal(const WebContents* web_contents) const {
return GetID() == web_contents->GetID(); return GetID() == web_contents->GetID();
} }
@ -1235,6 +1246,45 @@ void WebContents::StartDrag(const mate::Dictionary& item,
} }
} }
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 =
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(&OnCapturePageDone, callback),
kBGRA_8888_SkColorType);
}
void WebContents::OnCursorChange(const content::WebCursor& cursor) { void WebContents::OnCursorChange(const content::WebCursor& cursor) {
content::WebCursor::CursorInfo info; content::WebCursor::CursorInfo info;
cursor.GetCursorInfo(&info); cursor.GetCursorInfo(&info);
@ -1370,6 +1420,8 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
.SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace) .SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace)
.SetMethod("showDefinitionForSelection", .SetMethod("showDefinitionForSelection",
&WebContents::ShowDefinitionForSelection) &WebContents::ShowDefinitionForSelection)
.SetMethod("capturePage", &WebContents::CapturePage)
.SetMethod("isFocused", &WebContents::IsFocused)
.SetProperty("id", &WebContents::ID) .SetProperty("id", &WebContents::ID)
.SetProperty("session", &WebContents::Session) .SetProperty("session", &WebContents::Session)
.SetProperty("hostWebContents", &WebContents::HostWebContents) .SetProperty("hostWebContents", &WebContents::HostWebContents)

View file

@ -67,6 +67,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
int GetID() const; int GetID() const;
Type GetType() const; Type GetType() const;
bool IsFocused() const;
bool Equal(const WebContents* web_contents) const; bool Equal(const WebContents* web_contents) const;
void LoadURL(const GURL& url, const mate::Dictionary& options); void LoadURL(const GURL& url, const mate::Dictionary& options);
void DownloadURL(const GURL& url); void DownloadURL(const GURL& url);
@ -145,6 +146,10 @@ class WebContents : public mate::TrackableObject<WebContents>,
// Dragging native items. // Dragging native items.
void StartDrag(const mate::Dictionary& item, mate::Arguments* args); void StartDrag(const mate::Dictionary& item, mate::Arguments* args);
// Captures the page with |rect|, |callback| would be called when capturing is
// done.
void CapturePage(mate::Arguments* args);
// Methods for creating <webview>. // Methods for creating <webview>.
void SetSize(const SetSizeParams& params); void SetSize(const SetSizeParams& params);
bool IsGuest() const; bool IsGuest() const;
@ -240,11 +245,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
int error_code, int error_code,
const base::string16& error_description, const base::string16& error_description,
bool was_ignored_by_handler) override; bool was_ignored_by_handler) override;
void DidFailProvisionalLoad(content::RenderFrameHost* render_frame_host,
const GURL& validated_url,
int error_code,
const base::string16& error_description,
bool was_ignored_by_handler) override;
void DidStartLoading() override; void DidStartLoading() override;
void DidStopLoading() override; void DidStopLoading() override;
void DidGetResourceResponseStart( void DidGetResourceResponseStart(
@ -252,9 +252,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
void DidGetRedirectForResourceRequest( void DidGetRedirectForResourceRequest(
content::RenderFrameHost* render_frame_host, content::RenderFrameHost* render_frame_host,
const content::ResourceRedirectDetails& details) override; const content::ResourceRedirectDetails& details) override;
void DidNavigateMainFrame( void DidFinishNavigation(
const content::LoadCommittedDetails& details, content::NavigationHandle* navigation_handle) override;
const content::FrameNavigateParams& params) override;
bool OnMessageReceived(const IPC::Message& message) override; bool OnMessageReceived(const IPC::Message& message) override;
void WebContentsDestroyed() override; void WebContentsDestroyed() override;
void NavigationEntryCommitted( void NavigationEntryCommitted(

View file

@ -0,0 +1,30 @@
// 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 {
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;
}
auto view = web_contents()->GetRenderWidgetHostView();
return view && view->HasFocus();
}
} // namespace api
} // namespace atom

View file

@ -55,15 +55,6 @@ namespace api {
namespace { namespace {
void OnCapturePageDone(
v8::Isolate* isolate,
const base::Callback<void(const gfx::Image&)>& callback,
const SkBitmap& bitmap) {
v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
callback.Run(gfx::Image::CreateFrom1xBitmap(bitmap));
}
// Converts binary data to Buffer. // Converts binary data to Buffer.
v8::Local<v8::Value> ToBuffer(v8::Isolate* isolate, void* val, int size) { v8::Local<v8::Value> ToBuffer(v8::Isolate* isolate, void* val, int size) {
auto buffer = node::Buffer::Copy(isolate, static_cast<char*>(val), size); auto buffer = node::Buffer::Copy(isolate, static_cast<char*>(val), size);
@ -581,21 +572,6 @@ void Window::SetFocusable(bool focusable) {
return window_->SetFocusable(focusable); return window_->SetFocusable(focusable);
} }
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::SetProgressBar(double progress) { void Window::SetProgressBar(double progress) {
window_->SetProgressBar(progress); window_->SetProgressBar(progress);
} }
@ -673,6 +649,12 @@ bool Window::IsWindowMessageHooked(UINT message) {
void Window::UnhookAllWindowMessages() { void Window::UnhookAllWindowMessages() {
messages_callback_map_.clear(); messages_callback_map_.clear();
} }
bool Window::SetThumbnailClip(const gfx::Rect& region) {
auto window = static_cast<NativeWindowViews*>(window_.get());
return window->taskbar_host().SetThumbnailClip(
window_->GetAcceleratedWidget(), region);
}
#endif #endif
#if defined(TOOLKIT_VIEWS) #if defined(TOOLKIT_VIEWS)
@ -843,7 +825,6 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("focusOnWebView", &Window::FocusOnWebView) .SetMethod("focusOnWebView", &Window::FocusOnWebView)
.SetMethod("blurWebView", &Window::BlurWebView) .SetMethod("blurWebView", &Window::BlurWebView)
.SetMethod("isWebViewFocused", &Window::IsWebViewFocused) .SetMethod("isWebViewFocused", &Window::IsWebViewFocused)
.SetMethod("capturePage", &Window::CapturePage)
.SetMethod("setProgressBar", &Window::SetProgressBar) .SetMethod("setProgressBar", &Window::SetProgressBar)
.SetMethod("setOverlayIcon", &Window::SetOverlayIcon) .SetMethod("setOverlayIcon", &Window::SetOverlayIcon)
.SetMethod("setThumbarButtons", &Window::SetThumbarButtons) .SetMethod("setThumbarButtons", &Window::SetThumbarButtons)
@ -861,6 +842,7 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("isWindowMessageHooked", &Window::IsWindowMessageHooked) .SetMethod("isWindowMessageHooked", &Window::IsWindowMessageHooked)
.SetMethod("unhookWindowMessage", &Window::UnhookWindowMessage) .SetMethod("unhookWindowMessage", &Window::UnhookWindowMessage)
.SetMethod("unhookAllWindowMessages", &Window::UnhookAllWindowMessages) .SetMethod("unhookAllWindowMessages", &Window::UnhookAllWindowMessages)
.SetMethod("setThumbnailClip", &Window::SetThumbnailClip)
#endif #endif
#if defined(TOOLKIT_VIEWS) #if defined(TOOLKIT_VIEWS)
.SetMethod("setIcon", &Window::SetIcon) .SetMethod("setIcon", &Window::SetIcon)

View file

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

View file

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

View file

@ -25,7 +25,6 @@ const char* kGeolocationProviderURL =
} // namespace } // namespace
AtomAccessTokenStore::AtomAccessTokenStore() { AtomAccessTokenStore::AtomAccessTokenStore() {
LOG(ERROR) << "AtomAccessTokenStore";
content::GeolocationProvider::GetInstance()->UserDidOptIntoLocationServices(); content::GeolocationProvider::GetInstance()->UserDidOptIntoLocationServices();
} }
@ -47,8 +46,8 @@ void AtomAccessTokenStore::SaveAccessToken(const GURL& server_url,
} }
void AtomAccessTokenStore::GetRequestContextOnUIThread() { void AtomAccessTokenStore::GetRequestContextOnUIThread() {
auto browser_context = brightray::BrowserContext::From("", false); auto browser_context = AtomBrowserContext::From("", false);
request_context_getter_ = browser_context->url_request_context_getter(); request_context_getter_ = browser_context->GetRequestContext();
} }
void AtomAccessTokenStore::RespondOnOriginatingThread( void AtomAccessTokenStore::RespondOnOriginatingThread(

View file

@ -63,10 +63,10 @@ std::string RemoveWhitespace(const std::string& str) {
} // namespace } // namespace
AtomBrowserContext::AtomBrowserContext(const std::string& partition, AtomBrowserContext::AtomBrowserContext(
bool in_memory) const std::string& partition, bool in_memory,
const base::DictionaryValue& options)
: brightray::BrowserContext(partition, in_memory), : brightray::BrowserContext(partition, in_memory),
cert_verifier_(new AtomCertVerifier),
network_delegate_(new AtomNetworkDelegate) { network_delegate_(new AtomNetworkDelegate) {
// Construct user agent string. // Construct user agent string.
Browser* browser = Browser::Get(); Browser* browser = Browser::Get();
@ -83,6 +83,10 @@ AtomBrowserContext::AtomBrowserContext(const std::string& partition,
CHROME_VERSION_STRING); CHROME_VERSION_STRING);
} }
user_agent_ = content::BuildUserAgentFromProduct(user_agent); user_agent_ = content::BuildUserAgentFromProduct(user_agent);
// Read options.
use_cache_ = true;
options.GetBoolean("cache", &use_cache_);
} }
AtomBrowserContext::~AtomBrowserContext() { AtomBrowserContext::~AtomBrowserContext() {
@ -145,7 +149,7 @@ net::HttpCache::BackendFactory*
AtomBrowserContext::CreateHttpCacheBackendFactory( AtomBrowserContext::CreateHttpCacheBackendFactory(
const base::FilePath& base_path) { const base::FilePath& base_path) {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kDisableHttpCache)) if (!use_cache_ || command_line->HasSwitch(switches::kDisableHttpCache))
return new NoCacheBackend; return new NoCacheBackend;
else else
return brightray::BrowserContext::CreateHttpCacheBackendFactory(base_path); return brightray::BrowserContext::CreateHttpCacheBackendFactory(base_path);
@ -174,7 +178,7 @@ content::PermissionManager* AtomBrowserContext::GetPermissionManager() {
} }
std::unique_ptr<net::CertVerifier> AtomBrowserContext::CreateCertVerifier() { std::unique_ptr<net::CertVerifier> AtomBrowserContext::CreateCertVerifier() {
return base::WrapUnique(cert_verifier_); return base::WrapUnique(new AtomCertVerifier);
} }
net::SSLConfigService* AtomBrowserContext::CreateSSLConfigService() { net::SSLConfigService* AtomBrowserContext::CreateSSLConfigService() {
@ -191,14 +195,15 @@ void AtomBrowserContext::RegisterPrefs(PrefRegistrySimple* pref_registry) {
pref_registry->RegisterDictionaryPref(prefs::kDevToolsFileSystemPaths); pref_registry->RegisterDictionaryPref(prefs::kDevToolsFileSystemPaths);
} }
} // namespace atom
namespace brightray {
// static // static
scoped_refptr<BrowserContext> BrowserContext::Create( scoped_refptr<AtomBrowserContext> AtomBrowserContext::From(
const std::string& partition, bool in_memory) { const std::string& partition, bool in_memory,
return make_scoped_refptr(new atom::AtomBrowserContext(partition, in_memory)); const base::DictionaryValue& options) {
auto browser_context = brightray::BrowserContext::Get(partition, in_memory);
if (browser_context)
return static_cast<AtomBrowserContext*>(browser_context.get());
return new AtomBrowserContext(partition, in_memory, options);
} }
} // namespace brightray } // namespace atom

View file

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

View file

@ -32,7 +32,7 @@ void Erase(T* container, typename T::iterator iter) {
} }
// static // static
AtomBrowserMainParts* AtomBrowserMainParts::self_ = NULL; AtomBrowserMainParts* AtomBrowserMainParts::self_ = nullptr;
AtomBrowserMainParts::AtomBrowserMainParts() AtomBrowserMainParts::AtomBrowserMainParts()
: fake_browser_process_(new BrowserProcess), : fake_browser_process_(new BrowserProcess),

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -155,6 +155,12 @@ void Browser::DidFinishLaunching() {
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnFinishLaunching()); FOR_EACH_OBSERVER(BrowserObserver, observers_, OnFinishLaunching());
} }
void Browser::OnAccessibilitySupportChanged() {
FOR_EACH_OBSERVER(BrowserObserver,
observers_,
OnAccessibilitySupportChanged());
}
void Browser::RequestLogin( void Browser::RequestLogin(
LoginHandler* login_handler, LoginHandler* login_handler,
std::unique_ptr<base::DictionaryValue> request_details) { std::unique_ptr<base::DictionaryValue> request_details) {

View file

@ -25,16 +25,13 @@ class DictionaryValue;
class FilePath; class FilePath;
} }
namespace ui {
class MenuModel;
}
namespace gfx { namespace gfx {
class Image; class Image;
} }
namespace atom { namespace atom {
class AtomMenuModel;
class LoginHandler; class LoginHandler;
// This class is used for control application-wide operations. // This class is used for control application-wide operations.
@ -91,6 +88,17 @@ class Browser : public WindowListObserver {
bool SetBadgeCount(int count); bool SetBadgeCount(int count);
int GetBadgeCount(); int GetBadgeCount();
// Set/Get the login item settings of the app
struct LoginItemSettings {
bool open_at_login = false;
bool open_as_hidden = false;
bool restore_state = false;
bool opened_at_login = false;
bool opened_as_hidden = false;
};
void SetLoginItemSettings(LoginItemSettings settings);
LoginItemSettings GetLoginItemSettings();
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
// Hide the application. // Hide the application.
void Hide(); void Hide();
@ -130,7 +138,7 @@ class Browser : public WindowListObserver {
void DockShow(); void DockShow();
// Set docks' menu. // Set docks' menu.
void DockSetMenu(ui::MenuModel* model); void DockSetMenu(AtomMenuModel* model);
// Set docks' icon. // Set docks' icon.
void DockSetIcon(const gfx::Image& image); void DockSetIcon(const gfx::Image& image);
@ -174,6 +182,8 @@ class Browser : public WindowListObserver {
void WillFinishLaunching(); void WillFinishLaunching();
void DidFinishLaunching(); void DidFinishLaunching();
void OnAccessibilitySupportChanged();
// Request basic auth login. // Request basic auth login.
void RequestLogin(LoginHandler* login_handler, void RequestLogin(LoginHandler* login_handler,
std::unique_ptr<base::DictionaryValue> request_details); std::unique_ptr<base::DictionaryValue> request_details);

View file

@ -57,6 +57,13 @@ bool Browser::SetBadgeCount(int count) {
} }
} }
void Browser::SetLoginItemSettings(LoginItemSettings settings) {
}
Browser::LoginItemSettings Browser::GetLoginItemSettings() {
return LoginItemSettings();
}
std::string Browser::GetExecutableFileVersion() const { std::string Browser::GetExecutableFileVersion() const {
return brightray::GetApplicationVersion(); return brightray::GetApplicationVersion();
} }

View file

@ -11,6 +11,7 @@
#include "atom/browser/window_list.h" #include "atom/browser/window_list.h"
#include "base/mac/bundle_locations.h" #include "base/mac/bundle_locations.h"
#include "base/mac/foundation_util.h" #include "base/mac/foundation_util.h"
#include "base/mac/mac_util.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "base/strings/sys_string_conversions.h" #include "base/strings/sys_string_conversions.h"
#include "brightray/common/application_info.h" #include "brightray/common/application_info.h"
@ -148,6 +149,23 @@ bool Browser::ContinueUserActivity(const std::string& type,
return prevent_default; return prevent_default;
} }
Browser::LoginItemSettings Browser::GetLoginItemSettings() {
LoginItemSettings settings;
settings.open_at_login = base::mac::CheckLoginItemStatus(
&settings.open_as_hidden);
settings.restore_state = base::mac::WasLaunchedAsLoginItemRestoreState();
settings.opened_at_login = base::mac::WasLaunchedAsLoginOrResumeItem();
settings.opened_as_hidden = base::mac::WasLaunchedAsHiddenLoginItem();
return settings;
}
void Browser::SetLoginItemSettings(LoginItemSettings settings) {
if (settings.open_at_login)
base::mac::AddToLoginItems(settings.open_as_hidden);
else
base::mac::RemoveFromLoginItems();
}
std::string Browser::GetExecutableFileVersion() const { std::string Browser::GetExecutableFileVersion() const {
return brightray::GetApplicationVersion(); return brightray::GetApplicationVersion();
} }
@ -216,7 +234,7 @@ void Browser::DockShow() {
} }
} }
void Browser::DockSetMenu(ui::MenuModel* model) { void Browser::DockSetMenu(AtomMenuModel* model) {
AtomApplicationDelegate* delegate = (AtomApplicationDelegate*)[NSApp delegate]; AtomApplicationDelegate* delegate = (AtomApplicationDelegate*)[NSApp delegate];
[delegate setApplicationDockMenu:model]; [delegate setApplicationDockMenu:model];
} }

View file

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

View file

@ -272,6 +272,39 @@ bool Browser::SetBadgeCount(int count) {
return false; return false;
} }
void Browser::SetLoginItemSettings(LoginItemSettings settings) {
std::wstring keyPath = L"Software\\Microsoft\\Windows\\CurrentVersion\\Run";
base::win::RegKey key(HKEY_CURRENT_USER, keyPath.c_str(), KEY_ALL_ACCESS);
if (settings.open_at_login) {
base::FilePath path;
if (PathService::Get(base::FILE_EXE, &path)) {
std::wstring exePath(path.value());
key.WriteValue(GetAppUserModelID(), exePath.c_str());
}
} else {
key.DeleteValue(GetAppUserModelID());
}
}
Browser::LoginItemSettings Browser::GetLoginItemSettings() {
LoginItemSettings settings;
std::wstring keyPath = L"Software\\Microsoft\\Windows\\CurrentVersion\\Run";
base::win::RegKey key(HKEY_CURRENT_USER, keyPath.c_str(), KEY_ALL_ACCESS);
std::wstring keyVal;
if (!FAILED(key.ReadValue(GetAppUserModelID(), &keyVal))) {
base::FilePath path;
if (PathService::Get(base::FILE_EXE, &path)) {
std::wstring exePath(path.value());
settings.open_at_login = keyVal == exePath;
}
}
return settings;
}
PCWSTR Browser::GetAppUserModelID() { PCWSTR Browser::GetAppUserModelID() {
if (app_user_model_id_.empty()) { if (app_user_model_id_.empty()) {
SetAppUserModelID(base::ReplaceStringPlaceholders( SetAppUserModelID(base::ReplaceStringPlaceholders(

View file

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

View file

@ -27,6 +27,11 @@ void CommonWebContentsDelegate::HandleKeyboardEvent(
if (event.windowsKeyCode == ui::VKEY_ESCAPE && is_html_fullscreen()) if (event.windowsKeyCode == ui::VKEY_ESCAPE && is_html_fullscreen())
ExitFullscreenModeForTab(source); ExitFullscreenModeForTab(source);
// 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) if (event.os_event.window)
[event.os_event.window redispatchKeyEvent:event.os_event]; [event.os_event.window redispatchKeyEvent:event.os_event];
} }

View file

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

View file

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

View file

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

View file

@ -11,6 +11,7 @@
#include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h" #include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/browser.h" #include "atom/browser/browser.h"
#include "atom/browser/unresponsive_suppressor.h"
#include "atom/browser/window_list.h" #include "atom/browser/window_list.h"
#include "atom/common/api/api_messages.h" #include "atom/common/api/api_messages.h"
#include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/native_mate_converters/file_path_converter.h"
@ -53,7 +54,6 @@ NativeWindow::NativeWindow(
transparent_(false), transparent_(false),
enable_larger_than_screen_(false), enable_larger_than_screen_(false),
is_closed_(false), is_closed_(false),
has_dialog_attached_(false),
sheet_offset_x_(0.0), sheet_offset_x_(0.0),
sheet_offset_y_(0.0), sheet_offset_y_(0.0),
aspect_ratio_(0.0), aspect_ratio_(0.0),
@ -210,7 +210,7 @@ gfx::Size NativeWindow::GetContentSize() {
void NativeWindow::SetSizeConstraints( void NativeWindow::SetSizeConstraints(
const extensions::SizeConstraints& window_constraints) { const extensions::SizeConstraints& window_constraints) {
extensions::SizeConstraints content_constraints; extensions::SizeConstraints content_constraints(GetContentSizeConstraints());
if (window_constraints.HasMaximumSize()) if (window_constraints.HasMaximumSize())
content_constraints.set_maximum_size( content_constraints.set_maximum_size(
WindowSizeToContentSize(window_constraints.GetMaximumSize())); WindowSizeToContentSize(window_constraints.GetMaximumSize()));
@ -291,11 +291,7 @@ bool NativeWindow::IsDocumentEdited() {
void NativeWindow::SetFocusable(bool focusable) { void NativeWindow::SetFocusable(bool focusable) {
} }
void NativeWindow::SetMenu(ui::MenuModel* menu) { void NativeWindow::SetMenu(AtomMenuModel* menu) {
}
bool NativeWindow::HasModalDialog() {
return has_dialog_attached_;
} }
void NativeWindow::SetParentWindow(NativeWindow* parent) { void NativeWindow::SetParentWindow(NativeWindow* parent) {
@ -315,39 +311,6 @@ bool NativeWindow::IsWebViewFocused() {
return host_view && host_view->HasFocus(); return host_view && host_view->HasFocus();
} }
void NativeWindow::CapturePage(const gfx::Rect& rect,
const CapturePageCallback& callback) {
const auto view = web_contents()->GetRenderWidgetHostView();
const auto host = view ? view->GetRenderWidgetHost() : nullptr;
if (!view || !host) {
callback.Run(SkBitmap());
return;
}
// Capture full page if user doesn't specify a |rect|.
const gfx::Size view_size = rect.IsEmpty() ? view->GetViewBounds().size() :
rect.size();
// By default, the requested bitmap size is the view size in screen
// coordinates. However, if there's more pixel detail available on the
// current system, increase the requested bitmap size to capture it all.
gfx::Size bitmap_size = view_size;
const gfx::NativeView native_view = view->GetNativeView();
const float scale =
display::Screen::GetScreen()->GetDisplayNearestWindow(native_view)
.device_scale_factor();
if (scale > 1.0f)
bitmap_size = gfx::ScaleToCeiledSize(view_size, scale);
host->CopyFromBackingStore(
gfx::Rect(rect.origin(), view_size),
bitmap_size,
base::Bind(&NativeWindow::OnCapturePageDone,
weak_factory_.GetWeakPtr(),
callback),
kBGRA_8888_SkColorType);
}
void NativeWindow::SetAutoHideMenuBar(bool auto_hide) { void NativeWindow::SetAutoHideMenuBar(bool auto_hide) {
} }
@ -624,7 +587,7 @@ void NativeWindow::ScheduleUnresponsiveEvent(int ms) {
void NativeWindow::NotifyWindowUnresponsive() { void NativeWindow::NotifyWindowUnresponsive() {
window_unresposive_closure_.Cancel(); window_unresposive_closure_.Cancel();
if (!is_closed_ && !HasModalDialog() && IsEnabled()) if (!is_closed_ && !IsUnresponsiveEventSuppressed() && IsEnabled())
FOR_EACH_OBSERVER(NativeWindowObserver, FOR_EACH_OBSERVER(NativeWindowObserver,
observers_, observers_,
OnRendererUnresponsive()); OnRendererUnresponsive());
@ -634,10 +597,4 @@ void NativeWindow::NotifyReadyToShow() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnReadyToShow()); FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnReadyToShow());
} }
void NativeWindow::OnCapturePageDone(const CapturePageCallback& callback,
const SkBitmap& bitmap,
content::ReadbackResponse response) {
callback.Run(bitmap);
}
} // namespace atom } // namespace atom

View file

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

View file

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

View file

@ -241,13 +241,6 @@ bool ScopedDisableResize::disable_resize_ = false;
} }
- (void)windowDidExitFullScreen:(NSNotification*)notification { - (void)windowDidExitFullScreen:(NSNotification*)notification {
// For certain versions of macOS the fullscreen button will automatically show
// after exiting fullscreen mode.
if (!shell_->has_frame()) {
NSWindow* window = shell_->GetNativeWindow();
[[window standardWindowButton:NSWindowFullScreenButton] setHidden:YES];
}
shell_->NotifyWindowLeaveFullScreen(); shell_->NotifyWindowLeaveFullScreen();
} }
@ -732,13 +725,22 @@ bool NativeWindowMac::IsFullscreen() const {
} }
void NativeWindowMac::SetBounds(const gfx::Rect& bounds, bool animate) { void NativeWindowMac::SetBounds(const gfx::Rect& bounds, bool animate) {
NSRect cocoa_bounds = NSMakeRect(bounds.x(), 0, // Do nothing if in fullscreen mode.
bounds.width(), if (IsFullscreen())
bounds.height()); return;
// Check size constraints since setFrame does not check it.
gfx::Size size = bounds.size();
size.SetToMax(GetMinimumSize());
gfx::Size max_size = GetMaximumSize();
if (!max_size.IsEmpty())
size.SetToMin(max_size);
NSRect cocoa_bounds = NSMakeRect(bounds.x(), 0, size.width(), size.height());
// Flip coordinates based on the primary screen. // Flip coordinates based on the primary screen.
NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
cocoa_bounds.origin.y = cocoa_bounds.origin.y =
NSHeight([screen frame]) - bounds.height() - bounds.y(); NSHeight([screen frame]) - size.height() - bounds.y();
[window_ setFrame:cocoa_bounds display:YES animate:animate]; [window_ setFrame:cocoa_bounds display:YES animate:animate];
} }
@ -790,13 +792,13 @@ bool NativeWindowMac::IsResizable() {
void NativeWindowMac::SetAspectRatio(double aspect_ratio, void NativeWindowMac::SetAspectRatio(double aspect_ratio,
const gfx::Size& extra_size) { const gfx::Size& extra_size) {
NativeWindow::SetAspectRatio(aspect_ratio, extra_size); NativeWindow::SetAspectRatio(aspect_ratio, extra_size);
// Reset the behaviour to default if aspect_ratio is set to 0 or less. // Reset the behaviour to default if aspect_ratio is set to 0 or less.
if (aspect_ratio > 0.0) if (aspect_ratio > 0.0)
[window_ setAspectRatio:NSMakeSize(aspect_ratio, 1.0)]; [window_ setAspectRatio:NSMakeSize(aspect_ratio, 1.0)];
else else
[window_ setResizeIncrements:NSMakeSize(1.0, 1.0)]; [window_ setResizeIncrements:NSMakeSize(1.0, 1.0)];
} }
void NativeWindowMac::SetMovable(bool movable) { void NativeWindowMac::SetMovable(bool movable) {
@ -950,10 +952,6 @@ void NativeWindowMac::SetContentProtection(bool enable) {
: NSWindowSharingReadOnly]; : NSWindowSharingReadOnly];
} }
bool NativeWindowMac::HasModalDialog() {
return [window_ attachedSheet] != nil;
}
void NativeWindowMac::SetParentWindow(NativeWindow* parent) { void NativeWindowMac::SetParentWindow(NativeWindow* parent) {
if (is_modal()) if (is_modal())
return; return;
@ -1072,7 +1070,10 @@ void NativeWindowMac::UpdateDraggableRegions(
void NativeWindowMac::InstallView() { void NativeWindowMac::InstallView() {
// Make sure the bottom corner is rounded: http://crbug.com/396264. // Make sure the bottom corner is rounded: http://crbug.com/396264.
[[window_ contentView] setWantsLayer:YES]; // But do not enable it on OS X 10.9 for transparent window, otherwise a
// semi-transparent frame would show.
if (!(transparent() && base::mac::IsOSMavericks()))
[[window_ contentView] setWantsLayer:YES];
NSView* view = inspectable_web_contents()->GetView()->GetNativeView(); NSView* view = inspectable_web_contents()->GetView()->GetNativeView();
if (has_frame()) { if (has_frame()) {
@ -1092,6 +1093,9 @@ void NativeWindowMac::InstallView() {
[view setFrame:[content_view_ bounds]]; [view setFrame:[content_view_ bounds]];
[content_view_ addSubview:view]; [content_view_ addSubview:view];
// The fullscreen button should always be hidden for frameless window.
[[window_ standardWindowButton:NSWindowFullScreenButton] setHidden:YES];
if (title_bar_style_ != NORMAL) if (title_bar_style_ != NORMAL)
return; return;

View file

@ -23,6 +23,7 @@
#include "ui/aura/window_tree_host.h" #include "ui/aura/window_tree_host.h"
#include "ui/base/hit_test.h" #include "ui/base/hit_test.h"
#include "ui/gfx/image/image.h" #include "ui/gfx/image/image.h"
#include "ui/gfx/screen.h"
#include "ui/views/background.h" #include "ui/views/background.h"
#include "ui/views/controls/webview/unhandled_keyboard_event_handler.h" #include "ui/views/controls/webview/unhandled_keyboard_event_handler.h"
#include "ui/views/controls/webview/webview.h" #include "ui/views/controls/webview/webview.h"
@ -135,6 +136,10 @@ NativeWindowViews::NativeWindowViews(
menu_bar_autohide_(false), menu_bar_autohide_(false),
menu_bar_visible_(false), menu_bar_visible_(false),
menu_bar_alt_pressed_(false), menu_bar_alt_pressed_(false),
#if defined(OS_WIN)
enabled_a11y_support_(false),
thick_frame_(true),
#endif
keyboard_event_handler_(new views::UnhandledKeyboardEventHandler), keyboard_event_handler_(new views::UnhandledKeyboardEventHandler),
disable_count_(0), disable_count_(0),
use_content_size_(false), use_content_size_(false),
@ -152,6 +157,11 @@ NativeWindowViews::NativeWindowViews(
options.Get(options::kResizable, &resizable_); options.Get(options::kResizable, &resizable_);
options.Get(options::kMinimizable, &minimizable_); options.Get(options::kMinimizable, &minimizable_);
options.Get(options::kMaximizable, &maximizable_); options.Get(options::kMaximizable, &maximizable_);
// Transparent window must not have thick frame.
options.Get("thickFrame", &thick_frame_);
if (transparent())
thick_frame_ = false;
#endif #endif
if (enable_larger_than_screen()) if (enable_larger_than_screen())
@ -214,6 +224,9 @@ NativeWindowViews::NativeWindowViews(
bool fullscreen = false; bool fullscreen = false;
options.Get(options::kFullscreen, &fullscreen); options.Get(options::kFullscreen, &fullscreen);
std::string window_type;
options.Get(options::kType, &window_type);
#if defined(USE_X11) #if defined(USE_X11)
// Start monitoring window states. // Start monitoring window states.
window_state_watcher_.reset(new WindowStateWatcher(this)); window_state_watcher_.reset(new WindowStateWatcher(this));
@ -243,9 +256,6 @@ NativeWindowViews::NativeWindowViews(
state_atom_list.push_back(GetAtom("_NET_WM_STATE_FULLSCREEN")); state_atom_list.push_back(GetAtom("_NET_WM_STATE_FULLSCREEN"));
} }
std::string window_type;
options.Get(options::kType, &window_type);
if (parent) { if (parent) {
SetParentWindow(parent); SetParentWindow(parent);
// Force using dialog type for child window. // Force using dialog type for child window.
@ -269,13 +279,6 @@ NativeWindowViews::NativeWindowViews(
AddChildView(web_view_); AddChildView(web_view_);
#if defined(OS_WIN) #if defined(OS_WIN)
// Save initial window state.
if (fullscreen)
last_window_state_ = ui::SHOW_STATE_FULLSCREEN;
else
last_window_state_ = ui::SHOW_STATE_NORMAL;
last_normal_size_ = gfx::Size(widget_size_);
if (!has_frame()) { if (!has_frame()) {
// Set Window style so that we get a minimize and maximize animation when // Set Window style so that we get a minimize and maximize animation when
// frameless. // frameless.
@ -287,17 +290,18 @@ NativeWindowViews::NativeWindowViews(
if (maximizable_) if (maximizable_)
frame_style |= WS_MAXIMIZEBOX; frame_style |= WS_MAXIMIZEBOX;
// We should not show a frame for transparent window. // We should not show a frame for transparent window.
if (transparent()) if (!thick_frame_)
frame_style &= ~(WS_THICKFRAME | WS_CAPTION); frame_style &= ~(WS_THICKFRAME | WS_CAPTION);
::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, frame_style); ::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, frame_style);
} }
if (transparent()) { LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE);
// Transparent window on Windows has to have WS_EX_COMPOSITED style. // Window without thick frame has to have WS_EX_COMPOSITED style.
LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE); if (!thick_frame_)
ex_style |= WS_EX_COMPOSITED; ex_style |= WS_EX_COMPOSITED;
::SetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE, ex_style); if (window_type == "toolbar")
} ex_style |= WS_EX_TOOLWINDOW;
::SetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE, ex_style);
#endif #endif
// TODO(zcbenz): This was used to force using native frame on Windows 2003, we // TODO(zcbenz): This was used to force using native frame on Windows 2003, we
@ -315,6 +319,15 @@ NativeWindowViews::NativeWindowViews(
window_->CenterWindow(size); window_->CenterWindow(size);
Layout(); Layout();
#if defined(OS_WIN)
// Save initial window state.
if (fullscreen)
last_window_state_ = ui::SHOW_STATE_FULLSCREEN;
else
last_window_state_ = ui::SHOW_STATE_NORMAL;
last_normal_bounds_ = GetBounds();
#endif
} }
NativeWindowViews::~NativeWindowViews() { NativeWindowViews::~NativeWindowViews() {
@ -410,6 +423,17 @@ bool NativeWindowViews::IsEnabled() {
} }
void NativeWindowViews::Maximize() { void NativeWindowViews::Maximize() {
#if defined(OS_WIN)
// For window without WS_THICKFRAME style, we can not call Maximize().
if (!thick_frame_) {
restore_bounds_ = GetBounds();
auto display =
gfx::Screen::GetScreen()->GetDisplayNearestPoint(GetPosition());
SetBounds(display.work_area(), false);
return;
}
#endif
if (IsVisible()) if (IsVisible())
window_->Maximize(); window_->Maximize();
else else
@ -418,6 +442,13 @@ void NativeWindowViews::Maximize() {
} }
void NativeWindowViews::Unmaximize() { void NativeWindowViews::Unmaximize() {
#if defined(OS_WIN)
if (!thick_frame_) {
SetBounds(restore_bounds_, false);
return;
}
#endif
window_->Restore(); window_->Restore();
} }
@ -454,6 +485,20 @@ void NativeWindowViews::SetFullScreen(bool fullscreen) {
last_window_state_ = ui::SHOW_STATE_NORMAL; last_window_state_ = ui::SHOW_STATE_NORMAL;
NotifyWindowLeaveFullScreen(); NotifyWindowLeaveFullScreen();
} }
// For window without WS_THICKFRAME style, we can not call SetFullscreen().
if (!thick_frame_) {
if (fullscreen) {
restore_bounds_ = GetBounds();
auto display =
gfx::Screen::GetScreen()->GetDisplayNearestPoint(GetPosition());
SetBounds(display.bounds(), false);
} else {
SetBounds(restore_bounds_, false);
}
return;
}
// We set the new value after notifying, so we can handle the size event // We set the new value after notifying, so we can handle the size event
// correctly. // correctly.
window_->SetFullscreen(fullscreen); window_->SetFullscreen(fullscreen);
@ -463,6 +508,12 @@ void NativeWindowViews::SetFullScreen(bool fullscreen) {
else else
window_->native_widget_private()->ShowWithWindowState( window_->native_widget_private()->ShowWithWindowState(
ui::SHOW_STATE_FULLSCREEN); ui::SHOW_STATE_FULLSCREEN);
// Auto-hide menubar when in fullscreen.
if (fullscreen)
SetMenuBarVisibility(false);
else
SetMenuBarVisibility(!menu_bar_autohide_);
#endif #endif
} }
@ -470,8 +521,7 @@ bool NativeWindowViews::IsFullscreen() const {
return window_->IsFullscreen(); return window_->IsFullscreen();
} }
void NativeWindowViews::SetBounds(const gfx::Rect& bounds, void NativeWindowViews::SetBounds(const gfx::Rect& bounds, bool animate) {
bool animate = false) {
#if defined(USE_X11) #if defined(USE_X11)
// On Linux the minimum and maximum size should be updated with window size // On Linux the minimum and maximum size should be updated with window size
// when window is not resizable. // when window is not resizable.
@ -517,7 +567,7 @@ void NativeWindowViews::SetContentSizeConstraints(
void NativeWindowViews::SetResizable(bool resizable) { void NativeWindowViews::SetResizable(bool resizable) {
#if defined(OS_WIN) #if defined(OS_WIN)
if (!transparent()) if (thick_frame_)
FlipWindowStyle(GetAcceleratedWidget(), resizable, WS_THICKFRAME); FlipWindowStyle(GetAcceleratedWidget(), resizable, WS_THICKFRAME);
#elif defined(USE_X11) #elif defined(USE_X11)
if (resizable != resizable_) { if (resizable != resizable_) {
@ -540,7 +590,11 @@ void NativeWindowViews::SetResizable(bool resizable) {
bool NativeWindowViews::IsResizable() { bool NativeWindowViews::IsResizable() {
#if defined(OS_WIN) #if defined(OS_WIN)
return ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_THICKFRAME; if (thick_frame_) {
return ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_THICKFRAME;
} else {
return CanResize();
}
#else #else
return CanResize(); return CanResize();
#endif #endif
@ -752,7 +806,7 @@ void NativeWindowViews::SetFocusable(bool focusable) {
#endif #endif
} }
void NativeWindowViews::SetMenu(ui::MenuModel* menu_model) { void NativeWindowViews::SetMenu(AtomMenuModel* menu_model) {
if (menu_model == nullptr) { if (menu_model == nullptr) {
// Remove accelerators // Remove accelerators
accelerator_table_.clear(); accelerator_table_.clear();
@ -1188,7 +1242,7 @@ bool NativeWindowViews::AcceleratorPressed(const ui::Accelerator& accelerator) {
&accelerator_table_, accelerator); &accelerator_table_, accelerator);
} }
void NativeWindowViews::RegisterAccelerators(ui::MenuModel* menu_model) { void NativeWindowViews::RegisterAccelerators(AtomMenuModel* menu_model) {
// Clear previous accelerators. // Clear previous accelerators.
views::FocusManager* focus_manager = GetFocusManager(); views::FocusManager* focus_manager = GetFocusManager();
accelerator_table_.clear(); accelerator_table_.clear();

View file

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

View file

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

View file

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

View file

@ -111,7 +111,7 @@ void URLRequestAsarJob::Start() {
if (rv != net::ERR_IO_PENDING) if (rv != net::ERR_IO_PENDING)
DidOpen(rv); DidOpen(rv);
} else if (type_ == TYPE_FILE) { } else if (type_ == TYPE_FILE) {
FileMetaInfo* meta_info = new FileMetaInfo(); auto* meta_info = new FileMetaInfo();
file_task_runner_->PostTaskAndReply( file_task_runner_->PostTaskAndReply(
FROM_HERE, FROM_HERE,
base::Bind(&URLRequestAsarJob::FetchMetaInfo, file_path_, base::Bind(&URLRequestAsarJob::FetchMetaInfo, file_path_,
@ -224,7 +224,7 @@ int URLRequestAsarJob::GetResponseCode() const {
void URLRequestAsarJob::GetResponseInfo(net::HttpResponseInfo* info) { void URLRequestAsarJob::GetResponseInfo(net::HttpResponseInfo* info) {
std::string status("HTTP/1.1 200 OK"); std::string status("HTTP/1.1 200 OK");
net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status); auto* headers = new net::HttpResponseHeaders(status);
headers->AddHeader(atom::kCORSHeader); headers->AddHeader(atom::kCORSHeader);
info->headers = headers; info->headers = headers;
@ -338,7 +338,7 @@ void URLRequestAsarJob::DidRead(scoped_refptr<net::IOBuffer> buf, int result) {
DCHECK_GE(remaining_bytes_, 0); DCHECK_GE(remaining_bytes_, 0);
} }
buf = NULL; buf = nullptr;
ReadRawDataComplete(result); ReadRawDataComplete(result);
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -29,9 +29,25 @@ base::string16 AtomMenuModel::GetRoleAt(int index) {
return base::string16(); return base::string16();
} }
bool AtomMenuModel::GetAcceleratorAtWithParams(
int index,
bool use_default_accelerator,
ui::Accelerator* accelerator) const {
if (delegate_) {
return delegate_->GetAcceleratorForCommandIdWithParams(
GetCommandIdAt(index), use_default_accelerator, accelerator);
}
return false;
}
void AtomMenuModel::MenuClosed() { void AtomMenuModel::MenuClosed() {
ui::SimpleMenuModel::MenuClosed(); ui::SimpleMenuModel::MenuClosed();
FOR_EACH_OBSERVER(Observer, observers_, MenuClosed()); FOR_EACH_OBSERVER(Observer, observers_, MenuClosed());
} }
AtomMenuModel* AtomMenuModel::GetSubmenuModelAt(int index) {
return static_cast<AtomMenuModel*>(
ui::SimpleMenuModel::GetSubmenuModelAt(index));
}
} // namespace atom } // namespace atom

View file

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

View file

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

View file

@ -48,15 +48,11 @@ Role kRolesMap[] = {
@synthesize model = model_; @synthesize model = model_;
- (id)init { - (id)initWithModel:(atom::AtomMenuModel*)model useDefaultAccelerator:(BOOL)use {
if ((self = [super init]))
[self menu];
return self;
}
- (id)initWithModel:(ui::MenuModel*)model {
if ((self = [super init])) { if ((self = [super init])) {
model_ = model; model_ = model;
isMenuOpen_ = NO;
useDefaultAccelerator_ = use;
[self menu]; [self menu];
} }
return self; return self;
@ -73,7 +69,7 @@ Role kRolesMap[] = {
[super dealloc]; [super dealloc];
} }
- (void)populateWithModel:(ui::MenuModel*)model { - (void)populateWithModel:(atom::AtomMenuModel*)model {
if (!menu_) if (!menu_)
return; return;
@ -82,7 +78,7 @@ Role kRolesMap[] = {
const int count = model->GetItemCount(); const int count = model->GetItemCount();
for (int index = 0; index < count; index++) { for (int index = 0; index < count; index++) {
if (model->GetTypeAt(index) == ui::MenuModel::TYPE_SEPARATOR) if (model->GetTypeAt(index) == atom::AtomMenuModel::TYPE_SEPARATOR)
[self addSeparatorToMenu:menu_ atIndex:index]; [self addSeparatorToMenu:menu_ atIndex:index];
else else
[self addItemToMenu:menu_ atIndex:index fromModel:model]; [self addItemToMenu:menu_ atIndex:index fromModel:model];
@ -99,12 +95,12 @@ Role kRolesMap[] = {
// Creates a NSMenu from the given model. If the model has submenus, this can // Creates a NSMenu from the given model. If the model has submenus, this can
// be invoked recursively. // be invoked recursively.
- (NSMenu*)menuFromModel:(ui::MenuModel*)model { - (NSMenu*)menuFromModel:(atom::AtomMenuModel*)model {
NSMenu* menu = [[[NSMenu alloc] initWithTitle:@""] autorelease]; NSMenu* menu = [[[NSMenu alloc] initWithTitle:@""] autorelease];
const int count = model->GetItemCount(); const int count = model->GetItemCount();
for (int index = 0; index < count; index++) { for (int index = 0; index < count; index++) {
if (model->GetTypeAt(index) == ui::MenuModel::TYPE_SEPARATOR) if (model->GetTypeAt(index) == atom::AtomMenuModel::TYPE_SEPARATOR)
[self addSeparatorToMenu:menu atIndex:index]; [self addSeparatorToMenu:menu atIndex:index];
else else
[self addItemToMenu:menu atIndex:index fromModel:model]; [self addItemToMenu:menu atIndex:index fromModel:model];
@ -126,9 +122,7 @@ Role kRolesMap[] = {
// associated with the entry in the model identified by |modelIndex|. // associated with the entry in the model identified by |modelIndex|.
- (void)addItemToMenu:(NSMenu*)menu - (void)addItemToMenu:(NSMenu*)menu
atIndex:(NSInteger)index atIndex:(NSInteger)index
fromModel:(ui::MenuModel*)ui_model { fromModel:(atom::AtomMenuModel*)model {
atom::AtomMenuModel* model = static_cast<atom::AtomMenuModel*>(ui_model);
base::string16 label16 = model->GetLabelAt(index); base::string16 label16 = model->GetLabelAt(index);
NSString* label = l10n_util::FixUpWindowsStyleLabel(label16); NSString* label = l10n_util::FixUpWindowsStyleLabel(label16);
base::scoped_nsobject<NSMenuItem> item( base::scoped_nsobject<NSMenuItem> item(
@ -141,12 +135,13 @@ Role kRolesMap[] = {
if (model->GetIconAt(index, &icon) && !icon.IsEmpty()) if (model->GetIconAt(index, &icon) && !icon.IsEmpty())
[item setImage:icon.ToNSImage()]; [item setImage:icon.ToNSImage()];
ui::MenuModel::ItemType type = model->GetTypeAt(index); atom::AtomMenuModel::ItemType type = model->GetTypeAt(index);
if (type == ui::MenuModel::TYPE_SUBMENU) { if (type == atom::AtomMenuModel::TYPE_SUBMENU) {
// Recursively build a submenu from the sub-model at this index. // Recursively build a submenu from the sub-model at this index.
[item setTarget:nil]; [item setTarget:nil];
[item setAction:nil]; [item setAction:nil];
ui::MenuModel* submenuModel = model->GetSubmenuModelAt(index); atom::AtomMenuModel* submenuModel = static_cast<atom::AtomMenuModel*>(
model->GetSubmenuModelAt(index));
NSMenu* submenu = [self menuFromModel:submenuModel]; NSMenu* submenu = [self menuFromModel:submenuModel];
[submenu setTitle:[item title]]; [submenu setTitle:[item title]];
[item setSubmenu:submenu]; [item setSubmenu:submenu];
@ -170,7 +165,8 @@ Role kRolesMap[] = {
NSValue* modelObject = [NSValue valueWithPointer:model]; NSValue* modelObject = [NSValue valueWithPointer:model];
[item setRepresentedObject:modelObject]; // Retains |modelObject|. [item setRepresentedObject:modelObject]; // Retains |modelObject|.
ui::Accelerator accelerator; ui::Accelerator accelerator;
if (model->GetAcceleratorAt(index, &accelerator)) { if (model->GetAcceleratorAtWithParams(
index, useDefaultAccelerator_, &accelerator)) {
const ui::PlatformAcceleratorCocoa* platformAccelerator = const ui::PlatformAcceleratorCocoa* platformAccelerator =
static_cast<const ui::PlatformAcceleratorCocoa*>( static_cast<const ui::PlatformAcceleratorCocoa*>(
accelerator.platform_accelerator()); accelerator.platform_accelerator());
@ -206,8 +202,8 @@ Role kRolesMap[] = {
return NO; return NO;
NSInteger modelIndex = [item tag]; NSInteger modelIndex = [item tag];
ui::MenuModel* model = atom::AtomMenuModel* model =
static_cast<ui::MenuModel*>( static_cast<atom::AtomMenuModel*>(
[[(id)item representedObject] pointerValue]); [[(id)item representedObject] pointerValue]);
DCHECK(model); DCHECK(model);
if (model) { if (model) {
@ -234,8 +230,8 @@ Role kRolesMap[] = {
// item chosen. // item chosen.
- (void)itemSelected:(id)sender { - (void)itemSelected:(id)sender {
NSInteger modelIndex = [sender tag]; NSInteger modelIndex = [sender tag];
ui::MenuModel* model = atom::AtomMenuModel* model =
static_cast<ui::MenuModel*>( static_cast<atom::AtomMenuModel*>(
[[sender representedObject] pointerValue]); [[sender representedObject] pointerValue]);
DCHECK(model); DCHECK(model);
if (model) { if (model) {

View file

@ -23,10 +23,11 @@ typedef std::pair<std::string, std::vector<std::string> > Filter;
typedef std::vector<Filter> Filters; typedef std::vector<Filter> Filters;
enum FileDialogProperty { enum FileDialogProperty {
FILE_DIALOG_OPEN_FILE = 1 << 0, FILE_DIALOG_OPEN_FILE = 1 << 0,
FILE_DIALOG_OPEN_DIRECTORY = 1 << 1, FILE_DIALOG_OPEN_DIRECTORY = 1 << 1,
FILE_DIALOG_MULTI_SELECTIONS = 1 << 2, FILE_DIALOG_MULTI_SELECTIONS = 1 << 2,
FILE_DIALOG_CREATE_DIRECTORY = 1 << 3, FILE_DIALOG_CREATE_DIRECTORY = 1 << 3,
FILE_DIALOG_SHOW_HIDDEN_FILES = 1 << 4,
}; };
typedef base::Callback<void( typedef base::Callback<void(

View file

@ -5,6 +5,7 @@
#include "atom/browser/ui/file_dialog.h" #include "atom/browser/ui/file_dialog.h"
#include "atom/browser/native_window_views.h" #include "atom/browser/native_window_views.h"
#include "atom/browser/unresponsive_suppressor.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/files/file_util.h" #include "base/files/file_util.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
@ -41,7 +42,6 @@ class FileChooserDialog {
const base::FilePath& default_path, const base::FilePath& default_path,
const Filters& filters) const Filters& filters)
: parent_(static_cast<atom::NativeWindowViews*>(parent_window)), : parent_(static_cast<atom::NativeWindowViews*>(parent_window)),
dialog_scope_(parent_window),
filters_(filters) { filters_(filters) {
const char* confirm_text = GTK_STOCK_OK; const char* confirm_text = GTK_STOCK_OK;
@ -87,12 +87,19 @@ class FileChooserDialog {
AddFilters(filters); AddFilters(filters);
} }
virtual ~FileChooserDialog() { ~FileChooserDialog() {
gtk_widget_destroy(dialog_); gtk_widget_destroy(dialog_);
if (parent_) if (parent_)
parent_->SetEnabled(true); parent_->SetEnabled(true);
} }
void SetupProperties(int properties) {
if (properties & FILE_DIALOG_MULTI_SELECTIONS)
gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog()), TRUE);
if (properties & FILE_DIALOG_SHOW_HIDDEN_FILES)
g_object_set(dialog(), "show-hidden", TRUE, NULL);
}
void RunAsynchronous() { void RunAsynchronous() {
g_signal_connect(dialog_, "delete-event", g_signal_connect(dialog_, "delete-event",
G_CALLBACK(gtk_widget_hide_on_delete), NULL); G_CALLBACK(gtk_widget_hide_on_delete), NULL);
@ -146,7 +153,7 @@ class FileChooserDialog {
base::FilePath AddExtensionForFilename(const gchar* filename) const; base::FilePath AddExtensionForFilename(const gchar* filename) const;
atom::NativeWindowViews* parent_; atom::NativeWindowViews* parent_;
atom::NativeWindow::DialogScope dialog_scope_; atom::UnresponsiveSuppressor unresponsive_suppressor_;
GtkWidget* dialog_; GtkWidget* dialog_;
@ -235,9 +242,7 @@ bool ShowOpenDialog(atom::NativeWindow* parent_window,
action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER; action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
FileChooserDialog open_dialog(action, parent_window, title, button_label, FileChooserDialog open_dialog(action, parent_window, title, button_label,
default_path, filters); default_path, filters);
if (properties & FILE_DIALOG_MULTI_SELECTIONS) open_dialog.SetupProperties(properties);
gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(open_dialog.dialog()),
TRUE);
gtk_widget_show_all(open_dialog.dialog()); gtk_widget_show_all(open_dialog.dialog());
int response = gtk_dialog_run(GTK_DIALOG(open_dialog.dialog())); int response = gtk_dialog_run(GTK_DIALOG(open_dialog.dialog()));
@ -261,10 +266,7 @@ void ShowOpenDialog(atom::NativeWindow* parent_window,
action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER; action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
FileChooserDialog* open_dialog = new FileChooserDialog( FileChooserDialog* open_dialog = new FileChooserDialog(
action, parent_window, title, button_label, default_path, filters); action, parent_window, title, button_label, default_path, filters);
if (properties & FILE_DIALOG_MULTI_SELECTIONS) open_dialog->SetupProperties(properties);
gtk_file_chooser_set_select_multiple(
GTK_FILE_CHOOSER(open_dialog->dialog()), TRUE);
open_dialog->RunOpenAsynchronous(callback); open_dialog->RunOpenAsynchronous(callback);
} }

View file

@ -86,6 +86,8 @@ void SetupDialogForProperties(NSOpenPanel* dialog, int properties) {
[dialog setCanCreateDirectories:YES]; [dialog setCanCreateDirectories:YES];
if (properties & FILE_DIALOG_MULTI_SELECTIONS) if (properties & FILE_DIALOG_MULTI_SELECTIONS)
[dialog setAllowsMultipleSelection:YES]; [dialog setAllowsMultipleSelection:YES];
if (properties & FILE_DIALOG_SHOW_HIDDEN_FILES)
[dialog setShowsHiddenFiles:YES];
} }
// Run modal dialog with parent window and return user's choice. // Run modal dialog with parent window and return user's choice.

View file

@ -10,6 +10,7 @@
#include <shlobj.h> #include <shlobj.h>
#include "atom/browser/native_window_views.h" #include "atom/browser/native_window_views.h"
#include "atom/browser/unresponsive_suppressor.h"
#include "base/files/file_util.h" #include "base/files/file_util.h"
#include "base/i18n/case_conversion.h" #include "base/i18n/case_conversion.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
@ -108,7 +109,7 @@ class FileDialog {
} }
bool Show(atom::NativeWindow* parent_window) { bool Show(atom::NativeWindow* parent_window) {
atom::NativeWindow::DialogScope dialog_scope(parent_window); atom::UnresponsiveSuppressor suppressor;
HWND window = parent_window ? static_cast<atom::NativeWindowViews*>( HWND window = parent_window ? static_cast<atom::NativeWindowViews*>(
parent_window)->GetAcceleratedWidget() : parent_window)->GetAcceleratedWidget() :
NULL; NULL;
@ -201,6 +202,8 @@ bool ShowOpenDialog(atom::NativeWindow* parent_window,
options |= FOS_PICKFOLDERS; options |= FOS_PICKFOLDERS;
if (properties & FILE_DIALOG_MULTI_SELECTIONS) if (properties & FILE_DIALOG_MULTI_SELECTIONS)
options |= FOS_ALLOWMULTISELECT; options |= FOS_ALLOWMULTISELECT;
if (properties & FILE_DIALOG_SHOW_HIDDEN_FILES)
options |= FOS_FORCESHOWHIDDEN;
FileDialog<CShellFileOpenDialog> open_dialog( FileDialog<CShellFileOpenDialog> open_dialog(
default_path, title, button_label, filters, options); default_path, title, button_label, filters, options);

View file

@ -6,6 +6,7 @@
#include "atom/browser/browser.h" #include "atom/browser/browser.h"
#include "atom/browser/native_window_views.h" #include "atom/browser/native_window_views.h"
#include "atom/browser/unresponsive_suppressor.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
@ -35,8 +36,7 @@ class GtkMessageBox {
const std::string& message, const std::string& message,
const std::string& detail, const std::string& detail,
const gfx::ImageSkia& icon) const gfx::ImageSkia& icon)
: dialog_scope_(parent_window), : cancel_id_(cancel_id),
cancel_id_(cancel_id),
parent_(static_cast<NativeWindowViews*>(parent_window)) { parent_(static_cast<NativeWindowViews*>(parent_window)) {
// Create dialog. // Create dialog.
dialog_ = gtk_message_dialog_new( dialog_ = gtk_message_dialog_new(
@ -147,7 +147,7 @@ class GtkMessageBox {
CHROMEGTK_CALLBACK_1(GtkMessageBox, void, OnResponseDialog, int); CHROMEGTK_CALLBACK_1(GtkMessageBox, void, OnResponseDialog, int);
private: private:
atom::NativeWindow::DialogScope dialog_scope_; atom::UnresponsiveSuppressor unresponsive_suppressor_;
// The id to return when the dialog is closed without pressing buttons. // The id to return when the dialog is closed without pressing buttons.
int cancel_id_; int cancel_id_;

View file

@ -12,6 +12,7 @@
#include "atom/browser/browser.h" #include "atom/browser/browser.h"
#include "atom/browser/native_window_views.h" #include "atom/browser/native_window_views.h"
#include "atom/browser/unresponsive_suppressor.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
@ -198,7 +199,7 @@ int ShowMessageBox(NativeWindow* parent,
static_cast<atom::NativeWindowViews*>(parent)->GetAcceleratedWidget() : static_cast<atom::NativeWindowViews*>(parent)->GetAcceleratedWidget() :
NULL; NULL;
NativeWindow::DialogScope dialog_scope(parent); atom::UnresponsiveSuppressor suppressor;
return ShowMessageBoxUTF16(hwnd_parent, return ShowMessageBoxUTF16(hwnd_parent,
type, type,
utf16_buttons, utf16_buttons,
@ -239,6 +240,7 @@ void ShowMessageBox(NativeWindow* parent,
} }
void ShowErrorBox(const base::string16& title, const base::string16& content) { void ShowErrorBox(const base::string16& title, const base::string16& content) {
atom::UnresponsiveSuppressor suppressor;
ShowMessageBoxUTF16(NULL, MESSAGE_BOX_TYPE_ERROR, {}, -1, 0, 0, L"Error", ShowMessageBoxUTF16(NULL, MESSAGE_BOX_TYPE_ERROR, {}, -1, 0, 0, L"Error",
title, content, gfx::ImageSkia()); title, content, gfx::ImageSkia());
} }

View file

@ -27,7 +27,7 @@ void TrayIcon::DisplayBalloon(ImageType icon,
} }
void TrayIcon::PopUpContextMenu(const gfx::Point& pos, void TrayIcon::PopUpContextMenu(const gfx::Point& pos,
ui::SimpleMenuModel* menu_model) { AtomMenuModel* menu_model) {
} }
gfx::Rect TrayIcon::GetBounds() { gfx::Rect TrayIcon::GetBounds() {
@ -68,6 +68,10 @@ void TrayIcon::NotifyDropFiles(const std::vector<std::string>& files) {
FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnDropFiles(files)); FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnDropFiles(files));
} }
void TrayIcon::NotifyDropText(const std::string& text) {
FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnDropText(text));
}
void TrayIcon::NotifyDragEntered() { void TrayIcon::NotifyDragEntered() {
FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnDragEntered()); FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnDragEntered());
} }

View file

@ -8,9 +8,9 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "atom/browser/ui/atom_menu_model.h"
#include "atom/browser/ui/tray_icon_observer.h" #include "atom/browser/ui/tray_icon_observer.h"
#include "base/observer_list.h" #include "base/observer_list.h"
#include "ui/base/models/simple_menu_model.h"
#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect.h"
namespace atom { namespace atom {
@ -55,10 +55,10 @@ class TrayIcon {
// Popups the menu. // Popups the menu.
virtual void PopUpContextMenu(const gfx::Point& pos, virtual void PopUpContextMenu(const gfx::Point& pos,
ui::SimpleMenuModel* menu_model); AtomMenuModel* menu_model);
// Set the context menu for this icon. // Set the context menu for this icon.
virtual void SetContextMenu(ui::SimpleMenuModel* menu_model) = 0; virtual void SetContextMenu(AtomMenuModel* menu_model) = 0;
// Returns the bounds of tray icon. // Returns the bounds of tray icon.
virtual gfx::Rect GetBounds(); virtual gfx::Rect GetBounds();
@ -75,6 +75,7 @@ class TrayIcon {
int modifiers = 0); int modifiers = 0);
void NotifyDrop(); void NotifyDrop();
void NotifyDropFiles(const std::vector<std::string>& files); void NotifyDropFiles(const std::vector<std::string>& files);
void NotifyDropText(const std::string& text);
void NotifyDragEntered(); void NotifyDragEntered();
void NotifyDragExited(); void NotifyDragExited();
void NotifyDragEnded(); void NotifyDragEnded();

View file

@ -9,7 +9,6 @@
#include <string> #include <string>
#include "atom/browser/ui/atom_menu_model.h"
#include "atom/browser/ui/tray_icon.h" #include "atom/browser/ui/tray_icon.h"
#include "base/mac/scoped_nsobject.h" #include "base/mac/scoped_nsobject.h"
@ -30,8 +29,8 @@ class TrayIconCocoa : public TrayIcon,
void SetTitle(const std::string& title) override; void SetTitle(const std::string& title) override;
void SetHighlightMode(bool highlight) override; void SetHighlightMode(bool highlight) override;
void PopUpContextMenu(const gfx::Point& pos, void PopUpContextMenu(const gfx::Point& pos,
ui::SimpleMenuModel* menu_model) override; AtomMenuModel* menu_model) override;
void SetContextMenu(ui::SimpleMenuModel* menu_model) override; void SetContextMenu(AtomMenuModel* menu_model) override;
gfx::Rect GetBounds() override; gfx::Rect GetBounds() override;
protected: protected:

View file

@ -44,7 +44,10 @@ const CGFloat kVerticalTitleMargin = 2;
inMouseEventSequence_ = NO; inMouseEventSequence_ = NO;
if ((self = [super initWithFrame: CGRectZero])) { if ((self = [super initWithFrame: CGRectZero])) {
[self registerForDraggedTypes: @[NSFilenamesPboardType]]; [self registerForDraggedTypes: @[
NSFilenamesPboardType,
NSStringPboardType,
]];
// Create the status item. // Create the status item.
NSStatusItem * item = [[NSStatusBar systemStatusBar] NSStatusItem * item = [[NSStatusBar systemStatusBar]
@ -249,11 +252,12 @@ const CGFloat kVerticalTitleMargin = 2;
[self setNeedsDisplay:YES]; [self setNeedsDisplay:YES];
} }
- (void)popUpContextMenu:(ui::SimpleMenuModel*)menu_model { - (void)popUpContextMenu:(atom::AtomMenuModel*)menu_model {
// Show a custom menu. // Show a custom menu.
if (menu_model) { if (menu_model) {
base::scoped_nsobject<AtomMenuController> menuController( base::scoped_nsobject<AtomMenuController> menuController(
[[AtomMenuController alloc] initWithModel:menu_model]); [[AtomMenuController alloc] initWithModel:menu_model
useDefaultAccelerator:NO]);
forceHighlight_ = YES; // Should highlight when showing menu. forceHighlight_ = YES; // Should highlight when showing menu.
[self setNeedsDisplay:YES]; [self setNeedsDisplay:YES];
[statusItem_ popUpStatusItemMenu:[menuController menu]]; [statusItem_ popUpStatusItemMenu:[menuController menu]];
@ -306,7 +310,12 @@ const CGFloat kVerticalTitleMargin = 2;
dropFiles.push_back(base::SysNSStringToUTF8(file)); dropFiles.push_back(base::SysNSStringToUTF8(file));
trayIcon_->NotifyDropFiles(dropFiles); trayIcon_->NotifyDropFiles(dropFiles);
return YES; return YES;
} else if ([[pboard types] containsObject:NSStringPboardType]) {
NSString* dropText = [pboard stringForType:NSStringPboardType];
trayIcon_->NotifyDropText(base::SysNSStringToUTF8(dropText));
return YES;
} }
return NO; return NO;
} }
@ -365,18 +374,19 @@ void TrayIconCocoa::SetHighlightMode(bool highlight) {
} }
void TrayIconCocoa::PopUpContextMenu(const gfx::Point& pos, void TrayIconCocoa::PopUpContextMenu(const gfx::Point& pos,
ui::SimpleMenuModel* menu_model) { AtomMenuModel* menu_model) {
[status_item_view_ popUpContextMenu:menu_model]; [status_item_view_ popUpContextMenu:menu_model];
} }
void TrayIconCocoa::SetContextMenu(ui::SimpleMenuModel* menu_model) { void TrayIconCocoa::SetContextMenu(AtomMenuModel* menu_model) {
// Substribe to MenuClosed event. // Substribe to MenuClosed event.
if (menu_model_) if (menu_model_)
menu_model_->RemoveObserver(this); menu_model_->RemoveObserver(this);
static_cast<AtomMenuModel*>(menu_model)->AddObserver(this); menu_model->AddObserver(this);
// Create native menu. // Create native menu.
menu_.reset([[AtomMenuController alloc] initWithModel:menu_model]); menu_.reset([[AtomMenuController alloc] initWithModel:menu_model
useDefaultAccelerator:NO]);
[status_item_view_ setMenuController:menu_.get()]; [status_item_view_ setMenuController:menu_.get()];
} }

View file

@ -50,7 +50,7 @@ void TrayIconGtk::SetToolTip(const std::string& tool_tip) {
icon_->SetToolTip(base::UTF8ToUTF16(tool_tip)); icon_->SetToolTip(base::UTF8ToUTF16(tool_tip));
} }
void TrayIconGtk::SetContextMenu(ui::SimpleMenuModel* menu_model) { void TrayIconGtk::SetContextMenu(AtomMenuModel* menu_model) {
icon_->UpdatePlatformContextMenu(menu_model); icon_->UpdatePlatformContextMenu(menu_model);
} }

View file

@ -25,7 +25,7 @@ class TrayIconGtk : public TrayIcon,
// TrayIcon: // TrayIcon:
void SetImage(const gfx::Image& image) override; void SetImage(const gfx::Image& image) override;
void SetToolTip(const std::string& tool_tip) override; void SetToolTip(const std::string& tool_tip) override;
void SetContextMenu(ui::SimpleMenuModel* menu_model) override; void SetContextMenu(AtomMenuModel* menu_model) override;
private: private:
// views::StatusIconLinux::Delegate: // views::StatusIconLinux::Delegate:

View file

@ -24,6 +24,7 @@ class TrayIconObserver {
virtual void OnRightClicked(const gfx::Rect& bounds, int modifiers) {} virtual void OnRightClicked(const gfx::Rect& bounds, int modifiers) {}
virtual void OnDrop() {} virtual void OnDrop() {}
virtual void OnDropFiles(const std::vector<std::string>& files) {} virtual void OnDropFiles(const std::vector<std::string>& files) {}
virtual void OnDropText(const std::string& text) {}
virtual void OnDragEntered() {} virtual void OnDragEntered() {}
virtual void OnDragExited() {} virtual void OnDragExited() {}
virtual void OnDragEnded() {} virtual void OnDragEnded() {}

View file

@ -16,6 +16,7 @@
#include <glib-object.h> #include <glib-object.h>
#include "atom/browser/native_window_views.h" #include "atom/browser/native_window_views.h"
#include "atom/browser/ui/atom_menu_model.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
@ -23,7 +24,6 @@
#include "ui/aura/window.h" #include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h" #include "ui/aura/window_tree_host.h"
#include "ui/base/accelerators/menu_label_accelerator_util_linux.h" #include "ui/base/accelerators/menu_label_accelerator_util_linux.h"
#include "ui/base/models/menu_model.h"
#include "ui/events/keycodes/keyboard_code_conversion_x.h" #include "ui/events/keycodes/keyboard_code_conversion_x.h"
// libdbusmenu-glib types // libdbusmenu-glib types
@ -141,8 +141,8 @@ void EnsureMethodsLoaded() {
dlsym(dbusmenu_lib, "dbusmenu_server_set_root")); dlsym(dbusmenu_lib, "dbusmenu_server_set_root"));
} }
ui::MenuModel* ModelForMenuItem(DbusmenuMenuitem* item) { AtomMenuModel* ModelForMenuItem(DbusmenuMenuitem* item) {
return reinterpret_cast<ui::MenuModel*>( return reinterpret_cast<AtomMenuModel*>(
g_object_get_data(G_OBJECT(item), "model")); g_object_get_data(G_OBJECT(item), "model"));
} }
@ -188,7 +188,7 @@ std::string GlobalMenuBarX11::GetPathForWindow(gfx::AcceleratedWidget xid) {
return base::StringPrintf("/com/canonical/menu/%lX", xid); return base::StringPrintf("/com/canonical/menu/%lX", xid);
} }
void GlobalMenuBarX11::SetMenu(ui::MenuModel* menu_model) { void GlobalMenuBarX11::SetMenu(AtomMenuModel* menu_model) {
if (!IsServerStarted()) if (!IsServerStarted())
return; return;
@ -218,14 +218,14 @@ void GlobalMenuBarX11::OnWindowUnmapped() {
GlobalMenuBarRegistrarX11::GetInstance()->OnWindowUnmapped(xid_); GlobalMenuBarRegistrarX11::GetInstance()->OnWindowUnmapped(xid_);
} }
void GlobalMenuBarX11::BuildMenuFromModel(ui::MenuModel* model, void GlobalMenuBarX11::BuildMenuFromModel(AtomMenuModel* model,
DbusmenuMenuitem* parent) { DbusmenuMenuitem* parent) {
for (int i = 0; i < model->GetItemCount(); ++i) { for (int i = 0; i < model->GetItemCount(); ++i) {
DbusmenuMenuitem* item = menuitem_new(); DbusmenuMenuitem* item = menuitem_new();
menuitem_property_set_bool(item, kPropertyVisible, model->IsVisibleAt(i)); menuitem_property_set_bool(item, kPropertyVisible, model->IsVisibleAt(i));
ui::MenuModel::ItemType type = model->GetTypeAt(i); AtomMenuModel::ItemType type = model->GetTypeAt(i);
if (type == ui::MenuModel::TYPE_SEPARATOR) { if (type == AtomMenuModel::TYPE_SEPARATOR) {
menuitem_property_set(item, kPropertyType, kTypeSeparator); menuitem_property_set(item, kPropertyType, kTypeSeparator);
} else { } else {
std::string label = ui::ConvertAcceleratorsFromWindowsStyle( std::string label = ui::ConvertAcceleratorsFromWindowsStyle(
@ -236,22 +236,22 @@ void GlobalMenuBarX11::BuildMenuFromModel(ui::MenuModel* model,
g_object_set_data(G_OBJECT(item), "model", model); g_object_set_data(G_OBJECT(item), "model", model);
SetMenuItemID(item, i); SetMenuItemID(item, i);
if (type == ui::MenuModel::TYPE_SUBMENU) { if (type == AtomMenuModel::TYPE_SUBMENU) {
menuitem_property_set(item, kPropertyChildrenDisplay, kDisplaySubmenu); menuitem_property_set(item, kPropertyChildrenDisplay, kDisplaySubmenu);
g_signal_connect(item, "about-to-show", g_signal_connect(item, "about-to-show",
G_CALLBACK(OnSubMenuShowThunk), this); G_CALLBACK(OnSubMenuShowThunk), this);
} else { } else {
ui::Accelerator accelerator; ui::Accelerator accelerator;
if (model->GetAcceleratorAt(i, &accelerator)) if (model->GetAcceleratorAtWithParams(i, true, &accelerator))
RegisterAccelerator(item, accelerator); RegisterAccelerator(item, accelerator);
g_signal_connect(item, "item-activated", g_signal_connect(item, "item-activated",
G_CALLBACK(OnItemActivatedThunk), this); G_CALLBACK(OnItemActivatedThunk), this);
if (type == ui::MenuModel::TYPE_CHECK || if (type == AtomMenuModel::TYPE_CHECK ||
type == ui::MenuModel::TYPE_RADIO) { type == AtomMenuModel::TYPE_RADIO) {
menuitem_property_set(item, kPropertyToggleType, menuitem_property_set(item, kPropertyToggleType,
type == ui::MenuModel::TYPE_CHECK ? kToggleCheck : kToggleRadio); type == AtomMenuModel::TYPE_CHECK ? kToggleCheck : kToggleRadio);
menuitem_property_set_int(item, kPropertyToggleState, menuitem_property_set_int(item, kPropertyToggleState,
model->IsItemCheckedAt(i)); model->IsItemCheckedAt(i));
} }
@ -296,14 +296,14 @@ void GlobalMenuBarX11::RegisterAccelerator(DbusmenuMenuitem* item,
void GlobalMenuBarX11::OnItemActivated(DbusmenuMenuitem* item, void GlobalMenuBarX11::OnItemActivated(DbusmenuMenuitem* item,
unsigned int timestamp) { unsigned int timestamp) {
int id; int id;
ui::MenuModel* model = ModelForMenuItem(item); AtomMenuModel* model = ModelForMenuItem(item);
if (model && GetMenuItemID(item, &id)) if (model && GetMenuItemID(item, &id))
model->ActivatedAt(id, 0); model->ActivatedAt(id, 0);
} }
void GlobalMenuBarX11::OnSubMenuShow(DbusmenuMenuitem* item) { void GlobalMenuBarX11::OnSubMenuShow(DbusmenuMenuitem* item) {
int id; int id;
ui::MenuModel* model = ModelForMenuItem(item); AtomMenuModel* model = ModelForMenuItem(item);
if (!model || !GetMenuItemID(item, &id)) if (!model || !GetMenuItemID(item, &id))
return; return;

View file

@ -7,6 +7,7 @@
#include <string> #include <string>
#include "atom/browser/ui/atom_menu_model.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "ui/base/glib/glib_signal.h" #include "ui/base/glib/glib_signal.h"
@ -17,7 +18,6 @@ typedef struct _DbusmenuServer DbusmenuServer;
namespace ui { namespace ui {
class Accelerator; class Accelerator;
class MenuModel;
} }
namespace atom { namespace atom {
@ -43,7 +43,7 @@ class GlobalMenuBarX11 {
// Creates the object path for DbusmenuServer which is attached to |xid|. // Creates the object path for DbusmenuServer which is attached to |xid|.
static std::string GetPathForWindow(gfx::AcceleratedWidget xid); static std::string GetPathForWindow(gfx::AcceleratedWidget xid);
void SetMenu(ui::MenuModel* menu_model); void SetMenu(AtomMenuModel* menu_model);
bool IsServerStarted() const; bool IsServerStarted() const;
// Called by NativeWindow when it show/hides. // Called by NativeWindow when it show/hides.
@ -55,7 +55,7 @@ class GlobalMenuBarX11 {
void InitServer(gfx::AcceleratedWidget xid); void InitServer(gfx::AcceleratedWidget xid);
// Create a menu from menu model. // Create a menu from menu model.
void BuildMenuFromModel(ui::MenuModel* model, DbusmenuMenuitem* parent); void BuildMenuFromModel(AtomMenuModel* model, DbusmenuMenuitem* parent);
// Sets the accelerator for |item|. // Sets the accelerator for |item|.
void RegisterAccelerator(DbusmenuMenuitem* item, void RegisterAccelerator(DbusmenuMenuitem* item,

View file

@ -58,7 +58,7 @@ MenuBar::MenuBar()
MenuBar::~MenuBar() { MenuBar::~MenuBar() {
} }
void MenuBar::SetMenu(ui::MenuModel* model) { void MenuBar::SetMenu(AtomMenuModel* model) {
menu_model_ = model; menu_model_ = model;
RemoveAllChildViews(true); RemoveAllChildViews(true);
@ -105,7 +105,7 @@ int MenuBar::GetItemCount() const {
} }
bool MenuBar::GetMenuButtonFromScreenPoint(const gfx::Point& point, bool MenuBar::GetMenuButtonFromScreenPoint(const gfx::Point& point,
ui::MenuModel** menu_model, AtomMenuModel** menu_model,
views::MenuButton** button) { views::MenuButton** button) {
gfx::Point location(point); gfx::Point location(point);
views::View::ConvertPointFromScreen(this, &location); views::View::ConvertPointFromScreen(this, &location);
@ -117,7 +117,7 @@ bool MenuBar::GetMenuButtonFromScreenPoint(const gfx::Point& point,
for (int i = 0; i < child_count(); ++i) { for (int i = 0; i < child_count(); ++i) {
views::View* view = child_at(i); views::View* view = child_at(i);
if (view->bounds().Contains(location) && if (view->bounds().Contains(location) &&
(menu_model_->GetTypeAt(i) == ui::MenuModel::TYPE_SUBMENU)) { (menu_model_->GetTypeAt(i) == AtomMenuModel::TYPE_SUBMENU)) {
*menu_model = menu_model_->GetSubmenuModelAt(i); *menu_model = menu_model_->GetSubmenuModelAt(i);
*button = static_cast<views::MenuButton*>(view); *button = static_cast<views::MenuButton*>(view);
return true; return true;
@ -144,8 +144,8 @@ void MenuBar::OnMenuButtonClicked(views::MenuButton* source,
return; return;
int id = source->tag(); int id = source->tag();
ui::MenuModel::ItemType type = menu_model_->GetTypeAt(id); AtomMenuModel::ItemType type = menu_model_->GetTypeAt(id);
if (type != ui::MenuModel::TYPE_SUBMENU) { if (type != AtomMenuModel::TYPE_SUBMENU) {
menu_model_->ActivatedAt(id, 0); menu_model_->ActivatedAt(id, 0);
return; return;
} }

View file

@ -5,14 +5,11 @@
#ifndef ATOM_BROWSER_UI_VIEWS_MENU_BAR_H_ #ifndef ATOM_BROWSER_UI_VIEWS_MENU_BAR_H_
#define ATOM_BROWSER_UI_VIEWS_MENU_BAR_H_ #define ATOM_BROWSER_UI_VIEWS_MENU_BAR_H_
#include "atom/browser/ui/atom_menu_model.h"
#include "ui/views/controls/button/button.h" #include "ui/views/controls/button/button.h"
#include "ui/views/controls/button/menu_button_listener.h" #include "ui/views/controls/button/menu_button_listener.h"
#include "ui/views/view.h" #include "ui/views/view.h"
namespace ui {
class MenuModel;
}
namespace views { namespace views {
class MenuButton; class MenuButton;
} }
@ -29,7 +26,7 @@ class MenuBar : public views::View,
virtual ~MenuBar(); virtual ~MenuBar();
// Replaces current menu with a new one. // Replaces current menu with a new one.
void SetMenu(ui::MenuModel* menu_model); void SetMenu(AtomMenuModel* menu_model);
// Shows underline under accelerators. // Shows underline under accelerators.
void SetAcceleratorVisibility(bool visible); void SetAcceleratorVisibility(bool visible);
@ -46,7 +43,7 @@ class MenuBar : public views::View,
// Get the menu under specified screen point. // Get the menu under specified screen point.
bool GetMenuButtonFromScreenPoint(const gfx::Point& point, bool GetMenuButtonFromScreenPoint(const gfx::Point& point,
ui::MenuModel** menu_model, AtomMenuModel** menu_model,
views::MenuButton** button); views::MenuButton** button);
protected: protected:
@ -74,7 +71,7 @@ class MenuBar : public views::View,
SkColor hover_color_; SkColor hover_color_;
#endif #endif
ui::MenuModel* menu_model_; AtomMenuModel* menu_model_;
DISALLOW_COPY_AND_ASSIGN(MenuBar); DISALLOW_COPY_AND_ASSIGN(MenuBar);
}; };

View file

@ -5,10 +5,10 @@
#include "atom/browser/ui/views/menu_delegate.h" #include "atom/browser/ui/views/menu_delegate.h"
#include "atom/browser/ui/views/menu_bar.h" #include "atom/browser/ui/views/menu_bar.h"
#include "atom/browser/ui/views/menu_model_adapter.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "ui/views/controls/button/menu_button.h" #include "ui/views/controls/button/menu_button.h"
#include "ui/views/controls/menu/menu_item_view.h" #include "ui/views/controls/menu/menu_item_view.h"
#include "ui/views/controls/menu/menu_model_adapter.h"
#include "ui/views/controls/menu/menu_runner.h" #include "ui/views/controls/menu/menu_runner.h"
#include "ui/views/widget/widget.h" #include "ui/views/widget/widget.h"
@ -22,7 +22,7 @@ MenuDelegate::MenuDelegate(MenuBar* menu_bar)
MenuDelegate::~MenuDelegate() { MenuDelegate::~MenuDelegate() {
} }
void MenuDelegate::RunMenu(ui::MenuModel* model, views::MenuButton* button) { void MenuDelegate::RunMenu(AtomMenuModel* model, views::MenuButton* button) {
gfx::Point screen_loc; gfx::Point screen_loc;
views::View::ConvertPointToScreen(button, &screen_loc); views::View::ConvertPointToScreen(button, &screen_loc);
// Subtract 1 from the height to make the popup flush with the button border. // Subtract 1 from the height to make the popup flush with the button border.
@ -30,10 +30,10 @@ void MenuDelegate::RunMenu(ui::MenuModel* model, views::MenuButton* button) {
button->height() - 1); button->height() - 1);
id_ = button->tag(); id_ = button->tag();
adapter_.reset(new views::MenuModelAdapter(model)); adapter_.reset(new MenuModelAdapter(model));
views::MenuItemView* item = new views::MenuItemView(this); views::MenuItemView* item = new views::MenuItemView(this);
static_cast<views::MenuModelAdapter*>(adapter_.get())->BuildMenu(item); static_cast<MenuModelAdapter*>(adapter_.get())->BuildMenu(item);
menu_runner_.reset(new views::MenuRunner( menu_runner_.reset(new views::MenuRunner(
item, item,
@ -102,7 +102,7 @@ views::MenuItemView* MenuDelegate::GetSiblingMenu(
bool* has_mnemonics, bool* has_mnemonics,
views::MenuButton**) { views::MenuButton**) {
views::MenuButton* button; views::MenuButton* button;
ui::MenuModel* model; AtomMenuModel* model;
if (menu_bar_->GetMenuButtonFromScreenPoint(screen_point, &model, &button) && if (menu_bar_->GetMenuButtonFromScreenPoint(screen_point, &model, &button) &&
button->tag() != id_) { button->tag() != id_) {
DCHECK(menu_runner_->IsRunning()); DCHECK(menu_runner_->IsRunning());

View file

@ -7,16 +7,13 @@
#include <memory> #include <memory>
#include "atom/browser/ui/atom_menu_model.h"
#include "ui/views/controls/menu/menu_delegate.h" #include "ui/views/controls/menu/menu_delegate.h"
namespace views { namespace views {
class MenuRunner; class MenuRunner;
} }
namespace ui {
class MenuModel;
}
namespace atom { namespace atom {
class MenuBar; class MenuBar;
@ -26,7 +23,7 @@ class MenuDelegate : public views::MenuDelegate {
explicit MenuDelegate(MenuBar* menu_bar); explicit MenuDelegate(MenuBar* menu_bar);
virtual ~MenuDelegate(); virtual ~MenuDelegate();
void RunMenu(ui::MenuModel* model, views::MenuButton* button); void RunMenu(AtomMenuModel* model, views::MenuButton* button);
protected: protected:
// views::MenuDelegate: // views::MenuDelegate:

View file

@ -0,0 +1,28 @@
// 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/ui/views/menu_model_adapter.h"
namespace atom {
MenuModelAdapter::MenuModelAdapter(AtomMenuModel* menu_model)
: views::MenuModelAdapter(menu_model),
menu_model_(menu_model) {
}
MenuModelAdapter::~MenuModelAdapter() {
}
bool MenuModelAdapter::GetAccelerator(int id,
ui::Accelerator* accelerator) const {
ui::MenuModel* model = menu_model_;
int index = 0;
if (ui::MenuModel::GetModelAndIndexForCommandId(id, &model, &index)) {
return static_cast<AtomMenuModel*>(model)->
GetAcceleratorAtWithParams(index, true, accelerator);
}
return false;
}
} // namespace atom

View file

@ -0,0 +1,29 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_UI_VIEWS_MENU_MODEL_ADAPTER_H_
#define ATOM_BROWSER_UI_VIEWS_MENU_MODEL_ADAPTER_H_
#include "atom/browser/ui/atom_menu_model.h"
#include "ui/views/controls/menu/menu_model_adapter.h"
namespace atom {
class MenuModelAdapter : public views::MenuModelAdapter {
public:
explicit MenuModelAdapter(AtomMenuModel* menu_model);
virtual ~MenuModelAdapter();
protected:
bool GetAccelerator(int id, ui::Accelerator* accelerator) const override;
private:
AtomMenuModel* menu_model_;
DISALLOW_COPY_AND_ASSIGN(MenuModelAdapter);
};
} // namespace atom
#endif // ATOM_BROWSER_UI_VIEWS_MENU_MODEL_ADAPTER_H_

View file

@ -132,7 +132,7 @@ void NotifyIcon::DisplayBalloon(HICON icon,
} }
void NotifyIcon::PopUpContextMenu(const gfx::Point& pos, void NotifyIcon::PopUpContextMenu(const gfx::Point& pos,
ui::SimpleMenuModel* menu_model) { AtomMenuModel* menu_model) {
// Returns if context menu isn't set. // Returns if context menu isn't set.
if (menu_model == nullptr && menu_model_ == nullptr) if (menu_model == nullptr && menu_model_ == nullptr)
return; return;
@ -154,7 +154,7 @@ void NotifyIcon::PopUpContextMenu(const gfx::Point& pos,
NULL, NULL, rect, views::MENU_ANCHOR_TOPLEFT, ui::MENU_SOURCE_MOUSE)); NULL, NULL, rect, views::MENU_ANCHOR_TOPLEFT, ui::MENU_SOURCE_MOUSE));
} }
void NotifyIcon::SetContextMenu(ui::SimpleMenuModel* menu_model) { void NotifyIcon::SetContextMenu(AtomMenuModel* menu_model) {
menu_model_ = menu_model; menu_model_ = menu_model;
} }

View file

@ -51,8 +51,8 @@ class NotifyIcon : public TrayIcon {
const base::string16& title, const base::string16& title,
const base::string16& contents) override; const base::string16& contents) override;
void PopUpContextMenu(const gfx::Point& pos, void PopUpContextMenu(const gfx::Point& pos,
ui::SimpleMenuModel* menu_model) override; AtomMenuModel* menu_model) override;
void SetContextMenu(ui::SimpleMenuModel* menu_model) override; void SetContextMenu(AtomMenuModel* menu_model) override;
gfx::Rect GetBounds() override; gfx::Rect GetBounds() override;
private: private:
@ -74,7 +74,7 @@ class NotifyIcon : public TrayIcon {
base::win::ScopedHICON icon_; base::win::ScopedHICON icon_;
// The context menu. // The context menu.
ui::SimpleMenuModel* menu_model_; AtomMenuModel* menu_model_;
DISALLOW_COPY_AND_ASSIGN(NotifyIcon); DISALLOW_COPY_AND_ASSIGN(NotifyIcon);
}; };

View file

@ -142,6 +142,22 @@ bool TaskbarHost::SetOverlayIcon(
window, icon.get(), base::UTF8ToUTF16(text).c_str())); window, icon.get(), base::UTF8ToUTF16(text).c_str()));
} }
bool TaskbarHost::SetThumbnailClip(HWND window, const gfx::Rect& region) {
if (!InitializeTaskbar())
return false;
if (region.IsEmpty()) {
return SUCCEEDED(taskbar_->SetThumbnailClip(window, NULL));
} else {
RECT rect;
rect.left = region.x();
rect.right = region.right();
rect.top = region.y();
rect.bottom = region.bottom();
return SUCCEEDED(taskbar_->SetThumbnailClip(window, &rect));
}
}
bool TaskbarHost::HandleThumbarButtonEvent(int button_id) { bool TaskbarHost::HandleThumbarButtonEvent(int button_id) {
if (ContainsKey(callback_map_, button_id)) { if (ContainsKey(callback_map_, button_id)) {
auto callback = callback_map_[button_id]; auto callback = callback_map_[button_id];

View file

@ -13,6 +13,7 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/win/scoped_comptr.h" #include "base/win/scoped_comptr.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/image/image.h" #include "ui/gfx/image/image.h"
namespace atom { namespace atom {
@ -40,6 +41,9 @@ class TaskbarHost {
bool SetOverlayIcon( bool SetOverlayIcon(
HWND window, const gfx::Image& overlay, const std::string& text); HWND window, const gfx::Image& overlay, const std::string& text);
// Set the region of the window to show as a thumbnail in taskbar.
bool TaskbarHost::SetThumbnailClip(HWND window, const gfx::Rect& region);
// Called by the window that there is a button in thumbar clicked. // Called by the window that there is a button in thumbar clicked.
bool HandleThumbarButtonEvent(int button_id); bool HandleThumbarButtonEvent(int button_id);

View file

@ -0,0 +1,27 @@
// 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/unresponsive_suppressor.h"
namespace atom {
namespace {
int g_suppress_level = 0;
} // namespace
bool IsUnresponsiveEventSuppressed() {
return g_suppress_level > 0;
}
UnresponsiveSuppressor::UnresponsiveSuppressor() {
g_suppress_level++;
}
UnresponsiveSuppressor::~UnresponsiveSuppressor() {
g_suppress_level--;
}
} // namespace atom

View file

@ -0,0 +1,25 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_UNRESPONSIVE_SUPPRESSOR_H_
#define ATOM_BROWSER_UNRESPONSIVE_SUPPRESSOR_H_
#include "base/macros.h"
namespace atom {
bool IsUnresponsiveEventSuppressed();
class UnresponsiveSuppressor {
public:
UnresponsiveSuppressor();
~UnresponsiveSuppressor();
private:
DISALLOW_COPY_AND_ASSIGN(UnresponsiveSuppressor);
};
} // namespace atom
#endif // ATOM_BROWSER_UNRESPONSIVE_SUPPRESSOR_H_

View file

@ -7,6 +7,7 @@
#include "atom/browser/api/atom_api_web_contents.h" #include "atom/browser/api/atom_api_web_contents.h"
#include "atom/common/native_mate_converters/gurl_converter.h" #include "atom/common/native_mate_converters/gurl_converter.h"
#include "content/public/browser/guest_host.h" #include "content/public/browser/guest_host.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h" #include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host.h" #include "content/public/browser/render_widget_host.h"
@ -95,10 +96,13 @@ void WebViewGuestDelegate::SetSize(const SetSizeParams& params) {
auto_size_enabled_ = enable_auto_size; auto_size_enabled_ = enable_auto_size;
} }
void WebViewGuestDelegate::DidCommitProvisionalLoadForFrame( void WebViewGuestDelegate::DidFinishNavigation(
content::RenderFrameHost* render_frame_host, content::NavigationHandle* navigation_handle) {
const GURL& url, ui::PageTransition transition_type) { if (navigation_handle->HasCommitted() && !navigation_handle->IsErrorPage()) {
api_web_contents_->Emit("load-commit", url, !render_frame_host->GetParent()); auto is_main_frame = navigation_handle->IsInMainFrame();
auto url = navigation_handle->GetURL();
api_web_contents_->Emit("load-commit", url, is_main_frame);
}
} }
void WebViewGuestDelegate::DidAttach(int guest_proxy_routing_id) { void WebViewGuestDelegate::DidAttach(int guest_proxy_routing_id) {

View file

@ -47,9 +47,8 @@ class WebViewGuestDelegate : public content::BrowserPluginGuestDelegate,
protected: protected:
// content::WebContentsObserver: // content::WebContentsObserver:
void DidCommitProvisionalLoadForFrame( void DidFinishNavigation(
content::RenderFrameHost* render_frame_host, content::NavigationHandle* navigation_handle) override;
const GURL& url, ui::PageTransition transition_type) override;
// content::BrowserPluginGuestDelegate: // content::BrowserPluginGuestDelegate:
void DidAttach(int guest_proxy_routing_id) final; void DidAttach(int guest_proxy_routing_id) final;

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