diff --git a/.node-version b/.node-version index ed15bef9ae26..dffc266d6a8b 100644 --- a/.node-version +++ b/.node-version @@ -1 +1 @@ -v6.1.0 +v6.3.0 diff --git a/README-ko.md b/README-ko.md index c3c0216c2aca..79cc716587b0 100644 --- a/README-ko.md +++ b/README-ko.md @@ -75,6 +75,7 @@ npm install electron-prebuilt --save-dev - [`electron-br`](https://electron-br.slack.com) *(브라질)* 커뮤니티 - [`electron-kr`](http://www.meetup.com/electron-kr/) *(한국)* 커뮤니티 - [`electron-jp`](https://electron-jp-slackin.herokuapp.com/) *(일본)* 커뮤니티 +- [`electron-tr`](http://www.meetup.com/Electron-JS-Istanbul/) *(터키)* 커뮤니티 [awesome-electron](https://github.com/sindresorhus/awesome-electron) 프로젝트에 커뮤니티가 운영중인 유용한 예시 애플리케이션과 도구, 리소스가 있으니 참고하기 바랍니다. diff --git a/README.md b/README.md index cf8d97a56098..2726e0778972 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,7 @@ forums - [`electron-kr`](http://www.meetup.com/electron-kr/) *(Korean)* - [`electron-jp`](https://electron-jp-slackin.herokuapp.com/) *(Japanese)* - [`electron-tr`](http://www.meetup.com/Electron-JS-Istanbul/) *(Turkish)* +- [`electron-id`](https://electron-id.slack.com) *(Indonesia)* Check out [awesome-electron](https://github.com/sindresorhus/awesome-electron) for a community maintained list of useful example apps, tools and resources. diff --git a/atom/app/node_main.cc b/atom/app/node_main.cc index 3eaeed339416..040b4b615721 100644 --- a/atom/app/node_main.cc +++ b/atom/app/node_main.cc @@ -7,7 +7,6 @@ #include "atom/app/uv_task_runner.h" #include "atom/browser/javascript_environment.h" #include "atom/browser/node_debugger.h" -#include "atom/common/node_includes.h" #include "base/command_line.h" #include "base/feature_list.h" #include "base/threading/thread_task_runner_handle.h" @@ -15,6 +14,8 @@ #include "gin/public/isolate_holder.h" #include "gin/v8_initializer.h" +#include "atom/common/node_includes.h" + namespace atom { int NodeMain(int argc, char *argv[]) { @@ -69,7 +70,7 @@ int NodeMain(int argc, char *argv[]) { exit_code = node::EmitExit(env); node::RunAtExit(env); - env->Dispose(); + node::FreeEnvironment(env); } v8::V8::Dispose(); diff --git a/atom/app/uv_task_runner.cc b/atom/app/uv_task_runner.cc index 097cc3bcda18..7857ace3a2bd 100644 --- a/atom/app/uv_task_runner.cc +++ b/atom/app/uv_task_runner.cc @@ -21,7 +21,7 @@ UvTaskRunner::~UvTaskRunner() { bool UvTaskRunner::PostDelayedTask(const tracked_objects::Location& from_here, const base::Closure& task, base::TimeDelta delay) { - uv_timer_t* timer = new uv_timer_t; + auto* timer = new uv_timer_t; timer->data = this; uv_timer_init(loop_, timer); uv_timer_start(timer, UvTaskRunner::OnTimeout, delay.InMilliseconds(), 0); diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index a39f9809ebf0..8a66c041f4a2 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -32,6 +32,7 @@ #include "base/strings/string_util.h" #include "brightray/browser/brightray_paths.h" #include "chrome/common/chrome_paths.h" +#include "content/public/browser/browser_accessibility_state.h" #include "content/public/browser/client_certificate_delegate.h" #include "content/public/browser/gpu_data_manager.h" #include "content/public/browser/render_frame_host.h" @@ -71,6 +72,30 @@ struct Converter { }; #endif +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, v8::Local 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 ToV8(v8::Isolate* isolate, + Browser::LoginItemSettings val) { + mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); + dict.Set("openAtLogin", val.open_at_login); + dict.Set("openAsHidden", val.open_as_hidden); + dict.Set("restoreState", val.restore_state); + dict.Set("wasOpenedAtLogin", val.opened_at_login); + dict.Set("wasOpenedAsHidden", val.opened_as_hidden); + return dict.GetHandle(); + } +}; } // namespace mate @@ -254,6 +279,10 @@ void App::OnFinishLaunching() { Emit("ready"); } +void App::OnAccessibilitySupportChanged() { + Emit("accessibility-support-changed", IsAccessibilitySupportEnabled()); +} + #if defined(OS_MACOSX) void App::OnContinueUserActivity( bool* prevent_default, @@ -459,11 +488,16 @@ void App::DisableHardwareAcceleration(mate::Arguments* args) { content::GpuDataManager::GetInstance()->DisableHardwareAcceleration(); } +bool App::IsAccessibilitySupportEnabled() { + auto ax_state = content::BrowserAccessibilityState::GetInstance(); + return ax_state->IsAccessibleBrowser(); +} + #if defined(USE_NSS_CERTS) void App::ImportCertificate( const base::DictionaryValue& options, const net::CompletionCallback& callback) { - auto browser_context = brightray::BrowserContext::From("", false); + auto browser_context = AtomBrowserContext::From("", false); if (!certificate_manager_model_) { std::unique_ptr copy = options.CreateDeepCopy(); CertificateManagerModel::Create( @@ -522,6 +556,10 @@ void App::BuildPrototype( base::Bind(&Browser::RemoveAsDefaultProtocolClient, browser)) .SetMethod("setBadgeCount", base::Bind(&Browser::SetBadgeCount, browser)) .SetMethod("getBadgeCount", base::Bind(&Browser::GetBadgeCount, browser)) + .SetMethod("getLoginItemSettings", + base::Bind(&Browser::GetLoginItemSettings, browser)) + .SetMethod("setLoginItemSettings", + base::Bind(&Browser::SetLoginItemSettings, browser)) #if defined(OS_MACOSX) .SetMethod("hide", base::Bind(&Browser::Hide, browser)) .SetMethod("show", base::Bind(&Browser::Show, browser)) @@ -547,6 +585,8 @@ void App::BuildPrototype( .SetMethod("makeSingleInstance", &App::MakeSingleInstance) .SetMethod("releaseSingleInstance", &App::ReleaseSingleInstance) .SetMethod("relaunch", &App::Relaunch) + .SetMethod("isAccessibilitySupportEnabled", + &App::IsAccessibilitySupportEnabled) .SetMethod("disableHardwareAcceleration", &App::DisableHardwareAcceleration); } diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index b550f0ba7b90..13cedaa7d898 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -72,6 +72,7 @@ class App : public AtomBrowserClient::Delegate, void OnFinishLaunching() override; void OnLogin(LoginHandler* login_handler, const base::DictionaryValue& request_details) override; + void OnAccessibilitySupportChanged() override; #if defined(OS_MACOSX) void OnContinueUserActivity( bool* prevent_default, @@ -113,6 +114,7 @@ class App : public AtomBrowserClient::Delegate, void ReleaseSingleInstance(); bool Relaunch(mate::Arguments* args); void DisableHardwareAcceleration(mate::Arguments* args); + bool IsAccessibilitySupportEnabled(); #if defined(USE_NSS_CERTS) void ImportCertificate(const base::DictionaryValue& options, const net::CompletionCallback& callback); diff --git a/atom/browser/api/atom_api_auto_updater.cc b/atom/browser/api/atom_api_auto_updater.cc index 54e2bd9f746a..f8d9a2f9ac92 100644 --- a/atom/browser/api/atom_api_auto_updater.cc +++ b/atom/browser/api/atom_api_auto_updater.cc @@ -109,6 +109,7 @@ void AutoUpdater::BuildPrototype( v8::Isolate* isolate, v8::Local prototype) { mate::ObjectTemplateBuilder(isolate, prototype) .SetMethod("checkForUpdates", &auto_updater::AutoUpdater::CheckForUpdates) + .SetMethod("getFeedURL", &auto_updater::AutoUpdater::GetFeedURL) .SetMethod("setFeedURL", &AutoUpdater::SetFeedURL) .SetMethod("quitAndInstall", &AutoUpdater::QuitAndInstall); } diff --git a/atom/browser/api/atom_api_auto_updater.h b/atom/browser/api/atom_api_auto_updater.h index e8c135f292ea..4c73f7ce8e9c 100644 --- a/atom/browser/api/atom_api_auto_updater.h +++ b/atom/browser/api/atom_api_auto_updater.h @@ -44,6 +44,7 @@ class AutoUpdater : public mate::EventEmitter, void OnWindowAllClosed() override; private: + std::string GetFeedURL(); void SetFeedURL(const std::string& url, mate::Arguments* args); void QuitAndInstall(); diff --git a/atom/browser/api/atom_api_menu.cc b/atom/browser/api/atom_api_menu.cc index c9cd37522b82..54a3d4e81326 100644 --- a/atom/browser/api/atom_api_menu.cc +++ b/atom/browser/api/atom_api_menu.cc @@ -21,7 +21,7 @@ namespace api { Menu::Menu(v8::Isolate* isolate) : model_(new AtomMenuModel(this)), - parent_(NULL) { + parent_(nullptr) { } Menu::~Menu() { @@ -53,11 +53,14 @@ bool Menu::IsCommandIdVisible(int command_id) const { return is_visible_.Run(command_id); } -bool Menu::GetAcceleratorForCommandId(int command_id, - ui::Accelerator* accelerator) { +bool Menu::GetAcceleratorForCommandIdWithParams( + int command_id, + bool use_default_accelerator, + ui::Accelerator* accelerator) const { v8::Locker locker(isolate()); v8::HandleScope handle_scope(isolate()); - v8::Local val = get_accelerator_.Run(command_id); + v8::Local val = get_accelerator_.Run( + command_id, use_default_accelerator); return mate::ConvertFromV8(isolate(), val, accelerator); } diff --git a/atom/browser/api/atom_api_menu.h b/atom/browser/api/atom_api_menu.h index df1f97a50b8c..e04d189efc1c 100644 --- a/atom/browser/api/atom_api_menu.h +++ b/atom/browser/api/atom_api_menu.h @@ -46,8 +46,10 @@ class Menu : public mate::TrackableObject, bool IsCommandIdChecked(int command_id) const override; bool IsCommandIdEnabled(int command_id) const override; bool IsCommandIdVisible(int command_id) const override; - bool GetAcceleratorForCommandId(int command_id, - ui::Accelerator* accelerator) override; + bool GetAcceleratorForCommandIdWithParams( + int command_id, + bool use_default_accelerator, + ui::Accelerator* accelerator) const override; void ExecuteCommand(int command_id, int event_flags) override; void MenuWillShow(ui::SimpleMenuModel* source) override; @@ -89,7 +91,7 @@ class Menu : public mate::TrackableObject, base::Callback is_checked_; base::Callback is_enabled_; base::Callback is_visible_; - base::Callback(int)> get_accelerator_; + base::Callback(int, bool)> get_accelerator_; base::Callback, int)> execute_command_; base::Callback menu_will_show_; diff --git a/atom/browser/api/atom_api_menu_mac.mm b/atom/browser/api/atom_api_menu_mac.mm index 3b91dac62a7f..6a7d43b4da27 100644 --- a/atom/browser/api/atom_api_menu_mac.mm +++ b/atom/browser/api/atom_api_menu_mac.mm @@ -5,6 +5,7 @@ #import "atom/browser/api/atom_api_menu_mac.h" #include "atom/browser/native_window.h" +#include "atom/browser/unresponsive_suppressor.h" #include "base/message_loop/message_loop.h" #include "base/strings/sys_string_conversions.h" #include "brightray/browser/inspectable_web_contents.h" @@ -30,7 +31,8 @@ void MenuMac::PopupAt(Window* window, int x, int y, int positioning_item) { return; base::scoped_nsobject menu_controller( - [[AtomMenuController alloc] initWithModel:model_.get()]); + [[AtomMenuController alloc] initWithModel:model_.get() + useDefaultAccelerator:NO]); NSMenu* menu = [menu_controller menu]; NSView* view = web_contents->GetView()->GetNativeView(); @@ -66,6 +68,9 @@ void MenuMac::PopupAt(Window* window, int x, int y, int positioning_item) { if (rightmostMenuPoint > screenRight) position.x = position.x - [menu size].width; + // Don't emit unresponsive event when showing menu. + atom::UnresponsiveSuppressor suppressor; + // Show the menu. [menu popUpMenuPositioningItem:item atLocation:position inView:view]; } @@ -74,7 +79,8 @@ void MenuMac::PopupAt(Window* window, int x, int y, int positioning_item) { void Menu::SetApplicationMenu(Menu* base_menu) { MenuMac* menu = static_cast(base_menu); base::scoped_nsobject menu_controller( - [[AtomMenuController alloc] initWithModel:menu->model_.get()]); + [[AtomMenuController alloc] initWithModel:menu->model_.get() + useDefaultAccelerator:YES]); [NSApp setMainMenu:[menu_controller menu]]; // Ensure the menu_controller_ is destroyed after main menu is set. diff --git a/atom/browser/api/atom_api_menu_views.cc b/atom/browser/api/atom_api_menu_views.cc index c4040e39d71f..a6fd8024ab2a 100644 --- a/atom/browser/api/atom_api_menu_views.cc +++ b/atom/browser/api/atom_api_menu_views.cc @@ -5,6 +5,7 @@ #include "atom/browser/api/atom_api_menu_views.h" #include "atom/browser/native_window_views.h" +#include "atom/browser/unresponsive_suppressor.h" #include "content/public/browser/render_widget_host_view.h" #include "ui/display/screen.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); } + // Don't emit unresponsive event when showing menu. + atom::UnresponsiveSuppressor suppressor; + // Show the menu. views::MenuRunner menu_runner( model(), diff --git a/atom/browser/api/atom_api_protocol.cc b/atom/browser/api/atom_api_protocol.cc index 2b20dae28bf2..4019a96f2a6d 100644 --- a/atom/browser/api/atom_api_protocol.cc +++ b/atom/browser/api/atom_api_protocol.cc @@ -6,6 +6,7 @@ #include "atom/browser/atom_browser_client.h" #include "atom/browser/atom_browser_main_parts.h" +#include "atom/browser/browser.h" #include "atom/browser/net/url_request_async_asar_job.h" #include "atom/browser/net/url_request_buffer_job.h" #include "atom/browser/net/url_request_fetch_job.h" @@ -26,12 +27,30 @@ namespace atom { namespace api { +namespace { + +// Clear protocol handlers in IO thread. +void ClearJobFactoryInIO( + scoped_refptr request_context_getter) { + auto job_factory = static_cast( + request_context_getter->job_factory()); + job_factory->Clear(); +} + +} // namespace + Protocol::Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context) : request_context_getter_(browser_context->GetRequestContext()), weak_factory_(this) { Init(isolate); } +Protocol::~Protocol() { + content::BrowserThread::PostTask( + content::BrowserThread::IO, FROM_HERE, + base::Bind(ClearJobFactoryInIO, request_context_getter_)); +} + void Protocol::RegisterServiceWorkerSchemes( const std::vector& schemes) { atom::AtomBrowserClient::SetCustomServiceWorkerSchemes(schemes); @@ -173,7 +192,13 @@ void Protocol::BuildPrototype( namespace { void RegisterStandardSchemes( - const std::vector& schemes) { + const std::vector& schemes, mate::Arguments* args) { + if (atom::Browser::Get()->is_ready()) { + args->ThrowError("protocol.registerStandardSchemes should be called before " + "app is ready"); + return; + } + auto policy = content::ChildProcessSecurityPolicy::GetInstance(); for (const auto& scheme : schemes) { url::AddStandardScheme(scheme.c_str(), url::SCHEME_WITHOUT_PORT); diff --git a/atom/browser/api/atom_api_protocol.h b/atom/browser/api/atom_api_protocol.h index 379c43bfcd78..b5d47def68c4 100644 --- a/atom/browser/api/atom_api_protocol.h +++ b/atom/browser/api/atom_api_protocol.h @@ -43,6 +43,7 @@ class Protocol : public mate::TrackableObject { protected: Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context); + ~Protocol(); private: // Possible errors. diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index 8073affc1ed5..f839490ddf5e 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -11,6 +11,7 @@ #include "atom/browser/api/atom_api_download_item.h" #include "atom/browser/api/atom_api_protocol.h" #include "atom/browser/api/atom_api_web_request.h" +#include "atom/browser/browser.h" #include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_browser_main_parts.h" #include "atom/browser/atom_permission_manager.h" @@ -20,6 +21,7 @@ #include "atom/common/native_mate_converters/gurl_converter.h" #include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/native_mate_converters/net_converter.h" +#include "atom/common/native_mate_converters/value_converter.h" #include "atom/common/node_includes.h" #include "base/files/file_path.h" #include "base/guid.h" @@ -163,6 +165,8 @@ namespace api { namespace { +const char kPersistPrefix[] = "persist:"; + // The wrapSession funtion which is implemented in JavaScript using WrapSessionCallback = base::Callback)>; WrapSessionCallback g_wrap_session; @@ -241,10 +245,10 @@ void OnGetBackend(disk_cache::Backend** backend_ptr, } else if (action == Session::CacheAction::STATS) { base::StringPairs stats; (*backend_ptr)->GetStats(&stats); - for (size_t i = 0; i < stats.size(); ++i) { - if (stats[i].first == "Current size") { + for (const auto& stat : stats) { + if (stat.first == "Current size") { int current_size; - base::StringToInt(stats[i].second, ¤t_size); + base::StringToInt(stat.second, ¤t_size); RunCallbackInUI(callback, current_size); break; } @@ -266,7 +270,7 @@ void DoCacheActionInIO( // Call GetBackend and make the backend's ptr accessable in OnGetBackend. using BackendPtr = disk_cache::Backend*; - BackendPtr* backend_ptr = new BackendPtr(nullptr); + auto* backend_ptr = new BackendPtr(nullptr); net::CompletionCallback on_get_backend = base::Bind(&OnGetBackend, base::Owned(backend_ptr), action, callback); int rv = http_cache->GetBackend(backend_ptr, on_get_backend); @@ -285,6 +289,14 @@ void SetProxyInIO(net::URLRequestContextGetter* getter, RunCallbackInUI(callback); } +void SetCertVerifyProcInIO( + const scoped_refptr& context_getter, + const AtomCertVerifier::VerifyProc& proc) { + auto request_context = context_getter->GetURLRequestContext(); + static_cast(request_context->cert_verifier())-> + SetVerifyProc(proc); +} + void ClearHostResolverCacheInIO( const scoped_refptr& context_getter, const base::Closure& callback) { @@ -311,6 +323,11 @@ void AllowNTLMCredentialsForDomainsInIO( } } +void OnClearStorageDataDone(const base::Closure& callback) { + if (!callback.is_null()) + callback.Run(); +} + } // namespace Session::Session(v8::Isolate* isolate, AtomBrowserContext* browser_context) @@ -360,21 +377,19 @@ void Session::DoCacheAction(const net::CompletionCallback& callback) { } void Session::ClearStorageData(mate::Arguments* args) { - // clearStorageData([options, ]callback) + // clearStorageData([options, callback]) ClearStorageDataOptions options; - args->GetNext(&options); base::Closure callback; - if (!args->GetNext(&callback)) { - args->ThrowError(); - return; - } + args->GetNext(&options); + args->GetNext(&callback); auto storage_partition = content::BrowserContext::GetStoragePartition(browser_context(), nullptr); storage_partition->ClearData( options.storage_types, options.quota_types, options.origin, content::StoragePartition::OriginMatcherFunction(), - base::Time(), base::Time::Max(), callback); + base::Time(), base::Time::Max(), + base::Bind(&OnClearStorageDataDone, callback)); } void Session::FlushStorageData() { @@ -434,7 +449,10 @@ void Session::SetCertVerifyProc(v8::Local val, return; } - browser_context_->cert_verifier()->SetVerifyProc(proc); + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::Bind(&SetCertVerifyProcInIO, + make_scoped_refptr(browser_context_->GetRequestContext()), + proc)); } void Session::SetPermissionRequestHandler(v8::Local val, @@ -522,10 +540,19 @@ mate::Handle Session::CreateFrom( // static mate::Handle Session::FromPartition( - v8::Isolate* isolate, const std::string& partition, bool in_memory) { - auto browser_context = brightray::BrowserContext::From(partition, in_memory); - return CreateFrom(isolate, - static_cast(browser_context.get())); + v8::Isolate* isolate, const std::string& partition, + const base::DictionaryValue& options) { + scoped_refptr browser_context; + if (partition.empty()) { + browser_context = AtomBrowserContext::From("", false, options); + } else if (base::StartsWith(partition, kPersistPrefix, + base::CompareCase::SENSITIVE)) { + std::string name = partition.substr(8); + browser_context = AtomBrowserContext::From(name, false, options); + } else { + browser_context = AtomBrowserContext::From(partition, true, options); + } + return CreateFrom(isolate, browser_context.get()); } // static @@ -565,11 +592,23 @@ void SetWrapSession(const WrapSessionCallback& callback) { namespace { +v8::Local 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 exports, v8::Local unused, v8::Local context, void* priv) { v8::Isolate* isolate = context->GetIsolate(); mate::Dictionary dict(isolate, exports); - dict.SetMethod("fromPartition", &atom::api::Session::FromPartition); + dict.SetMethod("fromPartition", &FromPartition); dict.SetMethod("_setWrapSession", &atom::api::SetWrapSession); } diff --git a/atom/browser/api/atom_api_session.h b/atom/browser/api/atom_api_session.h index 0868cbe18bee..c3bb82eebaf4 100644 --- a/atom/browser/api/atom_api_session.h +++ b/atom/browser/api/atom_api_session.h @@ -8,6 +8,7 @@ #include #include "atom/browser/api/trackable_object.h" +#include "base/values.h" #include "content/public/browser/download_manager.h" #include "native_mate/handle.h" #include "net/base/completion_callback.h" @@ -47,9 +48,10 @@ class Session: public mate::TrackableObject, static mate::Handle CreateFrom( v8::Isolate* isolate, AtomBrowserContext* browser_context); - // Gets the Session of |partition| and |in_memory|. + // Gets the Session of |partition|. static mate::Handle 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(); } diff --git a/atom/browser/api/atom_api_tray.cc b/atom/browser/api/atom_api_tray.cc index 6bbad738b32d..e576601449d6 100644 --- a/atom/browser/api/atom_api_tray.cc +++ b/atom/browser/api/atom_api_tray.cc @@ -29,6 +29,8 @@ Tray::Tray(v8::Isolate* isolate, mate::Handle image) } Tray::~Tray() { + // Destroy the native tray in next tick. + base::MessageLoop::current()->DeleteSoon(FROM_HERE, tray_icon_.release()); } // static @@ -74,6 +76,10 @@ void Tray::OnDropFiles(const std::vector& files) { Emit("drop-files", files); } +void Tray::OnDropText(const std::string& text) { + Emit("drop-text", text); +} + void Tray::OnDragEntered() { Emit("drag-enter"); } diff --git a/atom/browser/api/atom_api_tray.h b/atom/browser/api/atom_api_tray.h index 95cca87db51c..56d851d44e76 100644 --- a/atom/browser/api/atom_api_tray.h +++ b/atom/browser/api/atom_api_tray.h @@ -53,6 +53,7 @@ class Tray : public mate::TrackableObject, void OnBalloonClosed() override; void OnDrop() override; void OnDropFiles(const std::vector& files) override; + void OnDropText(const std::string& text) override; void OnDragEntered() override; void OnDragExited() override; void OnDragEnded() override; diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 99cb2e007482..a4b3816b5d5e 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -47,6 +47,7 @@ #include "content/public/browser/native_web_keyboard_event.h" #include "content/public/browser/navigation_details.h" #include "content/public/browser/navigation_entry.h" +#include "content/public/browser/navigation_handle.h" #include "content/public/browser/plugin_service.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" @@ -65,6 +66,7 @@ #include "net/url_request/url_request_context.h" #include "third_party/WebKit/public/web/WebInputEvent.h" #include "third_party/WebKit/public/web/WebFindOptions.h" +#include "ui/gfx/screen.h" #include "atom/common/node_includes.h" @@ -238,6 +240,13 @@ content::ServiceWorkerContext* GetServiceWorkerContext( return storage_partition->GetServiceWorkerContext(); } +// Called when CapturePage is done. +void OnCapturePageDone(base::Callback callback, + const SkBitmap& bitmap, + content::ReadbackResponse response) { + callback.Run(gfx::Image::CreateFrom1xBitmap(bitmap)); +} + } // namespace WebContents::WebContents(v8::Isolate* isolate, @@ -277,16 +286,11 @@ WebContents::WebContents(v8::Isolate* isolate, std::string partition; mate::Handle session; if (options.Get("session", &session)) { - } else if (options.Get("partition", &partition) && !partition.empty()) { - bool in_memory = true; - if (base::StartsWith(partition, "persist:", base::CompareCase::SENSITIVE)) { - in_memory = false; - partition = partition.substr(8); - } - session = Session::FromPartition(isolate, partition, in_memory); + } else if (options.Get("partition", &partition)) { + session = Session::FromPartition(isolate, partition); } else { // Use the default session if not specified. - session = Session::FromPartition(isolate, "", false); + session = Session::FromPartition(isolate, ""); } session_.Reset(isolate, session.ToV8()); @@ -600,20 +604,6 @@ void WebContents::DidFinishLoad(content::RenderFrameHost* render_frame_host, Emit("did-finish-load"); } -void WebContents::DidFailProvisionalLoad( - content::RenderFrameHost* render_frame_host, - const GURL& url, - int code, - const base::string16& description, - bool was_ignored_by_handler) { - bool is_main_frame = !render_frame_host->GetParent(); - Emit("did-fail-provisional-load", code, description, url, is_main_frame); - - // 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, const GURL& url, int error_code, @@ -657,13 +647,27 @@ void WebContents::DidGetRedirectForResourceRequest( details.headers.get()); } -void WebContents::DidNavigateMainFrame( - const content::LoadCommittedDetails& details, - const content::FrameNavigateParams& params) { - if (details.is_navigation_to_different_page()) - Emit("did-navigate", params.url); - else if (details.is_in_page) - Emit("did-navigate-in-page", params.url); +void WebContents::DidFinishNavigation( + content::NavigationHandle* navigation_handle) { + bool is_main_frame = navigation_handle->IsInMainFrame(); + if (navigation_handle->HasCommitted() && !navigation_handle->IsErrorPage()) { + auto url = navigation_handle->GetURL(); + bool is_in_page = navigation_handle->IsSamePage(); + if (is_main_frame && !is_in_page) { + Emit("did-navigate", url); + } else if (is_in_page) { + Emit("did-navigate-in-page", url); + } + } else { + auto url = navigation_handle->GetURL(); + int code = navigation_handle->GetNetErrorCode(); + auto description = net::ErrorToShortString(code); + Emit("did-fail-provisional-load", code, description, url, is_main_frame); + + // Do not emit "did-fail-load" for canceled requests. + if (code != net::ERR_ABORTED) + Emit("did-fail-load", code, description, url, is_main_frame); + } } void WebContents::TitleWasSet(content::NavigationEntry* entry, @@ -677,10 +681,10 @@ void WebContents::TitleWasSet(content::NavigationEntry* entry, void WebContents::DidUpdateFaviconURL( const std::vector& urls) { std::set unique_urls; - for (auto iter = urls.begin(); iter != urls.end(); ++iter) { - if (iter->icon_type != content::FaviconURL::FAVICON) + for (const auto& iter : urls) { + if (iter.icon_type != content::FaviconURL::FAVICON) continue; - const GURL& url = iter->icon_url; + const GURL& url = iter.icon_url; if (url.is_valid()) unique_urls.insert(url); } @@ -781,6 +785,13 @@ WebContents::Type WebContents::GetType() const { return type_; } +#if !defined(OS_MACOSX) +bool WebContents::IsFocused() const { + auto view = web_contents()->GetRenderWidgetHostView(); + return view && view->HasFocus(); +} +#endif + bool WebContents::Equal(const WebContents* web_contents) const { return GetID() == web_contents->GetID(); } @@ -1235,6 +1246,45 @@ void WebContents::StartDrag(const mate::Dictionary& item, } } +void WebContents::CapturePage(mate::Arguments* args) { + gfx::Rect rect; + base::Callback 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) { content::WebCursor::CursorInfo info; cursor.GetCursorInfo(&info); @@ -1370,6 +1420,8 @@ void WebContents::BuildPrototype(v8::Isolate* isolate, .SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace) .SetMethod("showDefinitionForSelection", &WebContents::ShowDefinitionForSelection) + .SetMethod("capturePage", &WebContents::CapturePage) + .SetMethod("isFocused", &WebContents::IsFocused) .SetProperty("id", &WebContents::ID) .SetProperty("session", &WebContents::Session) .SetProperty("hostWebContents", &WebContents::HostWebContents) diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 2917aa860a81..47684b929830 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -67,6 +67,7 @@ class WebContents : public mate::TrackableObject, int GetID() const; Type GetType() const; + bool IsFocused() const; bool Equal(const WebContents* web_contents) const; void LoadURL(const GURL& url, const mate::Dictionary& options); void DownloadURL(const GURL& url); @@ -145,6 +146,10 @@ class WebContents : public mate::TrackableObject, // Dragging native items. void StartDrag(const mate::Dictionary& item, mate::Arguments* args); + // Captures the page with |rect|, |callback| would be called when capturing is + // done. + void CapturePage(mate::Arguments* args); + // Methods for creating . void SetSize(const SetSizeParams& params); bool IsGuest() const; @@ -240,11 +245,6 @@ class WebContents : public mate::TrackableObject, int error_code, const base::string16& error_description, bool was_ignored_by_handler) override; - void DidFailProvisionalLoad(content::RenderFrameHost* render_frame_host, - const GURL& validated_url, - int error_code, - const base::string16& error_description, - bool was_ignored_by_handler) override; void DidStartLoading() override; void DidStopLoading() override; void DidGetResourceResponseStart( @@ -252,9 +252,8 @@ class WebContents : public mate::TrackableObject, void DidGetRedirectForResourceRequest( content::RenderFrameHost* render_frame_host, const content::ResourceRedirectDetails& details) override; - void DidNavigateMainFrame( - const content::LoadCommittedDetails& details, - const content::FrameNavigateParams& params) override; + void DidFinishNavigation( + content::NavigationHandle* navigation_handle) override; bool OnMessageReceived(const IPC::Message& message) override; void WebContentsDestroyed() override; void NavigationEntryCommitted( diff --git a/atom/browser/api/atom_api_web_contents_mac.mm b/atom/browser/api/atom_api_web_contents_mac.mm new file mode 100644 index 000000000000..19246e82ac7f --- /dev/null +++ b/atom/browser/api/atom_api_web_contents_mac.mm @@ -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 diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index ac5fb87c7535..848294045428 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -55,15 +55,6 @@ namespace api { namespace { -void OnCapturePageDone( - v8::Isolate* isolate, - const base::Callback& callback, - const SkBitmap& bitmap) { - v8::Locker locker(isolate); - v8::HandleScope handle_scope(isolate); - callback.Run(gfx::Image::CreateFrom1xBitmap(bitmap)); -} - // Converts binary data to Buffer. v8::Local ToBuffer(v8::Isolate* isolate, void* val, int size) { auto buffer = node::Buffer::Copy(isolate, static_cast(val), size); @@ -581,21 +572,6 @@ void Window::SetFocusable(bool focusable) { return window_->SetFocusable(focusable); } -void Window::CapturePage(mate::Arguments* args) { - gfx::Rect rect; - base::Callback 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) { window_->SetProgressBar(progress); } @@ -673,6 +649,12 @@ bool Window::IsWindowMessageHooked(UINT message) { void Window::UnhookAllWindowMessages() { messages_callback_map_.clear(); } + +bool Window::SetThumbnailClip(const gfx::Rect& region) { + auto window = static_cast(window_.get()); + return window->taskbar_host().SetThumbnailClip( + window_->GetAcceleratedWidget(), region); +} #endif #if defined(TOOLKIT_VIEWS) @@ -843,7 +825,6 @@ void Window::BuildPrototype(v8::Isolate* isolate, .SetMethod("focusOnWebView", &Window::FocusOnWebView) .SetMethod("blurWebView", &Window::BlurWebView) .SetMethod("isWebViewFocused", &Window::IsWebViewFocused) - .SetMethod("capturePage", &Window::CapturePage) .SetMethod("setProgressBar", &Window::SetProgressBar) .SetMethod("setOverlayIcon", &Window::SetOverlayIcon) .SetMethod("setThumbarButtons", &Window::SetThumbarButtons) @@ -861,6 +842,7 @@ void Window::BuildPrototype(v8::Isolate* isolate, .SetMethod("isWindowMessageHooked", &Window::IsWindowMessageHooked) .SetMethod("unhookWindowMessage", &Window::UnhookWindowMessage) .SetMethod("unhookAllWindowMessages", &Window::UnhookAllWindowMessages) + .SetMethod("setThumbnailClip", &Window::SetThumbnailClip) #endif #if defined(TOOLKIT_VIEWS) .SetMethod("setIcon", &Window::SetIcon) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index a204b70e296c..7736f835f745 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -155,7 +155,6 @@ class Window : public mate::TrackableObject, void SetIgnoreMouseEvents(bool ignore); void SetContentProtection(bool enable); void SetFocusable(bool focusable); - void CapturePage(mate::Arguments* args); void SetProgressBar(double progress); void SetOverlayIcon(const gfx::Image& overlay, const std::string& description); @@ -180,6 +179,7 @@ class Window : public mate::TrackableObject, bool IsWindowMessageHooked(UINT message); void UnhookWindowMessage(UINT message); void UnhookAllWindowMessages(); + bool SetThumbnailClip(const gfx::Rect& region); #endif #if defined(TOOLKIT_VIEWS) diff --git a/atom/browser/api/event.cc b/atom/browser/api/event.cc index 2554e4ad0dab..8c60eda24713 100644 --- a/atom/browser/api/event.cc +++ b/atom/browser/api/event.cc @@ -12,8 +12,8 @@ namespace mate { Event::Event(v8::Isolate* isolate) - : sender_(NULL), - message_(NULL) { + : sender_(nullptr), + message_(nullptr) { Init(isolate); } @@ -31,8 +31,8 @@ void Event::SetSenderAndMessage(content::WebContents* sender, } void Event::WebContentsDestroyed() { - sender_ = NULL; - message_ = NULL; + sender_ = nullptr; + message_ = nullptr; } void Event::PreventDefault(v8::Isolate* isolate) { @@ -41,13 +41,13 @@ void Event::PreventDefault(v8::Isolate* isolate) { } bool Event::SendReply(const base::string16& json) { - if (message_ == NULL || sender_ == NULL) + if (message_ == nullptr || sender_ == nullptr) return false; AtomViewHostMsg_Message_Sync::WriteReplyParams(message_, json); bool success = sender_->Send(message_); - message_ = NULL; - sender_ = NULL; + message_ = nullptr; + sender_ = nullptr; return success; } diff --git a/atom/browser/atom_access_token_store.cc b/atom/browser/atom_access_token_store.cc index 42b04c5db6d8..5a4482b00b41 100644 --- a/atom/browser/atom_access_token_store.cc +++ b/atom/browser/atom_access_token_store.cc @@ -25,7 +25,6 @@ const char* kGeolocationProviderURL = } // namespace AtomAccessTokenStore::AtomAccessTokenStore() { - LOG(ERROR) << "AtomAccessTokenStore"; content::GeolocationProvider::GetInstance()->UserDidOptIntoLocationServices(); } @@ -47,8 +46,8 @@ void AtomAccessTokenStore::SaveAccessToken(const GURL& server_url, } void AtomAccessTokenStore::GetRequestContextOnUIThread() { - auto browser_context = brightray::BrowserContext::From("", false); - request_context_getter_ = browser_context->url_request_context_getter(); + auto browser_context = AtomBrowserContext::From("", false); + request_context_getter_ = browser_context->GetRequestContext(); } void AtomAccessTokenStore::RespondOnOriginatingThread( diff --git a/atom/browser/atom_browser_context.cc b/atom/browser/atom_browser_context.cc index 30617166a153..d87047ce283c 100644 --- a/atom/browser/atom_browser_context.cc +++ b/atom/browser/atom_browser_context.cc @@ -63,10 +63,10 @@ std::string RemoveWhitespace(const std::string& str) { } // namespace -AtomBrowserContext::AtomBrowserContext(const std::string& partition, - bool in_memory) +AtomBrowserContext::AtomBrowserContext( + const std::string& partition, bool in_memory, + const base::DictionaryValue& options) : brightray::BrowserContext(partition, in_memory), - cert_verifier_(new AtomCertVerifier), network_delegate_(new AtomNetworkDelegate) { // Construct user agent string. Browser* browser = Browser::Get(); @@ -83,6 +83,10 @@ AtomBrowserContext::AtomBrowserContext(const std::string& partition, CHROME_VERSION_STRING); } user_agent_ = content::BuildUserAgentFromProduct(user_agent); + + // Read options. + use_cache_ = true; + options.GetBoolean("cache", &use_cache_); } AtomBrowserContext::~AtomBrowserContext() { @@ -145,7 +149,7 @@ net::HttpCache::BackendFactory* AtomBrowserContext::CreateHttpCacheBackendFactory( const base::FilePath& base_path) { base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - if (command_line->HasSwitch(switches::kDisableHttpCache)) + if (!use_cache_ || command_line->HasSwitch(switches::kDisableHttpCache)) return new NoCacheBackend; else return brightray::BrowserContext::CreateHttpCacheBackendFactory(base_path); @@ -174,7 +178,7 @@ content::PermissionManager* AtomBrowserContext::GetPermissionManager() { } std::unique_ptr AtomBrowserContext::CreateCertVerifier() { - return base::WrapUnique(cert_verifier_); + return base::WrapUnique(new AtomCertVerifier); } net::SSLConfigService* AtomBrowserContext::CreateSSLConfigService() { @@ -191,14 +195,15 @@ void AtomBrowserContext::RegisterPrefs(PrefRegistrySimple* pref_registry) { pref_registry->RegisterDictionaryPref(prefs::kDevToolsFileSystemPaths); } -} // namespace atom - -namespace brightray { - // static -scoped_refptr BrowserContext::Create( - const std::string& partition, bool in_memory) { - return make_scoped_refptr(new atom::AtomBrowserContext(partition, in_memory)); +scoped_refptr AtomBrowserContext::From( + const std::string& partition, bool in_memory, + const base::DictionaryValue& options) { + auto browser_context = brightray::BrowserContext::Get(partition, in_memory); + if (browser_context) + return static_cast(browser_context.get()); + + return new AtomBrowserContext(partition, in_memory, options); } -} // namespace brightray +} // namespace atom diff --git a/atom/browser/atom_browser_context.h b/atom/browser/atom_browser_context.h index f793bc9870d6..ed3817da6033 100644 --- a/atom/browser/atom_browser_context.h +++ b/atom/browser/atom_browser_context.h @@ -12,15 +12,18 @@ namespace atom { class AtomDownloadManagerDelegate; -class AtomCertVerifier; class AtomNetworkDelegate; class AtomPermissionManager; class WebViewManager; class AtomBrowserContext : public brightray::BrowserContext { public: - AtomBrowserContext(const std::string& partition, bool in_memory); - ~AtomBrowserContext() override; + // Get or create the BrowserContext according to its |partition| and + // |in_memory|. The |options| will be passed to constructor when there is no + // existing BrowserContext. + static scoped_refptr From( + const std::string& partition, bool in_memory, + const base::DictionaryValue& options = base::DictionaryValue()); void SetUserAgent(const std::string& user_agent); @@ -42,17 +45,21 @@ class AtomBrowserContext : public brightray::BrowserContext { // brightray::BrowserContext: void RegisterPrefs(PrefRegistrySimple* pref_registry) override; - AtomCertVerifier* cert_verifier() const { return cert_verifier_; } AtomNetworkDelegate* network_delegate() const { return network_delegate_; } + protected: + AtomBrowserContext(const std::string& partition, bool in_memory, + const base::DictionaryValue& options); + ~AtomBrowserContext() override; + private: std::unique_ptr download_manager_delegate_; std::unique_ptr guest_manager_; std::unique_ptr permission_manager_; std::string user_agent_; + bool use_cache_; // Managed by brightray::BrowserContext. - AtomCertVerifier* cert_verifier_; AtomNetworkDelegate* network_delegate_; DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext); diff --git a/atom/browser/atom_browser_main_parts.cc b/atom/browser/atom_browser_main_parts.cc index 73e4e5e7353f..a8d18e8c5afc 100644 --- a/atom/browser/atom_browser_main_parts.cc +++ b/atom/browser/atom_browser_main_parts.cc @@ -32,7 +32,7 @@ void Erase(T* container, typename T::iterator iter) { } // static -AtomBrowserMainParts* AtomBrowserMainParts::self_ = NULL; +AtomBrowserMainParts* AtomBrowserMainParts::self_ = nullptr; AtomBrowserMainParts::AtomBrowserMainParts() : fake_browser_process_(new BrowserProcess), diff --git a/atom/browser/atom_browser_main_parts_posix.cc b/atom/browser/atom_browser_main_parts_posix.cc index 2a0dddc47483..8c96f91bfe68 100644 --- a/atom/browser/atom_browser_main_parts_posix.cc +++ b/atom/browser/atom_browser_main_parts_posix.cc @@ -43,7 +43,7 @@ void GracefulShutdownHandler(int signal) { struct sigaction action; memset(&action, 0, sizeof(action)); action.sa_handler = SIG_DFL; - RAW_CHECK(sigaction(signal, &action, NULL) == 0); + RAW_CHECK(sigaction(signal, &action, nullptr) == 0); RAW_CHECK(g_pipe_pid == getpid()); RAW_CHECK(g_shutdown_pipe_write_fd != -1); @@ -171,7 +171,7 @@ void AtomBrowserMainParts::HandleSIGCHLD() { struct sigaction action; memset(&action, 0, sizeof(action)); action.sa_handler = SIGCHLDHandler; - CHECK_EQ(sigaction(SIGCHLD, &action, NULL), 0); + CHECK_EQ(sigaction(SIGCHLD, &action, nullptr), 0); } void AtomBrowserMainParts::HandleShutdownSignals() { @@ -211,15 +211,15 @@ void AtomBrowserMainParts::HandleShutdownSignals() { struct sigaction action; memset(&action, 0, sizeof(action)); action.sa_handler = SIGTERMHandler; - CHECK_EQ(sigaction(SIGTERM, &action, NULL), 0); + CHECK_EQ(sigaction(SIGTERM, &action, nullptr), 0); // Also handle SIGINT - when the user terminates the browser via Ctrl+C. If // the browser process is being debugged, GDB will catch the SIGINT first. action.sa_handler = SIGINTHandler; - CHECK_EQ(sigaction(SIGINT, &action, NULL), 0); + CHECK_EQ(sigaction(SIGINT, &action, nullptr), 0); // And SIGHUP, for when the terminal disappears. On shutdown, many Linux // distros send SIGHUP, SIGTERM, and then SIGKILL. action.sa_handler = SIGHUPHandler; - CHECK_EQ(sigaction(SIGHUP, &action, NULL), 0); + CHECK_EQ(sigaction(SIGHUP, &action, nullptr), 0); } } // namespace atom diff --git a/atom/browser/atom_resource_dispatcher_host_delegate.cc b/atom/browser/atom_resource_dispatcher_host_delegate.cc index 1115aa049d69..c64a21d26dd8 100644 --- a/atom/browser/atom_resource_dispatcher_host_delegate.cc +++ b/atom/browser/atom_resource_dispatcher_host_delegate.cc @@ -7,6 +7,7 @@ #include "atom/browser/login_handler.h" #include "atom/browser/web_contents_permission_helper.h" #include "atom/common/platform_util.h" +#include "base/strings/utf_string_conversions.h" #include "content/public/browser/browser_thread.h" #include "net/base/escape.h" #include "url/gurl.h" @@ -20,7 +21,13 @@ namespace { void OnOpenExternal(const GURL& escaped_url, bool allowed) { if (allowed) - platform_util::OpenExternal(escaped_url, true); + platform_util::OpenExternal( +#if defined(OS_WIN) + base::UTF8ToUTF16(escaped_url.spec()), +#else + escaped_url, +#endif + true); } void HandleExternalProtocolInUI( diff --git a/atom/browser/auto_updater.cc b/atom/browser/auto_updater.cc index 5a14eda2e147..8ada3ff6ab3d 100644 --- a/atom/browser/auto_updater.cc +++ b/atom/browser/auto_updater.cc @@ -17,6 +17,10 @@ void AutoUpdater::SetDelegate(Delegate* delegate) { } #if !defined(OS_MACOSX) || defined(MAS_BUILD) +std::string AutoUpdater::GetFeedURL() { + return ""; +} + void AutoUpdater::SetFeedURL(const std::string& url, const HeaderMap& requestHeaders) { } diff --git a/atom/browser/auto_updater.h b/atom/browser/auto_updater.h index ad0b2cc18b9a..aa4ca19cf21f 100644 --- a/atom/browser/auto_updater.h +++ b/atom/browser/auto_updater.h @@ -49,6 +49,7 @@ class AutoUpdater { static Delegate* GetDelegate(); static void SetDelegate(Delegate* delegate); + static std::string GetFeedURL(); static void SetFeedURL(const std::string& url, const HeaderMap& requestHeaders); static void CheckForUpdates(); diff --git a/atom/browser/auto_updater_mac.mm b/atom/browser/auto_updater_mac.mm index 005627e6c089..1987f33621d8 100644 --- a/atom/browser/auto_updater_mac.mm +++ b/atom/browser/auto_updater_mac.mm @@ -25,9 +25,14 @@ SQRLUpdater* g_updater = nil; namespace { bool g_update_available = false; +std::string update_url_ = ""; } +std::string AutoUpdater::GetFeedURL() { + return update_url_; +} + // static void AutoUpdater::SetFeedURL(const std::string& feed, const HeaderMap& requestHeaders) { @@ -35,6 +40,8 @@ void AutoUpdater::SetFeedURL(const std::string& feed, if (!delegate) return; + update_url_ = feed; + NSURL* url = [NSURL URLWithString:base::SysUTF8ToNSString(feed)]; NSMutableURLRequest* urlRequest = [NSMutableURLRequest requestWithURL:url]; diff --git a/atom/browser/browser.cc b/atom/browser/browser.cc index b7d5626a82e3..dd958d0dc7d2 100644 --- a/atom/browser/browser.cc +++ b/atom/browser/browser.cc @@ -155,6 +155,12 @@ void Browser::DidFinishLaunching() { FOR_EACH_OBSERVER(BrowserObserver, observers_, OnFinishLaunching()); } +void Browser::OnAccessibilitySupportChanged() { + FOR_EACH_OBSERVER(BrowserObserver, + observers_, + OnAccessibilitySupportChanged()); +} + void Browser::RequestLogin( LoginHandler* login_handler, std::unique_ptr request_details) { diff --git a/atom/browser/browser.h b/atom/browser/browser.h index 37d2e11e6799..771a29a87a42 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -25,16 +25,13 @@ class DictionaryValue; class FilePath; } -namespace ui { -class MenuModel; -} - namespace gfx { class Image; } namespace atom { +class AtomMenuModel; class LoginHandler; // This class is used for control application-wide operations. @@ -91,6 +88,17 @@ class Browser : public WindowListObserver { bool SetBadgeCount(int count); int GetBadgeCount(); + // Set/Get the login item settings of the app + struct LoginItemSettings { + bool open_at_login = false; + bool open_as_hidden = false; + bool restore_state = false; + bool opened_at_login = false; + bool opened_as_hidden = false; + }; + void SetLoginItemSettings(LoginItemSettings settings); + LoginItemSettings GetLoginItemSettings(); + #if defined(OS_MACOSX) // Hide the application. void Hide(); @@ -130,7 +138,7 @@ class Browser : public WindowListObserver { void DockShow(); // Set docks' menu. - void DockSetMenu(ui::MenuModel* model); + void DockSetMenu(AtomMenuModel* model); // Set docks' icon. void DockSetIcon(const gfx::Image& image); @@ -174,6 +182,8 @@ class Browser : public WindowListObserver { void WillFinishLaunching(); void DidFinishLaunching(); + void OnAccessibilitySupportChanged(); + // Request basic auth login. void RequestLogin(LoginHandler* login_handler, std::unique_ptr request_details); diff --git a/atom/browser/browser_linux.cc b/atom/browser/browser_linux.cc index fe1a0af9ba3a..6aff6027266f 100644 --- a/atom/browser/browser_linux.cc +++ b/atom/browser/browser_linux.cc @@ -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 { return brightray::GetApplicationVersion(); } diff --git a/atom/browser/browser_mac.mm b/atom/browser/browser_mac.mm index bb789365ffb2..d4b615e73efb 100644 --- a/atom/browser/browser_mac.mm +++ b/atom/browser/browser_mac.mm @@ -11,6 +11,7 @@ #include "atom/browser/window_list.h" #include "base/mac/bundle_locations.h" #include "base/mac/foundation_util.h" +#include "base/mac/mac_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/sys_string_conversions.h" #include "brightray/common/application_info.h" @@ -148,6 +149,23 @@ bool Browser::ContinueUserActivity(const std::string& type, return prevent_default; } +Browser::LoginItemSettings Browser::GetLoginItemSettings() { + LoginItemSettings settings; + settings.open_at_login = base::mac::CheckLoginItemStatus( + &settings.open_as_hidden); + settings.restore_state = base::mac::WasLaunchedAsLoginItemRestoreState(); + settings.opened_at_login = base::mac::WasLaunchedAsLoginOrResumeItem(); + settings.opened_as_hidden = base::mac::WasLaunchedAsHiddenLoginItem(); + return settings; +} + +void Browser::SetLoginItemSettings(LoginItemSettings settings) { + if (settings.open_at_login) + base::mac::AddToLoginItems(settings.open_as_hidden); + else + base::mac::RemoveFromLoginItems(); +} + std::string Browser::GetExecutableFileVersion() const { return brightray::GetApplicationVersion(); } @@ -216,7 +234,7 @@ void Browser::DockShow() { } } -void Browser::DockSetMenu(ui::MenuModel* model) { +void Browser::DockSetMenu(AtomMenuModel* model) { AtomApplicationDelegate* delegate = (AtomApplicationDelegate*)[NSApp delegate]; [delegate setApplicationDockMenu:model]; } diff --git a/atom/browser/browser_observer.h b/atom/browser/browser_observer.h index 6e85b599d038..54617e5e09fa 100644 --- a/atom/browser/browser_observer.h +++ b/atom/browser/browser_observer.h @@ -52,6 +52,9 @@ class BrowserObserver { virtual void OnLogin(LoginHandler* login_handler, const base::DictionaryValue& request_details) {} + // The browser's accessibility suppport has changed. + virtual void OnAccessibilitySupportChanged() {} + #if defined(OS_MACOSX) // The browser wants to resume a user activity via handoff. (macOS only) virtual void OnContinueUserActivity( diff --git a/atom/browser/browser_win.cc b/atom/browser/browser_win.cc index 56820789dd3c..059b28909425 100644 --- a/atom/browser/browser_win.cc +++ b/atom/browser/browser_win.cc @@ -272,6 +272,39 @@ bool Browser::SetBadgeCount(int count) { return false; } +void Browser::SetLoginItemSettings(LoginItemSettings settings) { + std::wstring keyPath = L"Software\\Microsoft\\Windows\\CurrentVersion\\Run"; + base::win::RegKey key(HKEY_CURRENT_USER, keyPath.c_str(), KEY_ALL_ACCESS); + + if (settings.open_at_login) { + base::FilePath path; + if (PathService::Get(base::FILE_EXE, &path)) { + std::wstring exePath(path.value()); + key.WriteValue(GetAppUserModelID(), exePath.c_str()); + } + } else { + key.DeleteValue(GetAppUserModelID()); + } +} + +Browser::LoginItemSettings Browser::GetLoginItemSettings() { + LoginItemSettings settings; + std::wstring keyPath = L"Software\\Microsoft\\Windows\\CurrentVersion\\Run"; + base::win::RegKey key(HKEY_CURRENT_USER, keyPath.c_str(), KEY_ALL_ACCESS); + std::wstring keyVal; + + if (!FAILED(key.ReadValue(GetAppUserModelID(), &keyVal))) { + base::FilePath path; + if (PathService::Get(base::FILE_EXE, &path)) { + std::wstring exePath(path.value()); + settings.open_at_login = keyVal == exePath; + } + } + + return settings; +} + + PCWSTR Browser::GetAppUserModelID() { if (app_user_model_id_.empty()) { SetAppUserModelID(base::ReplaceStringPlaceholders( diff --git a/atom/browser/common_web_contents_delegate.cc b/atom/browser/common_web_contents_delegate.cc index c275d4aee74e..f2f0ee8aec53 100644 --- a/atom/browser/common_web_contents_delegate.cc +++ b/atom/browser/common_web_contents_delegate.cc @@ -94,7 +94,7 @@ FileSystem CreateFileSystemStruct( } base::DictionaryValue* CreateFileSystemValue(const FileSystem& file_system) { - base::DictionaryValue* file_system_value = new base::DictionaryValue(); + auto* file_system_value = new base::DictionaryValue(); file_system_value->SetString("fileSystemName", file_system.file_system_name); file_system_value->SetString("rootURL", file_system.root_url); file_system_value->SetString("fileSystemPath", file_system.file_system_path); @@ -377,7 +377,7 @@ content::SecurityStyle CommonWebContentsDelegate::GetSecurityStyle( void CommonWebContentsDelegate::DevToolsSaveToFile( const std::string& url, const std::string& content, bool save_as) { base::FilePath path; - PathsMap::iterator it = saved_files_.find(url); + auto it = saved_files_.find(url); if (it != saved_files_.end() && !save_as) { path = it->second; } else { @@ -402,7 +402,7 @@ void CommonWebContentsDelegate::DevToolsSaveToFile( void CommonWebContentsDelegate::DevToolsAppendToFile( const std::string& url, const std::string& content) { - PathsMap::iterator it = saved_files_.find(url); + auto it = saved_files_.find(url); if (it == saved_files_.end()) return; @@ -435,8 +435,8 @@ void CommonWebContentsDelegate::DevToolsRequestFileSystems() { } base::ListValue file_system_value; - for (size_t i = 0; i < file_systems.size(); ++i) - file_system_value.Append(CreateFileSystemValue(file_systems[i])); + for (const auto& file_system : file_systems) + file_system_value.Append(CreateFileSystemValue(file_system)); web_contents_->CallClientFunction("DevToolsAPI.fileSystemsLoaded", &file_system_value, nullptr, nullptr); } @@ -610,9 +610,8 @@ void CommonWebContentsDelegate::OnDevToolsSearchCompleted( const std::string& file_system_path, const std::vector& file_paths) { base::ListValue file_paths_value; - for (std::vector::const_iterator it(file_paths.begin()); - it != file_paths.end(); ++it) { - file_paths_value.AppendString(*it); + for (const auto& file_path : file_paths) { + file_paths_value.AppendString(file_path); } base::FundamentalValue request_id_value(request_id); base::StringValue file_system_path_value(file_system_path); diff --git a/atom/browser/common_web_contents_delegate_mac.mm b/atom/browser/common_web_contents_delegate_mac.mm index aa675408305a..34df15bb0c2c 100644 --- a/atom/browser/common_web_contents_delegate_mac.mm +++ b/atom/browser/common_web_contents_delegate_mac.mm @@ -27,6 +27,11 @@ void CommonWebContentsDelegate::HandleKeyboardEvent( if (event.windowsKeyCode == ui::VKEY_ESCAPE && is_html_fullscreen()) 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) [event.os_event.window redispatchKeyEvent:event.os_event]; } diff --git a/atom/browser/mac/atom_application.mm b/atom/browser/mac/atom_application.mm index ea64af3a04d2..159852a59a83 100644 --- a/atom/browser/mac/atom_application.mm +++ b/atom/browser/mac/atom_application.mm @@ -83,6 +83,8 @@ } else { ax_state->DisableAccessibility(); } + + atom::Browser::Get()->OnAccessibilitySupportChanged(); } @end diff --git a/atom/browser/mac/atom_application_delegate.h b/atom/browser/mac/atom_application_delegate.h index 3e5c59c3ff3d..777475213ecf 100644 --- a/atom/browser/mac/atom_application_delegate.h +++ b/atom/browser/mac/atom_application_delegate.h @@ -11,9 +11,7 @@ base::scoped_nsobject menu_controller_; } -- (id)init; - // Sets the menu that will be returned in "applicationDockMenu:". -- (void)setApplicationDockMenu:(ui::MenuModel*)model; +- (void)setApplicationDockMenu:(atom::AtomMenuModel*)model; @end diff --git a/atom/browser/mac/atom_application_delegate.mm b/atom/browser/mac/atom_application_delegate.mm index 84caae9d5ee3..e77bd125201b 100644 --- a/atom/browser/mac/atom_application_delegate.mm +++ b/atom/browser/mac/atom_application_delegate.mm @@ -12,14 +12,9 @@ @implementation AtomApplicationDelegate -- (id)init { - self = [super init]; - menu_controller_.reset([[AtomMenuController alloc] init]); - return self; -} - -- (void)setApplicationDockMenu:(ui::MenuModel*)model { - [menu_controller_ populateWithModel:model]; +- (void)setApplicationDockMenu:(atom::AtomMenuModel*)model { + menu_controller_.reset([[AtomMenuController alloc] initWithModel:model + useDefaultAccelerator:NO]); } - (void)applicationWillFinishLaunching:(NSNotification*)notify { @@ -34,7 +29,10 @@ } - (NSMenu*)applicationDockMenu:(NSApplication*)sender { - return [menu_controller_ menu]; + if (menu_controller_) + return [menu_controller_ menu]; + else + return nil; } - (BOOL)application:(NSApplication*)sender diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 131beebd79bd..287b3c1d7de0 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -11,6 +11,7 @@ #include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_browser_main_parts.h" #include "atom/browser/browser.h" +#include "atom/browser/unresponsive_suppressor.h" #include "atom/browser/window_list.h" #include "atom/common/api/api_messages.h" #include "atom/common/native_mate_converters/file_path_converter.h" @@ -53,7 +54,6 @@ NativeWindow::NativeWindow( transparent_(false), enable_larger_than_screen_(false), is_closed_(false), - has_dialog_attached_(false), sheet_offset_x_(0.0), sheet_offset_y_(0.0), aspect_ratio_(0.0), @@ -210,7 +210,7 @@ gfx::Size NativeWindow::GetContentSize() { void NativeWindow::SetSizeConstraints( const extensions::SizeConstraints& window_constraints) { - extensions::SizeConstraints content_constraints; + extensions::SizeConstraints content_constraints(GetContentSizeConstraints()); if (window_constraints.HasMaximumSize()) content_constraints.set_maximum_size( WindowSizeToContentSize(window_constraints.GetMaximumSize())); @@ -291,11 +291,7 @@ bool NativeWindow::IsDocumentEdited() { void NativeWindow::SetFocusable(bool focusable) { } -void NativeWindow::SetMenu(ui::MenuModel* menu) { -} - -bool NativeWindow::HasModalDialog() { - return has_dialog_attached_; +void NativeWindow::SetMenu(AtomMenuModel* menu) { } void NativeWindow::SetParentWindow(NativeWindow* parent) { @@ -315,39 +311,6 @@ bool NativeWindow::IsWebViewFocused() { return host_view && host_view->HasFocus(); } -void NativeWindow::CapturePage(const gfx::Rect& rect, - const CapturePageCallback& callback) { - const auto view = web_contents()->GetRenderWidgetHostView(); - const auto host = view ? view->GetRenderWidgetHost() : nullptr; - if (!view || !host) { - callback.Run(SkBitmap()); - return; - } - - // Capture full page if user doesn't specify a |rect|. - const gfx::Size view_size = rect.IsEmpty() ? view->GetViewBounds().size() : - rect.size(); - - // By default, the requested bitmap size is the view size in screen - // coordinates. However, if there's more pixel detail available on the - // current system, increase the requested bitmap size to capture it all. - gfx::Size bitmap_size = view_size; - const gfx::NativeView native_view = view->GetNativeView(); - const float scale = - display::Screen::GetScreen()->GetDisplayNearestWindow(native_view) - .device_scale_factor(); - if (scale > 1.0f) - bitmap_size = gfx::ScaleToCeiledSize(view_size, scale); - - host->CopyFromBackingStore( - gfx::Rect(rect.origin(), view_size), - bitmap_size, - base::Bind(&NativeWindow::OnCapturePageDone, - weak_factory_.GetWeakPtr(), - callback), - kBGRA_8888_SkColorType); -} - void NativeWindow::SetAutoHideMenuBar(bool auto_hide) { } @@ -624,7 +587,7 @@ void NativeWindow::ScheduleUnresponsiveEvent(int ms) { void NativeWindow::NotifyWindowUnresponsive() { window_unresposive_closure_.Cancel(); - if (!is_closed_ && !HasModalDialog() && IsEnabled()) + if (!is_closed_ && !IsUnresponsiveEventSuppressed() && IsEnabled()) FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnRendererUnresponsive()); @@ -634,10 +597,4 @@ void NativeWindow::NotifyReadyToShow() { FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnReadyToShow()); } -void NativeWindow::OnCapturePageDone(const CapturePageCallback& callback, - const SkBitmap& bitmap, - content::ReadbackResponse response) { - callback.Run(bitmap); -} - } // namespace atom diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 6c7ac826b6f2..b932c6317b08 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -12,6 +12,7 @@ #include "atom/browser/native_window_observer.h" #include "atom/browser/ui/accelerator_util.h" +#include "atom/browser/ui/atom_menu_model.h" #include "base/cancelable_callback.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" @@ -43,10 +44,6 @@ namespace mate { class Dictionary; } -namespace ui { -class MenuModel; -} - namespace atom { struct DraggableRegion; @@ -54,28 +51,7 @@ struct DraggableRegion; class NativeWindow : public base::SupportsUserData, public content::WebContentsObserver { public: - using CapturePageCallback = base::Callback; - - class DialogScope { - public: - explicit DialogScope(NativeWindow* window) - : window_(window) { - if (window_ != NULL) - window_->set_has_dialog_attached(true); - } - - ~DialogScope() { - if (window_ != NULL) - window_->set_has_dialog_attached(false); - } - - private: - NativeWindow* window_; - - DISALLOW_COPY_AND_ASSIGN(DialogScope); - }; - - virtual ~NativeWindow(); + ~NativeWindow() override; // Create window with existing WebContents, the caller is responsible for // managing the window's live. @@ -159,8 +135,7 @@ class NativeWindow : public base::SupportsUserData, virtual void SetIgnoreMouseEvents(bool ignore) = 0; virtual void SetContentProtection(bool enable) = 0; virtual void SetFocusable(bool focusable); - virtual void SetMenu(ui::MenuModel* menu); - virtual bool HasModalDialog(); + virtual void SetMenu(AtomMenuModel* menu); virtual void SetParentWindow(NativeWindow* parent); virtual gfx::NativeWindow GetNativeWindow() = 0; virtual gfx::AcceleratedWidget GetAcceleratedWidget() = 0; @@ -179,11 +154,6 @@ class NativeWindow : public base::SupportsUserData, virtual void BlurWebView(); virtual bool IsWebViewFocused(); - // Captures the page with |rect|, |callback| would be called when capturing is - // done. - virtual void CapturePage(const gfx::Rect& rect, - const CapturePageCallback& callback); - // Toggle the menu bar. virtual void SetAutoHideMenuBar(bool auto_hide); virtual bool IsMenuBarAutoHide(); @@ -255,10 +225,6 @@ class NativeWindow : public base::SupportsUserData, SkRegion* draggable_region() const { return draggable_region_.get(); } bool enable_larger_than_screen() const { return enable_larger_than_screen_; } - void set_has_dialog_attached(bool has_dialog_attached) { - has_dialog_attached_ = has_dialog_attached; - } - NativeWindow* parent() const { return parent_; } bool is_modal() const { return is_modal_; } @@ -296,11 +262,6 @@ class NativeWindow : public base::SupportsUserData, // Dispatch ReadyToShow event to observers. void NotifyReadyToShow(); - // Called when CapturePage has done. - void OnCapturePageDone(const CapturePageCallback& callback, - const SkBitmap& bitmap, - content::ReadbackResponse response); - // Whether window has standard frame. bool has_frame_; @@ -320,9 +281,6 @@ class NativeWindow : public base::SupportsUserData, // The windows has been closed. bool is_closed_; - // There is a dialog that has been attached to window. - bool has_dialog_attached_; - // Closure that would be called when window is unresponsive when closing, // it should be cancelled when we can prove that the window is responsive. base::CancelableClosure window_unresposive_closure_; diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index d07d586a8439..d09faa18f6c6 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -80,7 +80,6 @@ class NativeWindowMac : public NativeWindow { bool IsDocumentEdited() override; void SetIgnoreMouseEvents(bool ignore) override; void SetContentProtection(bool enable) override; - bool HasModalDialog() override; void SetParentWindow(NativeWindow* parent) override; gfx::NativeWindow GetNativeWindow() override; gfx::AcceleratedWidget GetAcceleratedWidget() override; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index adf7f41e4373..743e308d594a 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -241,13 +241,6 @@ bool ScopedDisableResize::disable_resize_ = false; } - (void)windowDidExitFullScreen:(NSNotification*)notification { - // For certain versions of macOS the fullscreen button will automatically show - // after exiting fullscreen mode. - if (!shell_->has_frame()) { - NSWindow* window = shell_->GetNativeWindow(); - [[window standardWindowButton:NSWindowFullScreenButton] setHidden:YES]; - } - shell_->NotifyWindowLeaveFullScreen(); } @@ -732,13 +725,22 @@ bool NativeWindowMac::IsFullscreen() const { } void NativeWindowMac::SetBounds(const gfx::Rect& bounds, bool animate) { - NSRect cocoa_bounds = NSMakeRect(bounds.x(), 0, - bounds.width(), - bounds.height()); + // Do nothing if in fullscreen mode. + if (IsFullscreen()) + return; + + // Check size constraints since setFrame does not check it. + gfx::Size size = bounds.size(); + size.SetToMax(GetMinimumSize()); + gfx::Size max_size = GetMaximumSize(); + if (!max_size.IsEmpty()) + size.SetToMin(max_size); + + NSRect cocoa_bounds = NSMakeRect(bounds.x(), 0, size.width(), size.height()); // Flip coordinates based on the primary screen. NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; cocoa_bounds.origin.y = - NSHeight([screen frame]) - bounds.height() - bounds.y(); + NSHeight([screen frame]) - size.height() - bounds.y(); [window_ setFrame:cocoa_bounds display:YES animate:animate]; } @@ -790,13 +792,13 @@ bool NativeWindowMac::IsResizable() { void NativeWindowMac::SetAspectRatio(double aspect_ratio, const gfx::Size& extra_size) { - NativeWindow::SetAspectRatio(aspect_ratio, extra_size); + NativeWindow::SetAspectRatio(aspect_ratio, extra_size); - // Reset the behaviour to default if aspect_ratio is set to 0 or less. - if (aspect_ratio > 0.0) - [window_ setAspectRatio:NSMakeSize(aspect_ratio, 1.0)]; - else - [window_ setResizeIncrements:NSMakeSize(1.0, 1.0)]; + // Reset the behaviour to default if aspect_ratio is set to 0 or less. + if (aspect_ratio > 0.0) + [window_ setAspectRatio:NSMakeSize(aspect_ratio, 1.0)]; + else + [window_ setResizeIncrements:NSMakeSize(1.0, 1.0)]; } void NativeWindowMac::SetMovable(bool movable) { @@ -950,10 +952,6 @@ void NativeWindowMac::SetContentProtection(bool enable) { : NSWindowSharingReadOnly]; } -bool NativeWindowMac::HasModalDialog() { - return [window_ attachedSheet] != nil; -} - void NativeWindowMac::SetParentWindow(NativeWindow* parent) { if (is_modal()) return; @@ -1072,7 +1070,10 @@ void NativeWindowMac::UpdateDraggableRegions( void NativeWindowMac::InstallView() { // Make sure the bottom corner is rounded: http://crbug.com/396264. - [[window_ contentView] setWantsLayer:YES]; + // But do not enable it on OS X 10.9 for transparent window, otherwise a + // semi-transparent frame would show. + if (!(transparent() && base::mac::IsOSMavericks())) + [[window_ contentView] setWantsLayer:YES]; NSView* view = inspectable_web_contents()->GetView()->GetNativeView(); if (has_frame()) { @@ -1092,6 +1093,9 @@ void NativeWindowMac::InstallView() { [view setFrame:[content_view_ bounds]]; [content_view_ addSubview:view]; + // The fullscreen button should always be hidden for frameless window. + [[window_ standardWindowButton:NSWindowFullScreenButton] setHidden:YES]; + if (title_bar_style_ != NORMAL) return; diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index fe80a52bb50d..c516a2e323de 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -23,6 +23,7 @@ #include "ui/aura/window_tree_host.h" #include "ui/base/hit_test.h" #include "ui/gfx/image/image.h" +#include "ui/gfx/screen.h" #include "ui/views/background.h" #include "ui/views/controls/webview/unhandled_keyboard_event_handler.h" #include "ui/views/controls/webview/webview.h" @@ -135,6 +136,10 @@ NativeWindowViews::NativeWindowViews( menu_bar_autohide_(false), menu_bar_visible_(false), menu_bar_alt_pressed_(false), +#if defined(OS_WIN) + enabled_a11y_support_(false), + thick_frame_(true), +#endif keyboard_event_handler_(new views::UnhandledKeyboardEventHandler), disable_count_(0), use_content_size_(false), @@ -152,6 +157,11 @@ NativeWindowViews::NativeWindowViews( options.Get(options::kResizable, &resizable_); options.Get(options::kMinimizable, &minimizable_); options.Get(options::kMaximizable, &maximizable_); + + // Transparent window must not have thick frame. + options.Get("thickFrame", &thick_frame_); + if (transparent()) + thick_frame_ = false; #endif if (enable_larger_than_screen()) @@ -214,6 +224,9 @@ NativeWindowViews::NativeWindowViews( bool fullscreen = false; options.Get(options::kFullscreen, &fullscreen); + std::string window_type; + options.Get(options::kType, &window_type); + #if defined(USE_X11) // Start monitoring window states. window_state_watcher_.reset(new WindowStateWatcher(this)); @@ -243,9 +256,6 @@ NativeWindowViews::NativeWindowViews( state_atom_list.push_back(GetAtom("_NET_WM_STATE_FULLSCREEN")); } - std::string window_type; - options.Get(options::kType, &window_type); - if (parent) { SetParentWindow(parent); // Force using dialog type for child window. @@ -269,13 +279,6 @@ NativeWindowViews::NativeWindowViews( AddChildView(web_view_); #if defined(OS_WIN) - // Save initial window state. - if (fullscreen) - last_window_state_ = ui::SHOW_STATE_FULLSCREEN; - else - last_window_state_ = ui::SHOW_STATE_NORMAL; - last_normal_size_ = gfx::Size(widget_size_); - if (!has_frame()) { // Set Window style so that we get a minimize and maximize animation when // frameless. @@ -287,17 +290,18 @@ NativeWindowViews::NativeWindowViews( if (maximizable_) frame_style |= WS_MAXIMIZEBOX; // We should not show a frame for transparent window. - if (transparent()) + if (!thick_frame_) frame_style &= ~(WS_THICKFRAME | WS_CAPTION); ::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, frame_style); } - if (transparent()) { - // Transparent window on Windows has to have WS_EX_COMPOSITED style. - LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE); + LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE); + // Window without thick frame has to have WS_EX_COMPOSITED style. + if (!thick_frame_) ex_style |= WS_EX_COMPOSITED; - ::SetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE, ex_style); - } + if (window_type == "toolbar") + ex_style |= WS_EX_TOOLWINDOW; + ::SetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE, ex_style); #endif // TODO(zcbenz): This was used to force using native frame on Windows 2003, we @@ -315,6 +319,15 @@ NativeWindowViews::NativeWindowViews( window_->CenterWindow(size); Layout(); + +#if defined(OS_WIN) + // Save initial window state. + if (fullscreen) + last_window_state_ = ui::SHOW_STATE_FULLSCREEN; + else + last_window_state_ = ui::SHOW_STATE_NORMAL; + last_normal_bounds_ = GetBounds(); +#endif } NativeWindowViews::~NativeWindowViews() { @@ -410,6 +423,17 @@ bool NativeWindowViews::IsEnabled() { } void NativeWindowViews::Maximize() { +#if defined(OS_WIN) + // For window without WS_THICKFRAME style, we can not call Maximize(). + if (!thick_frame_) { + restore_bounds_ = GetBounds(); + auto display = + gfx::Screen::GetScreen()->GetDisplayNearestPoint(GetPosition()); + SetBounds(display.work_area(), false); + return; + } +#endif + if (IsVisible()) window_->Maximize(); else @@ -418,6 +442,13 @@ void NativeWindowViews::Maximize() { } void NativeWindowViews::Unmaximize() { +#if defined(OS_WIN) + if (!thick_frame_) { + SetBounds(restore_bounds_, false); + return; + } +#endif + window_->Restore(); } @@ -454,6 +485,20 @@ void NativeWindowViews::SetFullScreen(bool fullscreen) { last_window_state_ = ui::SHOW_STATE_NORMAL; NotifyWindowLeaveFullScreen(); } + + // For window without WS_THICKFRAME style, we can not call SetFullscreen(). + if (!thick_frame_) { + if (fullscreen) { + restore_bounds_ = GetBounds(); + auto display = + gfx::Screen::GetScreen()->GetDisplayNearestPoint(GetPosition()); + SetBounds(display.bounds(), false); + } else { + SetBounds(restore_bounds_, false); + } + return; + } + // We set the new value after notifying, so we can handle the size event // correctly. window_->SetFullscreen(fullscreen); @@ -463,6 +508,12 @@ void NativeWindowViews::SetFullScreen(bool fullscreen) { else window_->native_widget_private()->ShowWithWindowState( ui::SHOW_STATE_FULLSCREEN); + + // Auto-hide menubar when in fullscreen. + if (fullscreen) + SetMenuBarVisibility(false); + else + SetMenuBarVisibility(!menu_bar_autohide_); #endif } @@ -470,8 +521,7 @@ bool NativeWindowViews::IsFullscreen() const { return window_->IsFullscreen(); } -void NativeWindowViews::SetBounds(const gfx::Rect& bounds, - bool animate = false) { +void NativeWindowViews::SetBounds(const gfx::Rect& bounds, bool animate) { #if defined(USE_X11) // On Linux the minimum and maximum size should be updated with window size // when window is not resizable. @@ -517,7 +567,7 @@ void NativeWindowViews::SetContentSizeConstraints( void NativeWindowViews::SetResizable(bool resizable) { #if defined(OS_WIN) - if (!transparent()) + if (thick_frame_) FlipWindowStyle(GetAcceleratedWidget(), resizable, WS_THICKFRAME); #elif defined(USE_X11) if (resizable != resizable_) { @@ -540,7 +590,11 @@ void NativeWindowViews::SetResizable(bool resizable) { bool NativeWindowViews::IsResizable() { #if defined(OS_WIN) - return ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_THICKFRAME; + if (thick_frame_) { + return ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_THICKFRAME; + } else { + return CanResize(); + } #else return CanResize(); #endif @@ -752,7 +806,7 @@ void NativeWindowViews::SetFocusable(bool focusable) { #endif } -void NativeWindowViews::SetMenu(ui::MenuModel* menu_model) { +void NativeWindowViews::SetMenu(AtomMenuModel* menu_model) { if (menu_model == nullptr) { // Remove accelerators accelerator_table_.clear(); @@ -1188,7 +1242,7 @@ bool NativeWindowViews::AcceleratorPressed(const ui::Accelerator& accelerator) { &accelerator_table_, accelerator); } -void NativeWindowViews::RegisterAccelerators(ui::MenuModel* menu_model) { +void NativeWindowViews::RegisterAccelerators(AtomMenuModel* menu_model) { // Clear previous accelerators. views::FocusManager* focus_manager = GetFocusManager(); accelerator_table_.clear(); diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 71f3741f2fad..7ad5e8ec292b 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -98,7 +98,7 @@ class NativeWindowViews : public NativeWindow, void SetIgnoreMouseEvents(bool ignore) override; void SetContentProtection(bool enable) override; void SetFocusable(bool focusable) override; - void SetMenu(ui::MenuModel* menu_model) override; + void SetMenu(AtomMenuModel* menu_model) override; void SetParentWindow(NativeWindow* parent) override; gfx::NativeWindow GetNativeWindow() override; void SetOverlayIcon(const gfx::Image& overlay, @@ -176,7 +176,7 @@ class NativeWindowViews : public NativeWindow, bool AcceleratorPressed(const ui::Accelerator& accelerator) override; // Register accelerators supported by the menu model. - void RegisterAccelerators(ui::MenuModel* menu_model); + void RegisterAccelerators(AtomMenuModel* menu_model); // Returns the restore state for the window. ui::WindowShowState GetRestoredState(); @@ -212,7 +212,7 @@ class NativeWindowViews : public NativeWindow, // to receive the wrong size (#2498). To circumvent that, we keep tabs on the // size of the window while in the normal state (not maximized, minimized or // fullscreen), so we restore it correctly. - gfx::Size last_normal_size_; + gfx::Rect last_normal_bounds_; // In charge of running taskbar related APIs. TaskbarHost taskbar_host_; @@ -220,6 +220,12 @@ class NativeWindowViews : public NativeWindow, // If true we have enabled a11y bool enabled_a11y_support_; + // Whether to show the WS_THICKFRAME style. + bool thick_frame_; + + // The bounds of window before maximize/fullscreen. + gfx::Rect restore_bounds_; + // The icons of window and taskbar. base::win::ScopedHICON window_icon_; base::win::ScopedHICON app_icon_; diff --git a/atom/browser/native_window_views_win.cc b/atom/browser/native_window_views_win.cc index 038ab105222d..9af003d55db0 100644 --- a/atom/browser/native_window_views_win.cc +++ b/atom/browser/native_window_views_win.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. +#include "atom/browser/browser.h" #include "atom/browser/native_window_views.h" #include "content/public/browser/browser_accessibility_state.h" @@ -98,6 +99,7 @@ bool NativeWindowViews::PreHandleMSG( if (axState && !axState->IsAccessibleBrowser()) { axState->OnScreenReaderDetected(); enabled_a11y_support_ = true; + Browser::Get()->OnAccessibilitySupportChanged(); } } @@ -140,7 +142,7 @@ void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) { case SIZE_RESTORED: if (last_window_state_ == ui::SHOW_STATE_NORMAL) { // Window was resized so we save it's new size. - last_normal_size_ = GetSize(); + last_normal_bounds_ = GetBounds(); } else { switch (last_window_state_) { case ui::SHOW_STATE_MAXIMIZED: @@ -148,7 +150,7 @@ void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) { // When the window is restored we resize it to the previous known // normal size. - NativeWindow::SetSize(last_normal_size_); + SetBounds(last_normal_bounds_, false); NotifyWindowUnmaximize(); break; @@ -161,7 +163,7 @@ void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) { // When the window is restored we resize it to the previous known // normal size. - NativeWindow::SetSize(last_normal_size_); + SetBounds(last_normal_bounds_, false); NotifyWindowRestore(); } diff --git a/atom/browser/net/asar/asar_protocol_handler.cc b/atom/browser/net/asar/asar_protocol_handler.cc index 324f8339c8c9..ffa2b3c9f288 100644 --- a/atom/browser/net/asar/asar_protocol_handler.cc +++ b/atom/browser/net/asar/asar_protocol_handler.cc @@ -22,7 +22,7 @@ net::URLRequestJob* AsarProtocolHandler::MaybeCreateJob( net::NetworkDelegate* network_delegate) const { base::FilePath full_path; net::FileURLToFilePath(request->url(), &full_path); - URLRequestAsarJob* job = new URLRequestAsarJob(request, network_delegate); + auto* job = new URLRequestAsarJob(request, network_delegate); job->Initialize(file_task_runner_, full_path); return job; } diff --git a/atom/browser/net/asar/url_request_asar_job.cc b/atom/browser/net/asar/url_request_asar_job.cc index 95a1bd175145..ad3a4c2724b3 100644 --- a/atom/browser/net/asar/url_request_asar_job.cc +++ b/atom/browser/net/asar/url_request_asar_job.cc @@ -111,7 +111,7 @@ void URLRequestAsarJob::Start() { if (rv != net::ERR_IO_PENDING) DidOpen(rv); } else if (type_ == TYPE_FILE) { - FileMetaInfo* meta_info = new FileMetaInfo(); + auto* meta_info = new FileMetaInfo(); file_task_runner_->PostTaskAndReply( FROM_HERE, base::Bind(&URLRequestAsarJob::FetchMetaInfo, file_path_, @@ -224,7 +224,7 @@ int URLRequestAsarJob::GetResponseCode() const { void URLRequestAsarJob::GetResponseInfo(net::HttpResponseInfo* info) { std::string status("HTTP/1.1 200 OK"); - net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status); + auto* headers = new net::HttpResponseHeaders(status); headers->AddHeader(atom::kCORSHeader); info->headers = headers; @@ -338,7 +338,7 @@ void URLRequestAsarJob::DidRead(scoped_refptr buf, int result) { DCHECK_GE(remaining_bytes_, 0); } - buf = NULL; + buf = nullptr; ReadRawDataComplete(result); } diff --git a/atom/browser/net/atom_cert_verifier.cc b/atom/browser/net/atom_cert_verifier.cc index adfba7060c90..dd588b9501ce 100644 --- a/atom/browser/net/atom_cert_verifier.cc +++ b/atom/browser/net/atom_cert_verifier.cc @@ -36,7 +36,6 @@ AtomCertVerifier::~AtomCertVerifier() { } void AtomCertVerifier::SetVerifyProc(const VerifyProc& proc) { - base::AutoLock auto_lock(lock_); verify_proc_ = proc; } @@ -52,20 +51,14 @@ int AtomCertVerifier::Verify( const net::BoundNetLog& net_log) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - VerifyProc proc; - { - base::AutoLock auto_lock(lock_); - proc = verify_proc_; - } - - if (proc.is_null()) + if (verify_proc_.is_null()) return default_cert_verifier_->Verify( cert, hostname, ocsp_response, flags, crl_set, verify_result, callback, out_req, net_log); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, - base::Bind(proc, hostname, make_scoped_refptr(cert), + base::Bind(verify_proc_, hostname, make_scoped_refptr(cert), base::Bind(OnResult, verify_result, callback))); return net::ERR_IO_PENDING; } diff --git a/atom/browser/net/atom_cert_verifier.h b/atom/browser/net/atom_cert_verifier.h index e00ba260ec3f..c8b4bf9290bb 100644 --- a/atom/browser/net/atom_cert_verifier.h +++ b/atom/browser/net/atom_cert_verifier.h @@ -5,10 +5,9 @@ #ifndef ATOM_BROWSER_NET_ATOM_CERT_VERIFIER_H_ #define ATOM_BROWSER_NET_ATOM_CERT_VERIFIER_H_ +#include #include -#include "base/memory/ref_counted.h" -#include "base/synchronization/lock.h" #include "net/cert/cert_verifier.h" namespace atom { @@ -39,7 +38,6 @@ class AtomCertVerifier : public net::CertVerifier { bool SupportsOCSPStapling() override; private: - base::Lock lock_; VerifyProc verify_proc_; std::unique_ptr default_cert_verifier_; diff --git a/atom/browser/net/atom_url_request_job_factory.cc b/atom/browser/net/atom_url_request_job_factory.cc index d78b7026e563..7e2eb95149ca 100644 --- a/atom/browser/net/atom_url_request_job_factory.cc +++ b/atom/browser/net/atom_url_request_job_factory.cc @@ -20,14 +20,14 @@ typedef net::URLRequestJobFactory::ProtocolHandler ProtocolHandler; AtomURLRequestJobFactory::AtomURLRequestJobFactory() {} AtomURLRequestJobFactory::~AtomURLRequestJobFactory() { - STLDeleteValues(&protocol_handler_map_); + Clear(); } bool AtomURLRequestJobFactory::SetProtocolHandler( const std::string& scheme, std::unique_ptr protocol_handler) { if (!protocol_handler) { - ProtocolHandlerMap::iterator it = protocol_handler_map_.find(scheme); + auto it = protocol_handler_map_.find(scheme); if (it == protocol_handler_map_.end()) return false; @@ -66,7 +66,7 @@ ProtocolHandler* AtomURLRequestJobFactory::GetProtocolHandler( const std::string& scheme) const { DCHECK_CURRENTLY_ON(BrowserThread::IO); - ProtocolHandlerMap::const_iterator it = protocol_handler_map_.find(scheme); + auto it = protocol_handler_map_.find(scheme); if (it == protocol_handler_map_.end()) return nullptr; return it->second; @@ -77,13 +77,17 @@ bool AtomURLRequestJobFactory::HasProtocolHandler( return ContainsKey(protocol_handler_map_, scheme); } +void AtomURLRequestJobFactory::Clear() { + STLDeleteValues(&protocol_handler_map_); +} + net::URLRequestJob* AtomURLRequestJobFactory::MaybeCreateJobWithProtocolHandler( const std::string& scheme, net::URLRequest* request, net::NetworkDelegate* network_delegate) const { DCHECK_CURRENTLY_ON(BrowserThread::IO); - ProtocolHandlerMap::const_iterator it = protocol_handler_map_.find(scheme); + auto it = protocol_handler_map_.find(scheme); if (it == protocol_handler_map_.end()) return nullptr; return it->second->MaybeCreateJob(request, network_delegate); diff --git a/atom/browser/net/atom_url_request_job_factory.h b/atom/browser/net/atom_url_request_job_factory.h index ea2710bb4cf3..5b439c2f9cd8 100644 --- a/atom/browser/net/atom_url_request_job_factory.h +++ b/atom/browser/net/atom_url_request_job_factory.h @@ -39,6 +39,9 @@ class AtomURLRequestJobFactory : public net::URLRequestJobFactory { // Whether the protocol handler is registered by the job factory. bool HasProtocolHandler(const std::string& scheme) const; + // Clear all protocol handlers. + void Clear(); + // URLRequestJobFactory implementation net::URLRequestJob* MaybeCreateJobWithProtocolHandler( const std::string& scheme, diff --git a/atom/browser/net/url_request_async_asar_job.cc b/atom/browser/net/url_request_async_asar_job.cc index 1234bccf4303..942f06233e3d 100644 --- a/atom/browser/net/url_request_async_asar_job.cc +++ b/atom/browser/net/url_request_async_asar_job.cc @@ -40,7 +40,7 @@ void URLRequestAsyncAsarJob::StartAsync(std::unique_ptr options) { void URLRequestAsyncAsarJob::GetResponseInfo(net::HttpResponseInfo* info) { std::string status("HTTP/1.1 200 OK"); - net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status); + auto* headers = new net::HttpResponseHeaders(status); headers->AddHeader(kCORSHeader); info->headers = headers; diff --git a/atom/browser/net/url_request_buffer_job.cc b/atom/browser/net/url_request_buffer_job.cc index c713099c76a1..70f460308174 100644 --- a/atom/browser/net/url_request_buffer_job.cc +++ b/atom/browser/net/url_request_buffer_job.cc @@ -72,7 +72,7 @@ void URLRequestBufferJob::GetResponseInfo(net::HttpResponseInfo* info) { status.append(" "); status.append(net::GetHttpReasonPhrase(status_code_)); status.append("\0\0", 2); - net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status); + auto* headers = new net::HttpResponseHeaders(status); headers->AddHeader(kCORSHeader); diff --git a/atom/browser/net/url_request_string_job.cc b/atom/browser/net/url_request_string_job.cc index 59945e66db07..abec345e63d5 100644 --- a/atom/browser/net/url_request_string_job.cc +++ b/atom/browser/net/url_request_string_job.cc @@ -31,7 +31,7 @@ void URLRequestStringJob::StartAsync(std::unique_ptr options) { void URLRequestStringJob::GetResponseInfo(net::HttpResponseInfo* info) { std::string status("HTTP/1.1 200 OK"); - net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status); + auto* headers = new net::HttpResponseHeaders(status); headers->AddHeader(kCORSHeader); diff --git a/atom/browser/relauncher_linux.cc b/atom/browser/relauncher_linux.cc index 2fbbd47faf03..6d60b072f6d9 100644 --- a/atom/browser/relauncher_linux.cc +++ b/atom/browser/relauncher_linux.cc @@ -4,11 +4,13 @@ #include "atom/browser/relauncher.h" +#include #include #include #include #include "base/files/file_util.h" +#include "base/files/scoped_file.h" #include "base/logging.h" #include "base/posix/eintr_wrapper.h" #include "base/process/launch.h" @@ -55,9 +57,17 @@ void RelauncherSynchronizeWithParent() { int LaunchProgram(const StringVector& relauncher_args, const StringVector& argv) { + // Redirect the stdout of child process to /dev/null, otherwise after + // relaunch the child process will raise exception when writing to stdout. + base::ScopedFD devnull(HANDLE_EINTR(open("/dev/null", O_WRONLY))); + base::FileHandleMappingVector no_stdout; + no_stdout.push_back(std::make_pair(devnull.get(), STDERR_FILENO)); + no_stdout.push_back(std::make_pair(devnull.get(), STDOUT_FILENO)); + base::LaunchOptions options; options.allow_new_privs = true; options.new_process_group = true; // detach + options.fds_to_remap = &no_stdout; base::Process process = base::LaunchProcess(argv, options); return process.IsValid() ? 0 : 1; } diff --git a/atom/browser/relauncher_mac.cc b/atom/browser/relauncher_mac.cc index ef26f8441df6..6e288502455b 100644 --- a/atom/browser/relauncher_mac.cc +++ b/atom/browser/relauncher_mac.cc @@ -43,7 +43,7 @@ void RelauncherSynchronizeWithParent() { struct kevent change = { 0 }; EV_SET(&change, parent_pid, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, NULL); - if (kevent(kq.get(), &change, 1, NULL, 0, NULL) == -1) { + if (kevent(kq.get(), &change, 1, nullptr, 0, nullptr) == -1) { PLOG(ERROR) << "kevent (add)"; return; } @@ -58,7 +58,7 @@ void RelauncherSynchronizeWithParent() { // write above to complete. The parent process is now free to exit. Wait for // that to happen. struct kevent event; - int events = kevent(kq.get(), NULL, 0, &event, 1, NULL); + int events = kevent(kq.get(), nullptr, 0, &event, 1, nullptr); if (events != 1) { if (events < 0) { PLOG(ERROR) << "kevent (monitor)"; @@ -79,8 +79,16 @@ void RelauncherSynchronizeWithParent() { int LaunchProgram(const StringVector& relauncher_args, const StringVector& argv) { + // Redirect the stdout of child process to /dev/null, otherwise after + // relaunch the child process will raise exception when writing to stdout. + base::ScopedFD devnull(HANDLE_EINTR(open("/dev/null", O_WRONLY))); + base::FileHandleMappingVector no_stdout; + no_stdout.push_back(std::make_pair(devnull.get(), STDERR_FILENO)); + no_stdout.push_back(std::make_pair(devnull.get(), STDOUT_FILENO)); + base::LaunchOptions options; options.new_process_group = true; // detach + options.fds_to_remap = &no_stdout; base::Process process = base::LaunchProcess(argv, options); return process.IsValid() ? 0 : 1; } diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index 33cfc66b2718..7d46960a4656 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,9 +17,9 @@ CFBundleIconFile electron.icns CFBundleVersion - 1.2.5 + 1.2.8 CFBundleShortVersionString - 1.2.5 + 1.2.8 LSApplicationCategoryType public.app-category.developer-tools LSMinimumSystemVersion diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 91101128feda..05a14e9d58ea 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -56,8 +56,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,5,0 - PRODUCTVERSION 1,2,5,0 + FILEVERSION 1,2,8,0 + PRODUCTVERSION 1,2,8,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "1.2.5" + VALUE "FileVersion", "1.2.8" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "1.2.5" + VALUE "ProductVersion", "1.2.8" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/browser/ui/accelerator_util.cc b/atom/browser/ui/accelerator_util.cc index f683c99c637f..eb89bf0c35f5 100644 --- a/atom/browser/ui/accelerator_util.cc +++ b/atom/browser/ui/accelerator_util.cc @@ -14,7 +14,6 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" -#include "ui/base/models/simple_menu_model.h" namespace accelerator_util { @@ -31,9 +30,9 @@ bool StringToAccelerator(const std::string& shortcut, // Now, parse it into an accelerator. int modifiers = ui::EF_NONE; ui::KeyboardCode key = ui::VKEY_UNKNOWN; - for (size_t i = 0; i < tokens.size(); i++) { + for (const auto& token : tokens) { bool shifted = false; - ui::KeyboardCode code = atom::KeyboardCodeFromStr(tokens[i], &shifted); + ui::KeyboardCode code = atom::KeyboardCodeFromStr(token, &shifted); if (shifted) modifiers |= ui::EF_SHIFT_DOWN; switch (code) { @@ -69,16 +68,17 @@ bool StringToAccelerator(const std::string& shortcut, return true; } -void GenerateAcceleratorTable(AcceleratorTable* table, ui::MenuModel* model) { +void GenerateAcceleratorTable(AcceleratorTable* table, + atom::AtomMenuModel* model) { int count = model->GetItemCount(); for (int i = 0; i < count; ++i) { - ui::MenuModel::ItemType type = model->GetTypeAt(i); - if (type == ui::MenuModel::TYPE_SUBMENU) { - ui::MenuModel* submodel = model->GetSubmenuModelAt(i); + atom::AtomMenuModel::ItemType type = model->GetTypeAt(i); + if (type == atom::AtomMenuModel::TYPE_SUBMENU) { + auto submodel = model->GetSubmenuModelAt(i); GenerateAcceleratorTable(table, submodel); } else { ui::Accelerator accelerator; - if (model->GetAcceleratorAt(i, &accelerator)) { + if (model->GetAcceleratorAtWithParams(i, true, &accelerator)) { MenuItem item = { i, model }; (*table)[accelerator] = item; } diff --git a/atom/browser/ui/accelerator_util.h b/atom/browser/ui/accelerator_util.h index 584041980b4c..38f206f5376d 100644 --- a/atom/browser/ui/accelerator_util.h +++ b/atom/browser/ui/accelerator_util.h @@ -8,15 +8,12 @@ #include #include +#include "atom/browser/ui/atom_menu_model.h" #include "ui/base/accelerators/accelerator.h" -namespace ui { -class MenuModel; -} - namespace accelerator_util { -typedef struct { int position; ui::MenuModel* model; } MenuItem; +typedef struct { int position; atom::AtomMenuModel* model; } MenuItem; typedef std::map AcceleratorTable; // Parse a string as an accelerator. @@ -27,7 +24,8 @@ bool StringToAccelerator(const std::string& description, void SetPlatformAccelerator(ui::Accelerator* accelerator); // Generate a table that contains memu model's accelerators and command ids. -void GenerateAcceleratorTable(AcceleratorTable* table, ui::MenuModel* model); +void GenerateAcceleratorTable(AcceleratorTable* table, + atom::AtomMenuModel* model); // Trigger command from the accelerators table. bool TriggerAcceleratorTableCommand(AcceleratorTable* table, diff --git a/atom/browser/ui/atom_menu_model.cc b/atom/browser/ui/atom_menu_model.cc index 369684dd3f21..de3465e8ab08 100644 --- a/atom/browser/ui/atom_menu_model.cc +++ b/atom/browser/ui/atom_menu_model.cc @@ -29,9 +29,25 @@ base::string16 AtomMenuModel::GetRoleAt(int index) { return base::string16(); } +bool AtomMenuModel::GetAcceleratorAtWithParams( + int index, + bool use_default_accelerator, + ui::Accelerator* accelerator) const { + if (delegate_) { + return delegate_->GetAcceleratorForCommandIdWithParams( + GetCommandIdAt(index), use_default_accelerator, accelerator); + } + return false; +} + void AtomMenuModel::MenuClosed() { ui::SimpleMenuModel::MenuClosed(); FOR_EACH_OBSERVER(Observer, observers_, MenuClosed()); } +AtomMenuModel* AtomMenuModel::GetSubmenuModelAt(int index) { + return static_cast( + ui::SimpleMenuModel::GetSubmenuModelAt(index)); +} + } // namespace atom diff --git a/atom/browser/ui/atom_menu_model.h b/atom/browser/ui/atom_menu_model.h index 1112949e7efa..887f6123bcca 100644 --- a/atom/browser/ui/atom_menu_model.h +++ b/atom/browser/ui/atom_menu_model.h @@ -17,6 +17,19 @@ class AtomMenuModel : public ui::SimpleMenuModel { class Delegate : public ui::SimpleMenuModel::Delegate { public: virtual ~Delegate() {} + + virtual bool GetAcceleratorForCommandIdWithParams( + int command_id, + bool use_default_accelerator, + ui::Accelerator* accelerator) const = 0; + + private: + // ui::SimpleMenuModel::Delegate: + bool GetAcceleratorForCommandId(int command_id, + ui::Accelerator* accelerator) { + return GetAcceleratorForCommandIdWithParams( + command_id, false, accelerator); + } }; class Observer { @@ -35,10 +48,16 @@ class AtomMenuModel : public ui::SimpleMenuModel { void SetRole(int index, const base::string16& role); base::string16 GetRoleAt(int index); + bool GetAcceleratorAtWithParams(int index, + bool use_default_accelerator, + ui::Accelerator* accelerator) const; // ui::SimpleMenuModel: void MenuClosed() override; + using SimpleMenuModel::GetSubmenuModelAt; + AtomMenuModel* GetSubmenuModelAt(int index); + private: Delegate* delegate_; // weak ref. diff --git a/atom/browser/ui/cocoa/atom_menu_controller.h b/atom/browser/ui/cocoa/atom_menu_controller.h index f8c48aa5dcb5..af0b27696185 100644 --- a/atom/browser/ui/cocoa/atom_menu_controller.h +++ b/atom/browser/ui/cocoa/atom_menu_controller.h @@ -11,8 +11,8 @@ #include "base/mac/scoped_nsobject.h" #include "base/strings/string16.h" -namespace ui { -class MenuModel; +namespace atom { +class AtomMenuModel; } // A controller for the cross-platform menu model. The menu that's created @@ -23,24 +23,20 @@ class MenuModel; // as it only maintains weak references. @interface AtomMenuController : NSObject { @protected - ui::MenuModel* model_; // weak + atom::AtomMenuModel* model_; // weak base::scoped_nsobject menu_; BOOL isMenuOpen_; + BOOL useDefaultAccelerator_; } -@property(nonatomic, assign) ui::MenuModel* model; - -// NIB-based initializer. This does not create a menu. Clients can set the -// properties of the object and the menu will be created upon the first call to -// |-menu|. Note that the menu will be immutable after creation. -- (id)init; +@property(nonatomic, assign) atom::AtomMenuModel* model; // Builds a NSMenu from the pre-built model (must not be nil). Changes made // to the contents of the model after calling this will not be noticed. -- (id)initWithModel:(ui::MenuModel*)model; +- (id)initWithModel:(atom::AtomMenuModel*)model useDefaultAccelerator:(BOOL)use; // Populate current NSMenu with |model|. -- (void)populateWithModel:(ui::MenuModel*)model; +- (void)populateWithModel:(atom::AtomMenuModel*)model; // Programmatically close the constructed menu. - (void)cancel; diff --git a/atom/browser/ui/cocoa/atom_menu_controller.mm b/atom/browser/ui/cocoa/atom_menu_controller.mm index 536f48760589..3efd1611516f 100644 --- a/atom/browser/ui/cocoa/atom_menu_controller.mm +++ b/atom/browser/ui/cocoa/atom_menu_controller.mm @@ -48,15 +48,11 @@ Role kRolesMap[] = { @synthesize model = model_; -- (id)init { - if ((self = [super init])) - [self menu]; - return self; -} - -- (id)initWithModel:(ui::MenuModel*)model { +- (id)initWithModel:(atom::AtomMenuModel*)model useDefaultAccelerator:(BOOL)use { if ((self = [super init])) { model_ = model; + isMenuOpen_ = NO; + useDefaultAccelerator_ = use; [self menu]; } return self; @@ -73,7 +69,7 @@ Role kRolesMap[] = { [super dealloc]; } -- (void)populateWithModel:(ui::MenuModel*)model { +- (void)populateWithModel:(atom::AtomMenuModel*)model { if (!menu_) return; @@ -82,7 +78,7 @@ Role kRolesMap[] = { const int count = model->GetItemCount(); 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]; else [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 // be invoked recursively. -- (NSMenu*)menuFromModel:(ui::MenuModel*)model { +- (NSMenu*)menuFromModel:(atom::AtomMenuModel*)model { NSMenu* menu = [[[NSMenu alloc] initWithTitle:@""] autorelease]; const int count = model->GetItemCount(); 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]; else [self addItemToMenu:menu atIndex:index fromModel:model]; @@ -126,9 +122,7 @@ Role kRolesMap[] = { // associated with the entry in the model identified by |modelIndex|. - (void)addItemToMenu:(NSMenu*)menu atIndex:(NSInteger)index - fromModel:(ui::MenuModel*)ui_model { - atom::AtomMenuModel* model = static_cast(ui_model); - + fromModel:(atom::AtomMenuModel*)model { base::string16 label16 = model->GetLabelAt(index); NSString* label = l10n_util::FixUpWindowsStyleLabel(label16); base::scoped_nsobject item( @@ -141,12 +135,13 @@ Role kRolesMap[] = { if (model->GetIconAt(index, &icon) && !icon.IsEmpty()) [item setImage:icon.ToNSImage()]; - ui::MenuModel::ItemType type = model->GetTypeAt(index); - if (type == ui::MenuModel::TYPE_SUBMENU) { + atom::AtomMenuModel::ItemType type = model->GetTypeAt(index); + if (type == atom::AtomMenuModel::TYPE_SUBMENU) { // Recursively build a submenu from the sub-model at this index. [item setTarget:nil]; [item setAction:nil]; - ui::MenuModel* submenuModel = model->GetSubmenuModelAt(index); + atom::AtomMenuModel* submenuModel = static_cast( + model->GetSubmenuModelAt(index)); NSMenu* submenu = [self menuFromModel:submenuModel]; [submenu setTitle:[item title]]; [item setSubmenu:submenu]; @@ -170,7 +165,8 @@ Role kRolesMap[] = { NSValue* modelObject = [NSValue valueWithPointer:model]; [item setRepresentedObject:modelObject]; // Retains |modelObject|. ui::Accelerator accelerator; - if (model->GetAcceleratorAt(index, &accelerator)) { + if (model->GetAcceleratorAtWithParams( + index, useDefaultAccelerator_, &accelerator)) { const ui::PlatformAcceleratorCocoa* platformAccelerator = static_cast( accelerator.platform_accelerator()); @@ -206,8 +202,8 @@ Role kRolesMap[] = { return NO; NSInteger modelIndex = [item tag]; - ui::MenuModel* model = - static_cast( + atom::AtomMenuModel* model = + static_cast( [[(id)item representedObject] pointerValue]); DCHECK(model); if (model) { @@ -234,8 +230,8 @@ Role kRolesMap[] = { // item chosen. - (void)itemSelected:(id)sender { NSInteger modelIndex = [sender tag]; - ui::MenuModel* model = - static_cast( + atom::AtomMenuModel* model = + static_cast( [[sender representedObject] pointerValue]); DCHECK(model); if (model) { diff --git a/atom/browser/ui/file_dialog.h b/atom/browser/ui/file_dialog.h index b857648161b5..f65204c10e47 100644 --- a/atom/browser/ui/file_dialog.h +++ b/atom/browser/ui/file_dialog.h @@ -23,10 +23,11 @@ typedef std::pair > Filter; typedef std::vector Filters; enum FileDialogProperty { - FILE_DIALOG_OPEN_FILE = 1 << 0, - FILE_DIALOG_OPEN_DIRECTORY = 1 << 1, - FILE_DIALOG_MULTI_SELECTIONS = 1 << 2, - FILE_DIALOG_CREATE_DIRECTORY = 1 << 3, + FILE_DIALOG_OPEN_FILE = 1 << 0, + FILE_DIALOG_OPEN_DIRECTORY = 1 << 1, + FILE_DIALOG_MULTI_SELECTIONS = 1 << 2, + FILE_DIALOG_CREATE_DIRECTORY = 1 << 3, + FILE_DIALOG_SHOW_HIDDEN_FILES = 1 << 4, }; typedef base::Callback(parent_window)), - dialog_scope_(parent_window), filters_(filters) { const char* confirm_text = GTK_STOCK_OK; @@ -87,12 +87,19 @@ class FileChooserDialog { AddFilters(filters); } - virtual ~FileChooserDialog() { + ~FileChooserDialog() { gtk_widget_destroy(dialog_); if (parent_) 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() { g_signal_connect(dialog_, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL); @@ -146,7 +153,7 @@ class FileChooserDialog { base::FilePath AddExtensionForFilename(const gchar* filename) const; atom::NativeWindowViews* parent_; - atom::NativeWindow::DialogScope dialog_scope_; + atom::UnresponsiveSuppressor unresponsive_suppressor_; GtkWidget* dialog_; @@ -235,9 +242,7 @@ bool ShowOpenDialog(atom::NativeWindow* parent_window, action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER; FileChooserDialog open_dialog(action, parent_window, title, button_label, default_path, filters); - if (properties & FILE_DIALOG_MULTI_SELECTIONS) - gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(open_dialog.dialog()), - TRUE); + open_dialog.SetupProperties(properties); gtk_widget_show_all(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; FileChooserDialog* open_dialog = new FileChooserDialog( action, parent_window, title, button_label, default_path, filters); - if (properties & FILE_DIALOG_MULTI_SELECTIONS) - gtk_file_chooser_set_select_multiple( - GTK_FILE_CHOOSER(open_dialog->dialog()), TRUE); - + open_dialog->SetupProperties(properties); open_dialog->RunOpenAsynchronous(callback); } diff --git a/atom/browser/ui/file_dialog_mac.mm b/atom/browser/ui/file_dialog_mac.mm index d674817a2a41..398357b0b125 100644 --- a/atom/browser/ui/file_dialog_mac.mm +++ b/atom/browser/ui/file_dialog_mac.mm @@ -86,6 +86,8 @@ void SetupDialogForProperties(NSOpenPanel* dialog, int properties) { [dialog setCanCreateDirectories:YES]; if (properties & FILE_DIALOG_MULTI_SELECTIONS) [dialog setAllowsMultipleSelection:YES]; + if (properties & FILE_DIALOG_SHOW_HIDDEN_FILES) + [dialog setShowsHiddenFiles:YES]; } // Run modal dialog with parent window and return user's choice. diff --git a/atom/browser/ui/file_dialog_win.cc b/atom/browser/ui/file_dialog_win.cc index 5314b63a45a8..ff7d8f97235b 100644 --- a/atom/browser/ui/file_dialog_win.cc +++ b/atom/browser/ui/file_dialog_win.cc @@ -10,6 +10,7 @@ #include #include "atom/browser/native_window_views.h" +#include "atom/browser/unresponsive_suppressor.h" #include "base/files/file_util.h" #include "base/i18n/case_conversion.h" #include "base/strings/string_util.h" @@ -108,7 +109,7 @@ class FileDialog { } bool Show(atom::NativeWindow* parent_window) { - atom::NativeWindow::DialogScope dialog_scope(parent_window); + atom::UnresponsiveSuppressor suppressor; HWND window = parent_window ? static_cast( parent_window)->GetAcceleratedWidget() : NULL; @@ -201,6 +202,8 @@ bool ShowOpenDialog(atom::NativeWindow* parent_window, options |= FOS_PICKFOLDERS; if (properties & FILE_DIALOG_MULTI_SELECTIONS) options |= FOS_ALLOWMULTISELECT; + if (properties & FILE_DIALOG_SHOW_HIDDEN_FILES) + options |= FOS_FORCESHOWHIDDEN; FileDialog open_dialog( default_path, title, button_label, filters, options); diff --git a/atom/browser/ui/message_box_gtk.cc b/atom/browser/ui/message_box_gtk.cc index d08171c6e426..8f11c94b7d3c 100644 --- a/atom/browser/ui/message_box_gtk.cc +++ b/atom/browser/ui/message_box_gtk.cc @@ -6,6 +6,7 @@ #include "atom/browser/browser.h" #include "atom/browser/native_window_views.h" +#include "atom/browser/unresponsive_suppressor.h" #include "base/callback.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" @@ -35,8 +36,7 @@ class GtkMessageBox { const std::string& message, const std::string& detail, const gfx::ImageSkia& icon) - : dialog_scope_(parent_window), - cancel_id_(cancel_id), + : cancel_id_(cancel_id), parent_(static_cast(parent_window)) { // Create dialog. dialog_ = gtk_message_dialog_new( @@ -147,7 +147,7 @@ class GtkMessageBox { CHROMEGTK_CALLBACK_1(GtkMessageBox, void, OnResponseDialog, int); private: - atom::NativeWindow::DialogScope dialog_scope_; + atom::UnresponsiveSuppressor unresponsive_suppressor_; // The id to return when the dialog is closed without pressing buttons. int cancel_id_; diff --git a/atom/browser/ui/message_box_win.cc b/atom/browser/ui/message_box_win.cc index b966ef92a8fd..e5615fb1fc11 100644 --- a/atom/browser/ui/message_box_win.cc +++ b/atom/browser/ui/message_box_win.cc @@ -12,6 +12,7 @@ #include "atom/browser/browser.h" #include "atom/browser/native_window_views.h" +#include "atom/browser/unresponsive_suppressor.h" #include "base/callback.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" @@ -198,7 +199,7 @@ int ShowMessageBox(NativeWindow* parent, static_cast(parent)->GetAcceleratedWidget() : NULL; - NativeWindow::DialogScope dialog_scope(parent); + atom::UnresponsiveSuppressor suppressor; return ShowMessageBoxUTF16(hwnd_parent, type, utf16_buttons, @@ -239,6 +240,7 @@ void ShowMessageBox(NativeWindow* parent, } void ShowErrorBox(const base::string16& title, const base::string16& content) { + atom::UnresponsiveSuppressor suppressor; ShowMessageBoxUTF16(NULL, MESSAGE_BOX_TYPE_ERROR, {}, -1, 0, 0, L"Error", title, content, gfx::ImageSkia()); } diff --git a/atom/browser/ui/tray_icon.cc b/atom/browser/ui/tray_icon.cc index fda68b09cd11..6e54af92757d 100644 --- a/atom/browser/ui/tray_icon.cc +++ b/atom/browser/ui/tray_icon.cc @@ -27,7 +27,7 @@ void TrayIcon::DisplayBalloon(ImageType icon, } void TrayIcon::PopUpContextMenu(const gfx::Point& pos, - ui::SimpleMenuModel* menu_model) { + AtomMenuModel* menu_model) { } gfx::Rect TrayIcon::GetBounds() { @@ -68,6 +68,10 @@ void TrayIcon::NotifyDropFiles(const std::vector& 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() { FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnDragEntered()); } diff --git a/atom/browser/ui/tray_icon.h b/atom/browser/ui/tray_icon.h index 2763e50941b6..78981d076c77 100644 --- a/atom/browser/ui/tray_icon.h +++ b/atom/browser/ui/tray_icon.h @@ -8,9 +8,9 @@ #include #include +#include "atom/browser/ui/atom_menu_model.h" #include "atom/browser/ui/tray_icon_observer.h" #include "base/observer_list.h" -#include "ui/base/models/simple_menu_model.h" #include "ui/gfx/geometry/rect.h" namespace atom { @@ -55,10 +55,10 @@ class TrayIcon { // Popups the menu. virtual void PopUpContextMenu(const gfx::Point& pos, - ui::SimpleMenuModel* menu_model); + AtomMenuModel* menu_model); // 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. virtual gfx::Rect GetBounds(); @@ -75,6 +75,7 @@ class TrayIcon { int modifiers = 0); void NotifyDrop(); void NotifyDropFiles(const std::vector& files); + void NotifyDropText(const std::string& text); void NotifyDragEntered(); void NotifyDragExited(); void NotifyDragEnded(); diff --git a/atom/browser/ui/tray_icon_cocoa.h b/atom/browser/ui/tray_icon_cocoa.h index cb972d54a9af..e9abaa5590e3 100644 --- a/atom/browser/ui/tray_icon_cocoa.h +++ b/atom/browser/ui/tray_icon_cocoa.h @@ -9,7 +9,6 @@ #include -#include "atom/browser/ui/atom_menu_model.h" #include "atom/browser/ui/tray_icon.h" #include "base/mac/scoped_nsobject.h" @@ -30,8 +29,8 @@ class TrayIconCocoa : public TrayIcon, void SetTitle(const std::string& title) override; void SetHighlightMode(bool highlight) override; void PopUpContextMenu(const gfx::Point& pos, - ui::SimpleMenuModel* menu_model) override; - void SetContextMenu(ui::SimpleMenuModel* menu_model) override; + AtomMenuModel* menu_model) override; + void SetContextMenu(AtomMenuModel* menu_model) override; gfx::Rect GetBounds() override; protected: diff --git a/atom/browser/ui/tray_icon_cocoa.mm b/atom/browser/ui/tray_icon_cocoa.mm index ccf5b5cd7e61..231f1bfb1282 100644 --- a/atom/browser/ui/tray_icon_cocoa.mm +++ b/atom/browser/ui/tray_icon_cocoa.mm @@ -44,7 +44,10 @@ const CGFloat kVerticalTitleMargin = 2; inMouseEventSequence_ = NO; if ((self = [super initWithFrame: CGRectZero])) { - [self registerForDraggedTypes: @[NSFilenamesPboardType]]; + [self registerForDraggedTypes: @[ + NSFilenamesPboardType, + NSStringPboardType, + ]]; // Create the status item. NSStatusItem * item = [[NSStatusBar systemStatusBar] @@ -249,11 +252,12 @@ const CGFloat kVerticalTitleMargin = 2; [self setNeedsDisplay:YES]; } -- (void)popUpContextMenu:(ui::SimpleMenuModel*)menu_model { +- (void)popUpContextMenu:(atom::AtomMenuModel*)menu_model { // Show a custom menu. if (menu_model) { base::scoped_nsobject menuController( - [[AtomMenuController alloc] initWithModel:menu_model]); + [[AtomMenuController alloc] initWithModel:menu_model + useDefaultAccelerator:NO]); forceHighlight_ = YES; // Should highlight when showing menu. [self setNeedsDisplay:YES]; [statusItem_ popUpStatusItemMenu:[menuController menu]]; @@ -306,7 +310,12 @@ const CGFloat kVerticalTitleMargin = 2; dropFiles.push_back(base::SysNSStringToUTF8(file)); trayIcon_->NotifyDropFiles(dropFiles); return YES; + } else if ([[pboard types] containsObject:NSStringPboardType]) { + NSString* dropText = [pboard stringForType:NSStringPboardType]; + trayIcon_->NotifyDropText(base::SysNSStringToUTF8(dropText)); + return YES; } + return NO; } @@ -365,18 +374,19 @@ void TrayIconCocoa::SetHighlightMode(bool highlight) { } void TrayIconCocoa::PopUpContextMenu(const gfx::Point& pos, - ui::SimpleMenuModel* menu_model) { + AtomMenuModel* menu_model) { [status_item_view_ popUpContextMenu:menu_model]; } -void TrayIconCocoa::SetContextMenu(ui::SimpleMenuModel* menu_model) { +void TrayIconCocoa::SetContextMenu(AtomMenuModel* menu_model) { // Substribe to MenuClosed event. if (menu_model_) menu_model_->RemoveObserver(this); - static_cast(menu_model)->AddObserver(this); + menu_model->AddObserver(this); // Create native menu. - menu_.reset([[AtomMenuController alloc] initWithModel:menu_model]); + menu_.reset([[AtomMenuController alloc] initWithModel:menu_model + useDefaultAccelerator:NO]); [status_item_view_ setMenuController:menu_.get()]; } diff --git a/atom/browser/ui/tray_icon_gtk.cc b/atom/browser/ui/tray_icon_gtk.cc index 3e533906090a..3286a95a7c99 100644 --- a/atom/browser/ui/tray_icon_gtk.cc +++ b/atom/browser/ui/tray_icon_gtk.cc @@ -50,7 +50,7 @@ void TrayIconGtk::SetToolTip(const std::string& 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); } diff --git a/atom/browser/ui/tray_icon_gtk.h b/atom/browser/ui/tray_icon_gtk.h index cfeb8ab3d0bf..8cb00363f08a 100644 --- a/atom/browser/ui/tray_icon_gtk.h +++ b/atom/browser/ui/tray_icon_gtk.h @@ -25,7 +25,7 @@ class TrayIconGtk : public TrayIcon, // TrayIcon: void SetImage(const gfx::Image& image) override; void SetToolTip(const std::string& tool_tip) override; - void SetContextMenu(ui::SimpleMenuModel* menu_model) override; + void SetContextMenu(AtomMenuModel* menu_model) override; private: // views::StatusIconLinux::Delegate: diff --git a/atom/browser/ui/tray_icon_observer.h b/atom/browser/ui/tray_icon_observer.h index ed421ed85452..1782e913d541 100644 --- a/atom/browser/ui/tray_icon_observer.h +++ b/atom/browser/ui/tray_icon_observer.h @@ -24,6 +24,7 @@ class TrayIconObserver { virtual void OnRightClicked(const gfx::Rect& bounds, int modifiers) {} virtual void OnDrop() {} virtual void OnDropFiles(const std::vector& files) {} + virtual void OnDropText(const std::string& text) {} virtual void OnDragEntered() {} virtual void OnDragExited() {} virtual void OnDragEnded() {} diff --git a/atom/browser/ui/views/global_menu_bar_x11.cc b/atom/browser/ui/views/global_menu_bar_x11.cc index b393e3f4657d..266d10b96db9 100644 --- a/atom/browser/ui/views/global_menu_bar_x11.cc +++ b/atom/browser/ui/views/global_menu_bar_x11.cc @@ -16,6 +16,7 @@ #include #include "atom/browser/native_window_views.h" +#include "atom/browser/ui/atom_menu_model.h" #include "base/logging.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" @@ -23,7 +24,6 @@ #include "ui/aura/window.h" #include "ui/aura/window_tree_host.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" // libdbusmenu-glib types @@ -141,8 +141,8 @@ void EnsureMethodsLoaded() { dlsym(dbusmenu_lib, "dbusmenu_server_set_root")); } -ui::MenuModel* ModelForMenuItem(DbusmenuMenuitem* item) { - return reinterpret_cast( +AtomMenuModel* ModelForMenuItem(DbusmenuMenuitem* item) { + return reinterpret_cast( 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); } -void GlobalMenuBarX11::SetMenu(ui::MenuModel* menu_model) { +void GlobalMenuBarX11::SetMenu(AtomMenuModel* menu_model) { if (!IsServerStarted()) return; @@ -218,14 +218,14 @@ void GlobalMenuBarX11::OnWindowUnmapped() { GlobalMenuBarRegistrarX11::GetInstance()->OnWindowUnmapped(xid_); } -void GlobalMenuBarX11::BuildMenuFromModel(ui::MenuModel* model, +void GlobalMenuBarX11::BuildMenuFromModel(AtomMenuModel* model, DbusmenuMenuitem* parent) { for (int i = 0; i < model->GetItemCount(); ++i) { DbusmenuMenuitem* item = menuitem_new(); menuitem_property_set_bool(item, kPropertyVisible, model->IsVisibleAt(i)); - ui::MenuModel::ItemType type = model->GetTypeAt(i); - if (type == ui::MenuModel::TYPE_SEPARATOR) { + AtomMenuModel::ItemType type = model->GetTypeAt(i); + if (type == AtomMenuModel::TYPE_SEPARATOR) { menuitem_property_set(item, kPropertyType, kTypeSeparator); } else { std::string label = ui::ConvertAcceleratorsFromWindowsStyle( @@ -236,22 +236,22 @@ void GlobalMenuBarX11::BuildMenuFromModel(ui::MenuModel* model, g_object_set_data(G_OBJECT(item), "model", model); SetMenuItemID(item, i); - if (type == ui::MenuModel::TYPE_SUBMENU) { + if (type == AtomMenuModel::TYPE_SUBMENU) { menuitem_property_set(item, kPropertyChildrenDisplay, kDisplaySubmenu); g_signal_connect(item, "about-to-show", G_CALLBACK(OnSubMenuShowThunk), this); } else { ui::Accelerator accelerator; - if (model->GetAcceleratorAt(i, &accelerator)) + if (model->GetAcceleratorAtWithParams(i, true, &accelerator)) RegisterAccelerator(item, accelerator); g_signal_connect(item, "item-activated", G_CALLBACK(OnItemActivatedThunk), this); - if (type == ui::MenuModel::TYPE_CHECK || - type == ui::MenuModel::TYPE_RADIO) { + if (type == AtomMenuModel::TYPE_CHECK || + type == AtomMenuModel::TYPE_RADIO) { menuitem_property_set(item, kPropertyToggleType, - type == ui::MenuModel::TYPE_CHECK ? kToggleCheck : kToggleRadio); + type == AtomMenuModel::TYPE_CHECK ? kToggleCheck : kToggleRadio); menuitem_property_set_int(item, kPropertyToggleState, model->IsItemCheckedAt(i)); } @@ -296,14 +296,14 @@ void GlobalMenuBarX11::RegisterAccelerator(DbusmenuMenuitem* item, void GlobalMenuBarX11::OnItemActivated(DbusmenuMenuitem* item, unsigned int timestamp) { int id; - ui::MenuModel* model = ModelForMenuItem(item); + AtomMenuModel* model = ModelForMenuItem(item); if (model && GetMenuItemID(item, &id)) model->ActivatedAt(id, 0); } void GlobalMenuBarX11::OnSubMenuShow(DbusmenuMenuitem* item) { int id; - ui::MenuModel* model = ModelForMenuItem(item); + AtomMenuModel* model = ModelForMenuItem(item); if (!model || !GetMenuItemID(item, &id)) return; diff --git a/atom/browser/ui/views/global_menu_bar_x11.h b/atom/browser/ui/views/global_menu_bar_x11.h index 89b2680cabeb..9bb4dd338559 100644 --- a/atom/browser/ui/views/global_menu_bar_x11.h +++ b/atom/browser/ui/views/global_menu_bar_x11.h @@ -7,6 +7,7 @@ #include +#include "atom/browser/ui/atom_menu_model.h" #include "base/macros.h" #include "base/compiler_specific.h" #include "ui/base/glib/glib_signal.h" @@ -17,7 +18,6 @@ typedef struct _DbusmenuServer DbusmenuServer; namespace ui { class Accelerator; -class MenuModel; } namespace atom { @@ -43,7 +43,7 @@ class GlobalMenuBarX11 { // Creates the object path for DbusmenuServer which is attached to |xid|. static std::string GetPathForWindow(gfx::AcceleratedWidget xid); - void SetMenu(ui::MenuModel* menu_model); + void SetMenu(AtomMenuModel* menu_model); bool IsServerStarted() const; // Called by NativeWindow when it show/hides. @@ -55,7 +55,7 @@ class GlobalMenuBarX11 { void InitServer(gfx::AcceleratedWidget xid); // Create a menu from menu model. - void BuildMenuFromModel(ui::MenuModel* model, DbusmenuMenuitem* parent); + void BuildMenuFromModel(AtomMenuModel* model, DbusmenuMenuitem* parent); // Sets the accelerator for |item|. void RegisterAccelerator(DbusmenuMenuitem* item, diff --git a/atom/browser/ui/views/menu_bar.cc b/atom/browser/ui/views/menu_bar.cc index 0538421bfe64..cb7af509cc8a 100644 --- a/atom/browser/ui/views/menu_bar.cc +++ b/atom/browser/ui/views/menu_bar.cc @@ -58,7 +58,7 @@ MenuBar::MenuBar() MenuBar::~MenuBar() { } -void MenuBar::SetMenu(ui::MenuModel* model) { +void MenuBar::SetMenu(AtomMenuModel* model) { menu_model_ = model; RemoveAllChildViews(true); @@ -105,7 +105,7 @@ int MenuBar::GetItemCount() const { } bool MenuBar::GetMenuButtonFromScreenPoint(const gfx::Point& point, - ui::MenuModel** menu_model, + AtomMenuModel** menu_model, views::MenuButton** button) { gfx::Point location(point); views::View::ConvertPointFromScreen(this, &location); @@ -117,7 +117,7 @@ bool MenuBar::GetMenuButtonFromScreenPoint(const gfx::Point& point, for (int i = 0; i < child_count(); ++i) { views::View* view = child_at(i); 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); *button = static_cast(view); return true; @@ -144,8 +144,8 @@ void MenuBar::OnMenuButtonClicked(views::MenuButton* source, return; int id = source->tag(); - ui::MenuModel::ItemType type = menu_model_->GetTypeAt(id); - if (type != ui::MenuModel::TYPE_SUBMENU) { + AtomMenuModel::ItemType type = menu_model_->GetTypeAt(id); + if (type != AtomMenuModel::TYPE_SUBMENU) { menu_model_->ActivatedAt(id, 0); return; } diff --git a/atom/browser/ui/views/menu_bar.h b/atom/browser/ui/views/menu_bar.h index eb62784e71ca..5b86e292c887 100644 --- a/atom/browser/ui/views/menu_bar.h +++ b/atom/browser/ui/views/menu_bar.h @@ -5,14 +5,11 @@ #ifndef 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/menu_button_listener.h" #include "ui/views/view.h" -namespace ui { -class MenuModel; -} - namespace views { class MenuButton; } @@ -29,7 +26,7 @@ class MenuBar : public views::View, virtual ~MenuBar(); // Replaces current menu with a new one. - void SetMenu(ui::MenuModel* menu_model); + void SetMenu(AtomMenuModel* menu_model); // Shows underline under accelerators. void SetAcceleratorVisibility(bool visible); @@ -46,7 +43,7 @@ class MenuBar : public views::View, // Get the menu under specified screen point. bool GetMenuButtonFromScreenPoint(const gfx::Point& point, - ui::MenuModel** menu_model, + AtomMenuModel** menu_model, views::MenuButton** button); protected: @@ -74,7 +71,7 @@ class MenuBar : public views::View, SkColor hover_color_; #endif - ui::MenuModel* menu_model_; + AtomMenuModel* menu_model_; DISALLOW_COPY_AND_ASSIGN(MenuBar); }; diff --git a/atom/browser/ui/views/menu_delegate.cc b/atom/browser/ui/views/menu_delegate.cc index a107a696250b..3a1a151b7269 100644 --- a/atom/browser/ui/views/menu_delegate.cc +++ b/atom/browser/ui/views/menu_delegate.cc @@ -5,10 +5,10 @@ #include "atom/browser/ui/views/menu_delegate.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 "ui/views/controls/button/menu_button.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/widget/widget.h" @@ -22,7 +22,7 @@ MenuDelegate::MenuDelegate(MenuBar* menu_bar) MenuDelegate::~MenuDelegate() { } -void MenuDelegate::RunMenu(ui::MenuModel* model, views::MenuButton* button) { +void MenuDelegate::RunMenu(AtomMenuModel* model, views::MenuButton* button) { gfx::Point screen_loc; views::View::ConvertPointToScreen(button, &screen_loc); // 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); id_ = button->tag(); - adapter_.reset(new views::MenuModelAdapter(model)); + adapter_.reset(new MenuModelAdapter(model)); views::MenuItemView* item = new views::MenuItemView(this); - static_cast(adapter_.get())->BuildMenu(item); + static_cast(adapter_.get())->BuildMenu(item); menu_runner_.reset(new views::MenuRunner( item, @@ -102,7 +102,7 @@ views::MenuItemView* MenuDelegate::GetSiblingMenu( bool* has_mnemonics, views::MenuButton**) { views::MenuButton* button; - ui::MenuModel* model; + AtomMenuModel* model; if (menu_bar_->GetMenuButtonFromScreenPoint(screen_point, &model, &button) && button->tag() != id_) { DCHECK(menu_runner_->IsRunning()); diff --git a/atom/browser/ui/views/menu_delegate.h b/atom/browser/ui/views/menu_delegate.h index bdc22fb4a7e4..f813f9cc7d0b 100644 --- a/atom/browser/ui/views/menu_delegate.h +++ b/atom/browser/ui/views/menu_delegate.h @@ -7,16 +7,13 @@ #include +#include "atom/browser/ui/atom_menu_model.h" #include "ui/views/controls/menu/menu_delegate.h" namespace views { class MenuRunner; } -namespace ui { -class MenuModel; -} - namespace atom { class MenuBar; @@ -26,7 +23,7 @@ class MenuDelegate : public views::MenuDelegate { explicit MenuDelegate(MenuBar* menu_bar); virtual ~MenuDelegate(); - void RunMenu(ui::MenuModel* model, views::MenuButton* button); + void RunMenu(AtomMenuModel* model, views::MenuButton* button); protected: // views::MenuDelegate: diff --git a/atom/browser/ui/views/menu_model_adapter.cc b/atom/browser/ui/views/menu_model_adapter.cc new file mode 100644 index 000000000000..303cdb9babd2 --- /dev/null +++ b/atom/browser/ui/views/menu_model_adapter.cc @@ -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(model)-> + GetAcceleratorAtWithParams(index, true, accelerator); + } + return false; +} + +} // namespace atom diff --git a/atom/browser/ui/views/menu_model_adapter.h b/atom/browser/ui/views/menu_model_adapter.h new file mode 100644 index 000000000000..4b87bc32fd56 --- /dev/null +++ b/atom/browser/ui/views/menu_model_adapter.h @@ -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_ diff --git a/atom/browser/ui/win/notify_icon.cc b/atom/browser/ui/win/notify_icon.cc index ae689eb1c5e8..e62b682e3e58 100644 --- a/atom/browser/ui/win/notify_icon.cc +++ b/atom/browser/ui/win/notify_icon.cc @@ -132,7 +132,7 @@ void NotifyIcon::DisplayBalloon(HICON icon, } void NotifyIcon::PopUpContextMenu(const gfx::Point& pos, - ui::SimpleMenuModel* menu_model) { + AtomMenuModel* menu_model) { // Returns if context menu isn't set. if (menu_model == nullptr && menu_model_ == nullptr) return; @@ -154,7 +154,7 @@ void NotifyIcon::PopUpContextMenu(const gfx::Point& pos, 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; } diff --git a/atom/browser/ui/win/notify_icon.h b/atom/browser/ui/win/notify_icon.h index 2225667cd331..ae6c9ca8a14b 100644 --- a/atom/browser/ui/win/notify_icon.h +++ b/atom/browser/ui/win/notify_icon.h @@ -51,8 +51,8 @@ class NotifyIcon : public TrayIcon { const base::string16& title, const base::string16& contents) override; void PopUpContextMenu(const gfx::Point& pos, - ui::SimpleMenuModel* menu_model) override; - void SetContextMenu(ui::SimpleMenuModel* menu_model) override; + AtomMenuModel* menu_model) override; + void SetContextMenu(AtomMenuModel* menu_model) override; gfx::Rect GetBounds() override; private: @@ -74,7 +74,7 @@ class NotifyIcon : public TrayIcon { base::win::ScopedHICON icon_; // The context menu. - ui::SimpleMenuModel* menu_model_; + AtomMenuModel* menu_model_; DISALLOW_COPY_AND_ASSIGN(NotifyIcon); }; diff --git a/atom/browser/ui/win/taskbar_host.cc b/atom/browser/ui/win/taskbar_host.cc index 78bcc578c19f..8fef5e08a3fb 100644 --- a/atom/browser/ui/win/taskbar_host.cc +++ b/atom/browser/ui/win/taskbar_host.cc @@ -142,6 +142,22 @@ bool TaskbarHost::SetOverlayIcon( 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) { if (ContainsKey(callback_map_, button_id)) { auto callback = callback_map_[button_id]; diff --git a/atom/browser/ui/win/taskbar_host.h b/atom/browser/ui/win/taskbar_host.h index 0cd5aa714fc2..c10e05f764dd 100644 --- a/atom/browser/ui/win/taskbar_host.h +++ b/atom/browser/ui/win/taskbar_host.h @@ -13,6 +13,7 @@ #include "base/callback.h" #include "base/win/scoped_comptr.h" +#include "ui/gfx/geometry/rect.h" #include "ui/gfx/image/image.h" namespace atom { @@ -40,6 +41,9 @@ class TaskbarHost { bool SetOverlayIcon( 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. bool HandleThumbarButtonEvent(int button_id); diff --git a/atom/browser/unresponsive_suppressor.cc b/atom/browser/unresponsive_suppressor.cc new file mode 100644 index 000000000000..89bfa6b9003b --- /dev/null +++ b/atom/browser/unresponsive_suppressor.cc @@ -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 diff --git a/atom/browser/unresponsive_suppressor.h b/atom/browser/unresponsive_suppressor.h new file mode 100644 index 000000000000..9fb3819237d5 --- /dev/null +++ b/atom/browser/unresponsive_suppressor.h @@ -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_ diff --git a/atom/browser/web_view_guest_delegate.cc b/atom/browser/web_view_guest_delegate.cc index 11f8219bf088..7f5a9261b93d 100644 --- a/atom/browser/web_view_guest_delegate.cc +++ b/atom/browser/web_view_guest_delegate.cc @@ -7,6 +7,7 @@ #include "atom/browser/api/atom_api_web_contents.h" #include "atom/common/native_mate_converters/gurl_converter.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_view_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; } -void WebViewGuestDelegate::DidCommitProvisionalLoadForFrame( - content::RenderFrameHost* render_frame_host, - const GURL& url, ui::PageTransition transition_type) { - api_web_contents_->Emit("load-commit", url, !render_frame_host->GetParent()); +void WebViewGuestDelegate::DidFinishNavigation( + content::NavigationHandle* navigation_handle) { + if (navigation_handle->HasCommitted() && !navigation_handle->IsErrorPage()) { + 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) { diff --git a/atom/browser/web_view_guest_delegate.h b/atom/browser/web_view_guest_delegate.h index d65eb1463586..f63a46cf76ce 100644 --- a/atom/browser/web_view_guest_delegate.h +++ b/atom/browser/web_view_guest_delegate.h @@ -47,9 +47,8 @@ class WebViewGuestDelegate : public content::BrowserPluginGuestDelegate, protected: // content::WebContentsObserver: - void DidCommitProvisionalLoadForFrame( - content::RenderFrameHost* render_frame_host, - const GURL& url, ui::PageTransition transition_type) override; + void DidFinishNavigation( + content::NavigationHandle* navigation_handle) override; // content::BrowserPluginGuestDelegate: void DidAttach(int guest_proxy_routing_id) final; diff --git a/atom/browser/window_list.cc b/atom/browser/window_list.cc index b3bec5d08c1c..83bf615aad25 100644 --- a/atom/browser/window_list.cc +++ b/atom/browser/window_list.cc @@ -17,7 +17,7 @@ base::LazyInstance>::Leaky WindowList::observers_ = LAZY_INSTANCE_INITIALIZER; // static -WindowList* WindowList::instance_ = NULL; +WindowList* WindowList::instance_ = nullptr; // static WindowList* WindowList::GetInstance() { @@ -70,8 +70,8 @@ void WindowList::RemoveObserver(WindowListObserver* observer) { // static void WindowList::CloseAllWindows() { WindowVector windows = GetInstance()->windows_; - for (size_t i = 0; i < windows.size(); ++i) - windows[i]->Close(); + for (const auto& window : windows) + window->Close(); } WindowList::WindowList() { diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index 3cd3dcc7f2ee..10a1c181b381 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -63,10 +63,10 @@ float GetScaleFactorFromPath(const base::FilePath& path) { // We don't try to convert string to float here because it is very very // expensive. - for (unsigned i = 0; i < node::arraysize(kScaleFactorPairs); ++i) { - if (base::EndsWith(filename, kScaleFactorPairs[i].name, + for (const auto& kScaleFactorPair : kScaleFactorPairs) { + if (base::EndsWith(filename, kScaleFactorPair.name, base::CompareCase::INSENSITIVE_ASCII)) - return kScaleFactorPairs[i].scale; + return kScaleFactorPair.scale; } return 1.0f; diff --git a/atom/common/api/atom_api_shell.cc b/atom/common/api/atom_api_shell.cc index f99e2ba1854e..860787f17c8f 100644 --- a/atom/common/api/atom_api_shell.cc +++ b/atom/common/api/atom_api_shell.cc @@ -7,12 +7,19 @@ #include "atom/common/platform_util.h" #include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/native_mate_converters/gurl_converter.h" +#include "atom/common/native_mate_converters/string16_converter.h" #include "atom/common/node_includes.h" #include "native_mate/dictionary.h" namespace { -bool OpenExternal(const GURL& url, mate::Arguments* args) { +bool OpenExternal( +#if defined(OS_WIN) + const base::string16& url, +#else + const GURL& url, +#endif + mate::Arguments* args) { bool activate = true; if (args->Length() == 2) { mate::Dictionary options; diff --git a/atom/common/api/atom_bindings.cc b/atom/common/api/atom_bindings.cc index 599fc6749890..b5a51ad507e4 100644 --- a/atom/common/api/atom_bindings.cc +++ b/atom/common/api/atom_bindings.cc @@ -25,7 +25,7 @@ namespace { struct DummyClass { bool crash; }; void Crash() { - static_cast(NULL)->crash = true; + static_cast(nullptr)->crash = true; } void Hang() { diff --git a/atom/common/asar/archive.cc b/atom/common/asar/archive.cc index c2306c3c8f38..e622effe5d3d 100644 --- a/atom/common/asar/archive.cc +++ b/atom/common/asar/archive.cc @@ -41,7 +41,7 @@ bool GetFilesNode(const base::DictionaryValue* root, // Test for symbol linked directory. std::string link; if (dir->GetStringWithoutPathExpansion("link", &link)) { - const base::DictionaryValue* linked_node = NULL; + const base::DictionaryValue* linked_node = nullptr; if (!GetNodeFromPath(link, root, &linked_node)) return false; dir = linked_node; @@ -60,7 +60,7 @@ bool GetChildNode(const base::DictionaryValue* root, return true; } - const base::DictionaryValue* files = NULL; + const base::DictionaryValue* files = nullptr; return GetFilesNode(root, dir, &files) && files->GetDictionaryWithoutPathExpansion(name, out); } @@ -78,7 +78,7 @@ bool GetNodeFromPath(std::string path, for (size_t delimiter_position = path.find_first_of(kSeparators); delimiter_position != std::string::npos; delimiter_position = path.find_first_of(kSeparators)) { - const base::DictionaryValue* child = NULL; + const base::DictionaryValue* child = nullptr; if (!GetChildNode(root, path.substr(0, delimiter_position), dir, &child)) return false; diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 7a61d6bc72bd..9ad4e0a65cb9 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -7,7 +7,7 @@ #define ATOM_MAJOR_VERSION 1 #define ATOM_MINOR_VERSION 2 -#define ATOM_PATCH_VERSION 5 +#define ATOM_PATCH_VERSION 8 #define ATOM_VERSION_IS_RELEASE 1 diff --git a/atom/common/crash_reporter/win/crash_service.cc b/atom/common/crash_reporter/win/crash_service.cc index 4563a9202a3e..5782fd72a3fb 100644 --- a/atom/common/crash_reporter/win/crash_service.cc +++ b/atom/common/crash_reporter/win/crash_service.cc @@ -239,23 +239,17 @@ bool CrashService::Initialize(const base::string16& application_name, } SECURITY_ATTRIBUTES security_attributes = {0}; - SECURITY_ATTRIBUTES* security_attributes_actual = NULL; + SECURITY_DESCRIPTOR* security_descriptor = + reinterpret_cast( + GetSecurityDescriptorForLowIntegrity()); + DCHECK(security_descriptor != NULL); - if (base::win::GetVersion() >= base::win::VERSION_VISTA) { - SECURITY_DESCRIPTOR* security_descriptor = - reinterpret_cast( - GetSecurityDescriptorForLowIntegrity()); - DCHECK(security_descriptor != NULL); - - security_attributes.nLength = sizeof(security_attributes); - security_attributes.lpSecurityDescriptor = security_descriptor; - security_attributes.bInheritHandle = FALSE; - - security_attributes_actual = &security_attributes; - } + security_attributes.nLength = sizeof(security_attributes); + security_attributes.lpSecurityDescriptor = security_descriptor; + security_attributes.bInheritHandle = FALSE; // Create the OOP crash generator object. - dumper_ = new CrashGenerationServer(pipe_name, security_attributes_actual, + dumper_ = new CrashGenerationServer(pipe_name, &security_attributes, &CrashService::OnClientConnected, this, &CrashService::OnClientDumpRequest, this, &CrashService::OnClientExited, this, diff --git a/atom/common/native_mate_converters/callback.cc b/atom/common/native_mate_converters/callback.cc index 8bf5c459b0a2..dc6d30fd23d7 100644 --- a/atom/common/native_mate_converters/callback.cc +++ b/atom/common/native_mate_converters/callback.cc @@ -123,7 +123,7 @@ v8::Local CreateFunctionFromTranslater( v8::Local call_translater = v8::Local::New(isolate, g_call_translater); - TranslaterHolder* holder = new TranslaterHolder; + auto* holder = new TranslaterHolder; holder->translater = translater; return BindFunctionWith(isolate, isolate->GetCurrentContext(), diff --git a/atom/common/native_mate_converters/net_converter.cc b/atom/common/native_mate_converters/net_converter.cc index 71bc50fde7d3..e79e09df10b2 100644 --- a/atom/common/native_mate_converters/net_converter.cc +++ b/atom/common/native_mate_converters/net_converter.cc @@ -11,6 +11,7 @@ #include "atom/common/native_mate_converters/gurl_converter.h" #include "atom/common/native_mate_converters/value_converter.h" #include "base/values.h" +#include "base/strings/string_number_conversions.h" #include "native_mate/dictionary.h" #include "net/base/upload_bytes_element_reader.h" #include "net/base/upload_data_stream.h" @@ -46,6 +47,15 @@ v8::Local Converter>::ToV8( encoded_data.size()).ToLocalChecked(); dict.Set("data", buffer); dict.Set("issuerName", val->issuer().GetDisplayName()); + dict.Set("subjectName", val->subject().GetDisplayName()); + dict.Set("serialNumber", base::HexEncode(val->serial_number().data(), + val->serial_number().size())); + dict.Set("validStart", val->valid_start().ToDoubleT()); + dict.Set("validExpiry", val->valid_expiry().ToDoubleT()); + dict.Set("fingerprint", + net::HashValue( + val->CalculateFingerprint256(val->os_cert_handle())).ToString()); + return dict.GetHandle(); } diff --git a/atom/common/native_mate_converters/v8_value_converter.cc b/atom/common/native_mate_converters/v8_value_converter.cc index af2cbaecc23f..6d159d4daf39 100644 --- a/atom/common/native_mate_converters/v8_value_converter.cc +++ b/atom/common/native_mate_converters/v8_value_converter.cc @@ -12,7 +12,8 @@ #include "base/logging.h" #include "base/values.h" #include "native_mate/dictionary.h" -#include "vendor/node/src/node_buffer.h" + +#include "atom/common/node_includes.h" namespace atom { @@ -55,7 +56,7 @@ class V8ValueConverter::FromV8ValueState { // hash. Different hash obviously means different objects, but two objects // in a couple of thousands could have the same identity hash. std::pair range = unique_map_.equal_range(hash); - for (Iterator it = range.first; it != range.second; ++it) { + for (auto it = range.first; it != range.second; ++it) { // Operator == for handles actually compares the underlying objects. if (it->second == handle) return false; @@ -110,32 +111,31 @@ base::Value* V8ValueConverter::FromV8Value( v8::Local V8ValueConverter::ToV8ValueImpl( v8::Isolate* isolate, const base::Value* value) const { - CHECK(value); switch (value->GetType()) { case base::Value::TYPE_NULL: return v8::Null(isolate); case base::Value::TYPE_BOOLEAN: { bool val = false; - CHECK(value->GetAsBoolean(&val)); + value->GetAsBoolean(&val); return v8::Boolean::New(isolate, val); } case base::Value::TYPE_INTEGER: { int val = 0; - CHECK(value->GetAsInteger(&val)); + value->GetAsInteger(&val); return v8::Integer::New(isolate, val); } case base::Value::TYPE_DOUBLE: { double val = 0.0; - CHECK(value->GetAsDouble(&val)); + value->GetAsDouble(&val); return v8::Number::New(isolate, val); } case base::Value::TYPE_STRING: { std::string val; - CHECK(value->GetAsString(&val)); + value->GetAsString(&val); return v8::String::NewFromUtf8( isolate, val.c_str(), v8::String::kNormalString, val.length()); } @@ -162,11 +162,10 @@ v8::Local V8ValueConverter::ToV8Array( v8::Local result(v8::Array::New(isolate, val->GetSize())); for (size_t i = 0; i < val->GetSize(); ++i) { - const base::Value* child = NULL; - CHECK(val->Get(i, &child)); + const base::Value* child = nullptr; + val->Get(i, &child); v8::Local child_v8 = ToV8ValueImpl(isolate, child); - CHECK(!child_v8.IsEmpty()); v8::TryCatch try_catch; result->Set(static_cast(i), child_v8); @@ -186,7 +185,6 @@ v8::Local V8ValueConverter::ToV8Object( !iter.IsAtEnd(); iter.Advance()) { const std::string& key = iter.key(); v8::Local child_v8 = ToV8ValueImpl(isolate, &iter.value()); - CHECK(!child_v8.IsEmpty()); v8::TryCatch try_catch; result.Set(key, child_v8); @@ -210,11 +208,9 @@ base::Value* V8ValueConverter::FromV8ValueImpl( FromV8ValueState* state, v8::Local val, v8::Isolate* isolate) const { - CHECK(!val.IsEmpty()); - FromV8ValueState::Level state_level(state); if (state->HasReachedMaxRecursionDepth()) - return NULL; + return nullptr; if (val->IsNull()) return base::Value::CreateNullValue().release(); @@ -235,7 +231,7 @@ base::Value* V8ValueConverter::FromV8ValueImpl( if (val->IsUndefined()) // JSON.stringify ignores undefined. - return NULL; + return nullptr; if (val->IsDate()) { v8::Date* date = v8::Date::Cast(*val); @@ -265,7 +261,7 @@ base::Value* V8ValueConverter::FromV8ValueImpl( if (val->IsFunction()) { if (!function_allowed_) // JSON.stringify refuses to convert function(){}. - return NULL; + return nullptr; return FromV8Object(val->ToObject(), state, isolate); } @@ -278,7 +274,7 @@ base::Value* V8ValueConverter::FromV8ValueImpl( } LOG(ERROR) << "Unexpected v8 value type encountered."; - return NULL; + return nullptr; } base::Value* V8ValueConverter::FromV8Array( @@ -295,7 +291,7 @@ base::Value* V8ValueConverter::FromV8Array( val->CreationContext() != isolate->GetCurrentContext()) scope.reset(new v8::Context::Scope(val->CreationContext())); - base::ListValue* result = new base::ListValue(); + auto* result = new base::ListValue(); // Only fields with integer keys are carried over to the ListValue. for (uint32_t i = 0; i < val->Length(); ++i) { diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index 40fa6bdb6e28..2a999ea79bc9 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -11,7 +11,6 @@ #include "atom/common/api/locker.h" #include "atom/common/atom_command_line.h" #include "atom/common/native_mate_converters/file_path_converter.h" -#include "atom/common/node_includes.h" #include "base/command_line.h" #include "base/base_paths.h" #include "base/environment.h" @@ -22,6 +21,8 @@ #include "content/public/common/content_paths.h" #include "native_mate/dictionary.h" +#include "atom/common/node_includes.h" + using content::BrowserThread; // Force all builtin modules to be referenced so they can actually run their @@ -216,7 +217,6 @@ void NodeBindings::UvRunOnce() { DCHECK(!is_browser_ || BrowserThread::CurrentlyOn(BrowserThread::UI)); node::Environment* env = uv_env(); - CHECK(env); // Use Locker in browser process. mate::Locker locker(env->isolate()); diff --git a/atom/common/node_bindings_mac.cc b/atom/common/node_bindings_mac.cc index 9e61d27f496b..cbcbdba36050 100644 --- a/atom/common/node_bindings_mac.cc +++ b/atom/common/node_bindings_mac.cc @@ -54,7 +54,8 @@ void NodeBindingsMac::PollEvents() { // Wait for new libuv events. int r; do { - r = select(fd + 1, &readset, NULL, NULL, timeout == -1 ? NULL : &tv); + r = select(fd + 1, &readset, nullptr, nullptr, + timeout == -1 ? nullptr : &tv); } while (r == -1 && errno == EINTR); } diff --git a/atom/common/node_includes.h b/atom/common/node_includes.h index 46b6fa058ebb..01efa6b15470 100644 --- a/atom/common/node_includes.h +++ b/atom/common/node_includes.h @@ -19,6 +19,7 @@ #undef CHECK_GT #undef CHECK_LE #undef CHECK_LT +#undef UNLIKELY #undef DISALLOW_COPY_AND_ASSIGN #undef NO_RETURN #undef arraysize diff --git a/atom/common/platform_util.h b/atom/common/platform_util.h index 4565221e9d84..262f0a2e6e49 100644 --- a/atom/common/platform_util.h +++ b/atom/common/platform_util.h @@ -5,6 +5,12 @@ #ifndef ATOM_COMMON_PLATFORM_UTIL_H_ #define ATOM_COMMON_PLATFORM_UTIL_H_ +#include "build/build_config.h" + +#if defined(OS_WIN) +#include "base/strings/string16.h" +#endif + class GURL; namespace base { @@ -23,7 +29,13 @@ void OpenItem(const base::FilePath& full_path); // Open the given external protocol URL in the desktop's default manner. // (For example, mailto: URLs in the default mail user agent.) -bool OpenExternal(const GURL& url, bool activate); +bool OpenExternal( +#if defined(OS_WIN) + const base::string16& url, +#else + const GURL& url, +#endif + bool activate); // Move a file to trash. bool MoveItemToTrash(const base::FilePath& full_path); diff --git a/atom/common/platform_util_win.cc b/atom/common/platform_util_win.cc index 12591a94d569..0795fcb72bff 100644 --- a/atom/common/platform_util_win.cc +++ b/atom/common/platform_util_win.cc @@ -24,8 +24,8 @@ #include "base/win/scoped_com_initializer.h" #include "base/win/scoped_comptr.h" #include "base/win/windows_version.h" -#include "url/gurl.h" #include "ui/base/win/shell.h" +#include "url/gurl.h" namespace { @@ -301,30 +301,13 @@ void OpenItem(const base::FilePath& full_path) { ui::win::OpenFileViaShell(full_path); } -bool OpenExternal(const GURL& url, bool activate) { +bool OpenExternal(const base::string16& url, bool activate) { // Quote the input scheme to be sure that the command does not have // parameters unexpected by the external program. This url should already // have been escaped. - std::string escaped_url = url.spec(); - escaped_url.insert(0, "\""); - escaped_url += "\""; + base::string16 escaped_url = L"\"" + url + L"\""; - // According to Mozilla in uriloader/exthandler/win/nsOSHelperAppService.cpp: - // "Some versions of windows (Win2k before SP3, Win XP before SP1) crash in - // ShellExecute on long URLs (bug 161357 on bugzilla.mozilla.org). IE 5 and 6 - // support URLS of 2083 chars in length, 2K is safe." - const size_t kMaxURLLength = 2048; - if (escaped_url.length() > kMaxURLLength) { - NOTREACHED(); - return false; - } - - if (base::win::GetVersion() < base::win::VERSION_WIN7) { - if (!ValidateShellCommandForScheme(url.scheme())) - return false; - } - - if (reinterpret_cast(ShellExecuteA(NULL, "open", + if (reinterpret_cast(ShellExecuteW(NULL, L"open", escaped_url.c_str(), NULL, NULL, SW_SHOWNORMAL)) <= 32) { // We fail to execute the call. We could display a message to the user. diff --git a/atom/node/osfhandle.h b/atom/node/osfhandle.h index 6ebb2ab11e9d..3933236e5091 100644 --- a/atom/node/osfhandle.h +++ b/atom/node/osfhandle.h @@ -7,8 +7,6 @@ #include -#include "node_extern.h" - namespace node { // The _open_osfhandle and _close functions on Windows are provided by the @@ -20,8 +18,8 @@ namespace node { // we always create fd in one instance of VC++ library. // Followings wrappers are compiled in node.dll, and all code in electron.exe // should call these wrappers instead of calling _open_osfhandle directly. -NODE_EXTERN int open_osfhandle(intptr_t osfhandle, int flags); -NODE_EXTERN int close(int fd); +__declspec(dllexport) int open_osfhandle(intptr_t osfhandle, int flags); +__declspec(dllexport) int close(int fd); } // namespace node diff --git a/atom/renderer/api/atom_api_renderer_ipc.cc b/atom/renderer/api/atom_api_renderer_ipc.cc index a82562f93614..49f917292bb2 100644 --- a/atom/renderer/api/atom_api_renderer_ipc.cc +++ b/atom/renderer/api/atom_api_renderer_ipc.cc @@ -20,11 +20,11 @@ namespace { RenderView* GetCurrentRenderView() { WebLocalFrame* frame = WebLocalFrame::frameForCurrentContext(); if (!frame) - return NULL; + return nullptr; WebView* view = frame->view(); if (!view) - return NULL; // can happen during closing. + return nullptr; // can happen during closing. return RenderView::FromWebView(view); } @@ -33,7 +33,7 @@ void Send(mate::Arguments* args, const base::string16& channel, const base::ListValue& arguments) { RenderView* render_view = GetCurrentRenderView(); - if (render_view == NULL) + if (render_view == nullptr) return; bool success = render_view->Send(new AtomViewHostMsg_Message( @@ -49,7 +49,7 @@ base::string16 SendSync(mate::Arguments* args, base::string16 json; RenderView* render_view = GetCurrentRenderView(); - if (render_view == NULL) + if (render_view == nullptr) return json; IPC::SyncMessage* message = new AtomViewHostMsg_Message_Sync( diff --git a/atom/renderer/api/atom_api_web_frame.cc b/atom/renderer/api/atom_api_web_frame.cc index 0b291d3b552a..dce72b580951 100644 --- a/atom/renderer/api/atom_api_web_frame.cc +++ b/atom/renderer/api/atom_api_web_frame.cc @@ -39,7 +39,7 @@ class ScriptExecutionCallback : public blink::WebScriptExecutionCallback { explicit ScriptExecutionCallback(const CompletionCallback& callback) : callback_(callback) {} - ~ScriptExecutionCallback() {} + ~ScriptExecutionCallback() override {} void completed( const blink::WebVector>& result) override { diff --git a/atom/renderer/atom_render_view_observer.cc b/atom/renderer/atom_render_view_observer.cc index 7ee93efb39b7..45a41eef8acc 100644 --- a/atom/renderer/atom_render_view_observer.cc +++ b/atom/renderer/atom_render_view_observer.cc @@ -132,10 +132,10 @@ void AtomRenderViewObserver::DraggableRegionsChanged(blink::WebFrame* frame) { blink::WebVector webregions = frame->document().draggableRegions(); std::vector regions; - for (size_t i = 0; i < webregions.size(); ++i) { + for (const auto& webregion : webregions) { DraggableRegion region; - region.bounds = webregions[i].bounds; - region.draggable = webregions[i].draggable; + region.bounds = webregion.bounds; + region.draggable = webregion.draggable; regions.push_back(region); } Send(new AtomViewHostMsg_UpdateDraggableRegions(routing_id(), regions)); diff --git a/atom/renderer/atom_renderer_client.cc b/atom/renderer/atom_renderer_client.cc index 7861f9d1e63b..d2c341fa27f5 100644 --- a/atom/renderer/atom_renderer_client.cc +++ b/atom/renderer/atom_renderer_client.cc @@ -20,7 +20,6 @@ #include "atom/renderer/node_array_buffer_bridge.h" #include "atom/renderer/preferences_manager.h" #include "base/command_line.h" -#include "base/strings/utf_string_conversions.h" #include "chrome/renderer/media/chrome_key_systems.h" #include "chrome/renderer/pepper/pepper_helper.h" #include "chrome/renderer/printing/print_web_view_helper.h" @@ -32,7 +31,6 @@ #include "content/public/renderer/render_view.h" #include "ipc/ipc_message_macros.h" #include "native_mate/dictionary.h" -#include "net/base/net_errors.h" #include "third_party/WebKit/public/web/WebCustomElement.h" #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebFrameWidget.h" @@ -317,18 +315,6 @@ content::BrowserPluginDelegate* AtomRendererClient::CreateBrowserPluginDelegate( } } -void AtomRendererClient::GetNavigationErrorStrings( - content::RenderFrame* render_frame, - const blink::WebURLRequest& failed_request, - const blink::WebURLError& error, - std::string* error_html, - base::string16* error_description) { - if (!error_description) - return; - - *error_description = base::UTF8ToUTF16(net::ErrorToShortString(error.reason)); -} - void AtomRendererClient::AddSupportedKeySystems( std::vector>* key_systems) { AddChromeKeySystems(key_systems); diff --git a/atom/renderer/atom_renderer_client.h b/atom/renderer/atom_renderer_client.h index 3b6f8a52d224..5419692d2aeb 100644 --- a/atom/renderer/atom_renderer_client.h +++ b/atom/renderer/atom_renderer_client.h @@ -57,11 +57,6 @@ class AtomRendererClient : public content::ContentRendererClient { content::RenderFrame* render_frame, const std::string& mime_type, const GURL& original_url) override; - void GetNavigationErrorStrings(content::RenderFrame* render_frame, - const blink::WebURLRequest& failed_request, - const blink::WebURLError& error, - std::string* error_html, - base::string16* error_description) override; void AddSupportedKeySystems( std::vector>* key_systems) override; diff --git a/atom/utility/atom_content_utility_client.cc b/atom/utility/atom_content_utility_client.cc index aff567fbcaab..8d4ccf628933 100644 --- a/atom/utility/atom_content_utility_client.cc +++ b/atom/utility/atom_content_utility_client.cc @@ -58,8 +58,7 @@ bool AtomContentUtilityClient::OnMessageReceived( IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() - for (Handlers::iterator it = handlers_.begin(); - !handled && it != handlers_.end(); ++it) { + for (auto it = handlers_.begin(); !handled && it != handlers_.end(); ++it) { handled = (*it)->OnMessageReceived(message); } diff --git a/chromium_src/chrome/browser/renderer_host/pepper/pepper_broker_message_filter.cc b/chromium_src/chrome/browser/renderer_host/pepper/pepper_broker_message_filter.cc index 224b55d4cac5..c77c8f00f807 100644 --- a/chromium_src/chrome/browser/renderer_host/pepper/pepper_broker_message_filter.cc +++ b/chromium_src/chrome/browser/renderer_host/pepper/pepper_broker_message_filter.cc @@ -17,7 +17,6 @@ using content::BrowserPpapiHost; using content::BrowserThread; -using content::RenderProcessHost; namespace chrome { diff --git a/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.cc b/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.cc index 43179c68d485..96fe8dc8e382 100644 --- a/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.cc +++ b/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.cc @@ -26,7 +26,6 @@ using content::BrowserPpapiHost; using content::BrowserThread; -using content::RenderProcessHost; namespace chrome { diff --git a/common.gypi b/common.gypi index e0224525c89c..e8d07caf5fb4 100644 --- a/common.gypi +++ b/common.gypi @@ -14,11 +14,13 @@ 'python': 'python', 'openssl_fips': '', 'openssl_no_asm': 1, + 'OPENSSL_PRODUCT': 'libopenssl.a', 'node_release_urlbase': 'https://atom.io/download/atom-shell', 'node_byteorder': ' { @@ -9,13 +10,18 @@ app.on('window-all-closed', () => { exports.load = (appUrl) => { app.on('ready', () => { - mainWindow = new BrowserWindow({ + const options = { width: 800, height: 600, autoHideMenuBar: true, backgroundColor: '#FFFFFF', useContentSize: true - }) + } + if (process.platform === 'linux') { + options.icon = path.join(__dirname, 'icon.png') + } + + mainWindow = new BrowserWindow(options) mainWindow.loadURL(appUrl) mainWindow.focus() }) diff --git a/default_app/icon.png b/default_app/icon.png new file mode 100644 index 000000000000..ac3a6547d9ec Binary files /dev/null and b/default_app/icon.png differ diff --git a/default_app/index.html b/default_app/index.html index edfb3e6ddc92..67e3e249e37a 100644 --- a/default_app/index.html +++ b/default_app/index.html @@ -1,9 +1,9 @@ - + Electron