Merge remote-tracking branch 'refs/remotes/atom/master'
This commit is contained in:
commit
a190b964c8
110 changed files with 2288 additions and 341 deletions
|
@ -52,6 +52,7 @@ contains documents describing how to build and contribute to Electron.
|
||||||
- [Spanish](https://github.com/atom/electron/tree/master/docs-translations/es)
|
- [Spanish](https://github.com/atom/electron/tree/master/docs-translations/es)
|
||||||
- [Simplified Chinese](https://github.com/atom/electron/tree/master/docs-translations/zh-CN)
|
- [Simplified Chinese](https://github.com/atom/electron/tree/master/docs-translations/zh-CN)
|
||||||
- [Traditional Chinese](https://github.com/atom/electron/tree/master/docs-translations/zh-TW)
|
- [Traditional Chinese](https://github.com/atom/electron/tree/master/docs-translations/zh-TW)
|
||||||
|
- [Ukrainian](https://github.com/atom/electron/tree/master/docs-translations/uk-UA)
|
||||||
- [Russian](https://github.com/atom/electron/tree/master/docs-translations/ru-RU)
|
- [Russian](https://github.com/atom/electron/tree/master/docs-translations/ru-RU)
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
7
atom.gyp
7
atom.gyp
|
@ -4,7 +4,7 @@
|
||||||
'product_name%': 'Electron',
|
'product_name%': 'Electron',
|
||||||
'company_name%': 'GitHub, Inc',
|
'company_name%': 'GitHub, Inc',
|
||||||
'company_abbr%': 'github',
|
'company_abbr%': 'github',
|
||||||
'version%': '0.35.2',
|
'version%': '0.36.0',
|
||||||
},
|
},
|
||||||
'includes': [
|
'includes': [
|
||||||
'filenames.gypi',
|
'filenames.gypi',
|
||||||
|
@ -256,6 +256,10 @@
|
||||||
'vendor/node/deps/cares/include',
|
'vendor/node/deps/cares/include',
|
||||||
# The `third_party/WebKit/Source/platform/weborigin/SchemeRegistry.h` is using `platform/PlatformExport.h`.
|
# The `third_party/WebKit/Source/platform/weborigin/SchemeRegistry.h` is using `platform/PlatformExport.h`.
|
||||||
'<(libchromiumcontent_src_dir)/third_party/WebKit/Source',
|
'<(libchromiumcontent_src_dir)/third_party/WebKit/Source',
|
||||||
|
# The 'third_party/libyuv/include/libyuv/scale_argb.h' is using 'libyuv/basic_types.h'.
|
||||||
|
'<(libchromiumcontent_src_dir)/third_party/libyuv/include',
|
||||||
|
# The 'third_party/webrtc/modules/desktop_capture/desktop_frame.h' is using 'webrtc/base/scoped_ptr.h'.
|
||||||
|
'<(libchromiumcontent_src_dir)/third_party/',
|
||||||
],
|
],
|
||||||
'direct_dependent_settings': {
|
'direct_dependent_settings': {
|
||||||
'include_dirs': [
|
'include_dirs': [
|
||||||
|
@ -282,6 +286,7 @@
|
||||||
'-lcomctl32.lib',
|
'-lcomctl32.lib',
|
||||||
'-lcomdlg32.lib',
|
'-lcomdlg32.lib',
|
||||||
'-lwininet.lib',
|
'-lwininet.lib',
|
||||||
|
'-lwinmm.lib',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
'dependencies': [
|
'dependencies': [
|
||||||
|
|
|
@ -31,8 +31,8 @@ content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
|
||||||
plugin.path = path;
|
plugin.path = path;
|
||||||
plugin.permissions = ppapi::PERMISSION_ALL_BITS;
|
plugin.permissions = ppapi::PERMISSION_ALL_BITS;
|
||||||
|
|
||||||
std::vector<std::string> flash_version_numbers;
|
std::vector<std::string> flash_version_numbers = base::SplitString(
|
||||||
base::SplitString(version, '.', &flash_version_numbers);
|
version, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||||
if (flash_version_numbers.size() < 1)
|
if (flash_version_numbers.size() < 1)
|
||||||
flash_version_numbers.push_back("11");
|
flash_version_numbers.push_back("11");
|
||||||
// |SplitString()| puts in an empty string given an empty string. :(
|
// |SplitString()| puts in an empty string given an empty string. :(
|
||||||
|
@ -47,7 +47,7 @@ content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
|
||||||
// E.g., "Shockwave Flash 10.2 r154":
|
// E.g., "Shockwave Flash 10.2 r154":
|
||||||
plugin.description = plugin.name + " " + flash_version_numbers[0] + "." +
|
plugin.description = plugin.name + " " + flash_version_numbers[0] + "." +
|
||||||
flash_version_numbers[1] + " r" + flash_version_numbers[2];
|
flash_version_numbers[1] + " r" + flash_version_numbers[2];
|
||||||
plugin.version = JoinString(flash_version_numbers, '.');
|
plugin.version = base::JoinString(flash_version_numbers, ".");
|
||||||
content::WebPluginMimeType swf_mime_type(
|
content::WebPluginMimeType swf_mime_type(
|
||||||
content::kFlashPluginSwfMimeType,
|
content::kFlashPluginSwfMimeType,
|
||||||
content::kFlashPluginSwfExtension,
|
content::kFlashPluginSwfExtension,
|
||||||
|
@ -81,19 +81,18 @@ std::string AtomContentClient::GetUserAgent() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomContentClient::AddAdditionalSchemes(
|
void AtomContentClient::AddAdditionalSchemes(
|
||||||
std::vector<std::string>* standard_schemes,
|
std::vector<url::SchemeWithType>* standard_schemes,
|
||||||
std::vector<std::string>* savable_schemes) {
|
std::vector<std::string>* savable_schemes) {
|
||||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||||
auto custom_schemes = command_line->GetSwitchValueASCII(
|
auto custom_schemes = command_line->GetSwitchValueASCII(
|
||||||
switches::kRegisterStandardSchemes);
|
switches::kRegisterStandardSchemes);
|
||||||
if (!custom_schemes.empty()) {
|
if (!custom_schemes.empty()) {
|
||||||
std::vector<std::string> schemes;
|
std::vector<std::string> schemes = base::SplitString(
|
||||||
base::SplitString(custom_schemes, ',', &schemes);
|
custom_schemes, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||||
standard_schemes->insert(standard_schemes->end(),
|
for (const std::string& scheme : schemes)
|
||||||
schemes.begin(),
|
standard_schemes->push_back({scheme.c_str(), url::SCHEME_WITHOUT_PORT});
|
||||||
schemes.end());
|
|
||||||
}
|
}
|
||||||
standard_schemes->push_back("chrome-extension");
|
standard_schemes->push_back({"chrome-extension", url::SCHEME_WITHOUT_PORT});
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomContentClient::AddPepperPlugins(
|
void AtomContentClient::AddPepperPlugins(
|
||||||
|
|
|
@ -22,7 +22,7 @@ class AtomContentClient : public brightray::ContentClient {
|
||||||
std::string GetProduct() const override;
|
std::string GetProduct() const override;
|
||||||
std::string GetUserAgent() const override;
|
std::string GetUserAgent() const override;
|
||||||
void AddAdditionalSchemes(
|
void AddAdditionalSchemes(
|
||||||
std::vector<std::string>* standard_schemes,
|
std::vector<url::SchemeWithType>* standard_schemes,
|
||||||
std::vector<std::string>* savable_schemes) override;
|
std::vector<std::string>* savable_schemes) override;
|
||||||
void AddPepperPlugins(
|
void AddPepperPlugins(
|
||||||
std::vector<content::PepperPluginInfo>* plugins) override;
|
std::vector<content::PepperPluginInfo>* plugins) override;
|
||||||
|
|
120
atom/browser/api/atom_api_desktop_capturer.cc
Normal file
120
atom/browser/api/atom_api_desktop_capturer.cc
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
// Copyright (c) 2015 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_desktop_capturer.h"
|
||||||
|
|
||||||
|
#include "atom/common/api/atom_api_native_image.h"
|
||||||
|
#include "atom/common/node_includes.h"
|
||||||
|
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||||
|
#include "base/strings/utf_string_conversions.h"
|
||||||
|
#include "chrome/browser/media/desktop_media_list.h"
|
||||||
|
#include "native_mate/dictionary.h"
|
||||||
|
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
|
||||||
|
#include "third_party/webrtc/modules/desktop_capture/screen_capturer.h"
|
||||||
|
#include "third_party/webrtc/modules/desktop_capture/window_capturer.h"
|
||||||
|
|
||||||
|
namespace mate {
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Converter<DesktopMediaList::Source> {
|
||||||
|
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
|
const DesktopMediaList::Source& source) {
|
||||||
|
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||||
|
content::DesktopMediaID id = source.id;
|
||||||
|
dict.Set("name", base::UTF16ToUTF8(source.name));
|
||||||
|
dict.Set("id", id.ToString());
|
||||||
|
dict.Set(
|
||||||
|
"thumbnail",
|
||||||
|
atom::api::NativeImage::Create(isolate, gfx::Image(source.thumbnail)));
|
||||||
|
return ConvertToV8(isolate, dict);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mate
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
namespace api {
|
||||||
|
|
||||||
|
DesktopCapturer::DesktopCapturer() {
|
||||||
|
}
|
||||||
|
|
||||||
|
DesktopCapturer::~DesktopCapturer() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopCapturer::StartHandling(bool capture_window,
|
||||||
|
bool capture_screen,
|
||||||
|
const gfx::Size& thumbnail_size) {
|
||||||
|
webrtc::DesktopCaptureOptions options =
|
||||||
|
webrtc::DesktopCaptureOptions::CreateDefault();
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
// On windows, desktop effects (e.g. Aero) will be disabled when the Desktop
|
||||||
|
// capture API is active by default.
|
||||||
|
// We keep the desktop effects in most times. Howerver, the screen still
|
||||||
|
// fickers when the API is capturing the window due to limitation of current
|
||||||
|
// implemetation. This is a known and wontFix issue in webrtc (see:
|
||||||
|
// http://code.google.com/p/webrtc/issues/detail?id=3373)
|
||||||
|
options.set_disable_effects(false);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
scoped_ptr<webrtc::ScreenCapturer> screen_capturer(
|
||||||
|
capture_screen ? webrtc::ScreenCapturer::Create(options) : nullptr);
|
||||||
|
scoped_ptr<webrtc::WindowCapturer> window_capturer(
|
||||||
|
capture_window ? webrtc::WindowCapturer::Create(options) : nullptr);
|
||||||
|
media_list_.reset(new NativeDesktopMediaList(screen_capturer.Pass(),
|
||||||
|
window_capturer.Pass()));
|
||||||
|
|
||||||
|
media_list_->SetThumbnailSize(thumbnail_size);
|
||||||
|
media_list_->StartUpdating(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopCapturer::OnSourceAdded(int index) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopCapturer::OnSourceRemoved(int index) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopCapturer::OnSourceMoved(int old_index, int new_index) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopCapturer::OnSourceNameChanged(int index) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopCapturer::OnSourceThumbnailChanged(int index) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DesktopCapturer::OnRefreshFinished() {
|
||||||
|
Emit("finished", media_list_->GetSources());
|
||||||
|
media_list_.reset();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mate::ObjectTemplateBuilder DesktopCapturer::GetObjectTemplateBuilder(
|
||||||
|
v8::Isolate* isolate) {
|
||||||
|
return mate::ObjectTemplateBuilder(isolate)
|
||||||
|
.SetMethod("startHandling", &DesktopCapturer::StartHandling);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
mate::Handle<DesktopCapturer> DesktopCapturer::Create(v8::Isolate* isolate) {
|
||||||
|
return mate::CreateHandle(isolate, new DesktopCapturer);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace api
|
||||||
|
|
||||||
|
} // namespace atom
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||||
|
v8::Local<v8::Context> context, void* priv) {
|
||||||
|
v8::Isolate* isolate = context->GetIsolate();
|
||||||
|
mate::Dictionary dict(isolate, exports);
|
||||||
|
dict.Set("desktopCapturer", atom::api::DesktopCapturer::Create(isolate));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_desktop_capturer, Initialize);
|
52
atom/browser/api/atom_api_desktop_capturer.h
Normal file
52
atom/browser/api/atom_api_desktop_capturer.h
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
// Copyright (c) 2015 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef ATOM_BROWSER_API_ATOM_API_DESKTOP_CAPTURER_H_
|
||||||
|
#define ATOM_BROWSER_API_ATOM_API_DESKTOP_CAPTURER_H_
|
||||||
|
|
||||||
|
#include "atom/browser/api/event_emitter.h"
|
||||||
|
#include "chrome/browser/media/desktop_media_list_observer.h"
|
||||||
|
#include "chrome/browser/media/native_desktop_media_list.h"
|
||||||
|
#include "native_mate/handle.h"
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
namespace api {
|
||||||
|
|
||||||
|
class DesktopCapturer: public mate::EventEmitter,
|
||||||
|
public DesktopMediaListObserver {
|
||||||
|
public:
|
||||||
|
static mate::Handle<DesktopCapturer> Create(v8::Isolate* isolate);
|
||||||
|
|
||||||
|
void StartHandling(bool capture_window,
|
||||||
|
bool capture_screen,
|
||||||
|
const gfx::Size& thumbnail_size);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
DesktopCapturer();
|
||||||
|
~DesktopCapturer();
|
||||||
|
|
||||||
|
// DesktopMediaListObserver overrides.
|
||||||
|
void OnSourceAdded(int index) override;
|
||||||
|
void OnSourceRemoved(int index) override;
|
||||||
|
void OnSourceMoved(int old_index, int new_index) override;
|
||||||
|
void OnSourceNameChanged(int index) override;
|
||||||
|
void OnSourceThumbnailChanged(int index) override;
|
||||||
|
bool OnRefreshFinished() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// mate::Wrappable:
|
||||||
|
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||||
|
v8::Isolate* isolate) override;
|
||||||
|
|
||||||
|
scoped_ptr<DesktopMediaList> media_list_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(DesktopCapturer);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace api
|
||||||
|
|
||||||
|
} // namespace atom
|
||||||
|
|
||||||
|
#endif // ATOM_BROWSER_API_ATOM_API_DESKTOP_CAPTURER_H_
|
|
@ -51,7 +51,7 @@ struct ClearStorageDataOptions {
|
||||||
uint32 GetStorageMask(const std::vector<std::string>& storage_types) {
|
uint32 GetStorageMask(const std::vector<std::string>& storage_types) {
|
||||||
uint32 storage_mask = 0;
|
uint32 storage_mask = 0;
|
||||||
for (const auto& it : storage_types) {
|
for (const auto& it : storage_types) {
|
||||||
auto type = base::StringToLowerASCII(it);
|
auto type = base::ToLowerASCII(it);
|
||||||
if (type == "appcache")
|
if (type == "appcache")
|
||||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_APPCACHE;
|
storage_mask |= StoragePartition::REMOVE_DATA_MASK_APPCACHE;
|
||||||
else if (type == "cookies")
|
else if (type == "cookies")
|
||||||
|
@ -75,7 +75,7 @@ uint32 GetStorageMask(const std::vector<std::string>& storage_types) {
|
||||||
uint32 GetQuotaMask(const std::vector<std::string>& quota_types) {
|
uint32 GetQuotaMask(const std::vector<std::string>& quota_types) {
|
||||||
uint32 quota_mask = 0;
|
uint32 quota_mask = 0;
|
||||||
for (const auto& it : quota_types) {
|
for (const auto& it : quota_types) {
|
||||||
auto type = base::StringToLowerASCII(it);
|
auto type = base::ToLowerASCII(it);
|
||||||
if (type == "temporary")
|
if (type == "temporary")
|
||||||
quota_mask |= StoragePartition::QUOTA_MANAGED_STORAGE_MASK_TEMPORARY;
|
quota_mask |= StoragePartition::QUOTA_MANAGED_STORAGE_MASK_TEMPORARY;
|
||||||
else if (type == "persistent")
|
else if (type == "persistent")
|
||||||
|
@ -233,7 +233,8 @@ void SetProxyInIO(net::URLRequestContextGetter* getter,
|
||||||
const net::ProxyConfig& config,
|
const net::ProxyConfig& config,
|
||||||
const base::Closure& callback) {
|
const base::Closure& callback) {
|
||||||
auto proxy_service = getter->GetURLRequestContext()->proxy_service();
|
auto proxy_service = getter->GetURLRequestContext()->proxy_service();
|
||||||
proxy_service->ResetConfigService(new net::ProxyConfigServiceFixed(config));
|
proxy_service->ResetConfigService(make_scoped_ptr(
|
||||||
|
new net::ProxyConfigServiceFixed(config)));
|
||||||
// Refetches and applies the new pac script if provided.
|
// Refetches and applies the new pac script if provided.
|
||||||
proxy_service->ForceReloadProxyConfig();
|
proxy_service->ForceReloadProxyConfig();
|
||||||
RunCallbackInUI(callback);
|
RunCallbackInUI(callback);
|
||||||
|
|
|
@ -148,7 +148,7 @@ struct Converter<net::HttpResponseHeaders*> {
|
||||||
std::string key;
|
std::string key;
|
||||||
std::string value;
|
std::string value;
|
||||||
while (headers->EnumerateHeaderLines(&iter, &key, &value)) {
|
while (headers->EnumerateHeaderLines(&iter, &key, &value)) {
|
||||||
key = base::StringToLowerASCII(key);
|
key = base::ToLowerASCII(key);
|
||||||
if (response_headers.HasKey(key)) {
|
if (response_headers.HasKey(key)) {
|
||||||
base::ListValue* values = nullptr;
|
base::ListValue* values = nullptr;
|
||||||
if (response_headers.GetList(key, &values))
|
if (response_headers.GetList(key, &values))
|
||||||
|
@ -171,7 +171,7 @@ struct Converter<content::SavePageType> {
|
||||||
std::string save_type;
|
std::string save_type;
|
||||||
if (!ConvertFromV8(isolate, val, &save_type))
|
if (!ConvertFromV8(isolate, val, &save_type))
|
||||||
return false;
|
return false;
|
||||||
save_type = base::StringToLowerASCII(save_type);
|
save_type = base::ToLowerASCII(save_type);
|
||||||
if (save_type == "htmlonly") {
|
if (save_type == "htmlonly") {
|
||||||
*out = content::SAVE_PAGE_TYPE_AS_ONLY_HTML;
|
*out = content::SAVE_PAGE_TYPE_AS_ONLY_HTML;
|
||||||
} else if (save_type == "htmlcomplete") {
|
} else if (save_type == "htmlcomplete") {
|
||||||
|
|
|
@ -159,6 +159,10 @@ Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) {
|
||||||
Window::~Window() {
|
Window::~Window() {
|
||||||
if (!window_->IsClosed())
|
if (!window_->IsClosed())
|
||||||
window_->CloseContents(nullptr);
|
window_->CloseContents(nullptr);
|
||||||
|
|
||||||
|
// Destroy the native window in next tick because the native code might be
|
||||||
|
// iterating all windows.
|
||||||
|
base::MessageLoop::current()->DeleteSoon(FROM_HERE, window_.release());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::WillCloseWindow(bool* prevent_default) {
|
void Window::WillCloseWindow(bool* prevent_default) {
|
||||||
|
@ -484,6 +488,10 @@ bool Window::IsDocumentEdited() {
|
||||||
return window_->IsDocumentEdited();
|
return window_->IsDocumentEdited();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Window::SetIgnoreMouseEvents(bool ignore) {
|
||||||
|
return window_->SetIgnoreMouseEvents(ignore);
|
||||||
|
}
|
||||||
|
|
||||||
void Window::CapturePage(mate::Arguments* args) {
|
void Window::CapturePage(mate::Arguments* args) {
|
||||||
gfx::Rect rect;
|
gfx::Rect rect;
|
||||||
base::Callback<void(const gfx::Image&)> callback;
|
base::Callback<void(const gfx::Image&)> callback;
|
||||||
|
@ -658,6 +666,7 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
||||||
.SetMethod("getRepresentedFilename", &Window::GetRepresentedFilename)
|
.SetMethod("getRepresentedFilename", &Window::GetRepresentedFilename)
|
||||||
.SetMethod("setDocumentEdited", &Window::SetDocumentEdited)
|
.SetMethod("setDocumentEdited", &Window::SetDocumentEdited)
|
||||||
.SetMethod("isDocumentEdited", &Window::IsDocumentEdited)
|
.SetMethod("isDocumentEdited", &Window::IsDocumentEdited)
|
||||||
|
.SetMethod("setIgnoreMouseEvents", &Window::SetIgnoreMouseEvents)
|
||||||
.SetMethod("focusOnWebView", &Window::FocusOnWebView)
|
.SetMethod("focusOnWebView", &Window::FocusOnWebView)
|
||||||
.SetMethod("blurWebView", &Window::BlurWebView)
|
.SetMethod("blurWebView", &Window::BlurWebView)
|
||||||
.SetMethod("isWebViewFocused", &Window::IsWebViewFocused)
|
.SetMethod("isWebViewFocused", &Window::IsWebViewFocused)
|
||||||
|
|
|
@ -126,6 +126,7 @@ class Window : public mate::TrackableObject<Window>,
|
||||||
std::string GetRepresentedFilename();
|
std::string GetRepresentedFilename();
|
||||||
void SetDocumentEdited(bool edited);
|
void SetDocumentEdited(bool edited);
|
||||||
bool IsDocumentEdited();
|
bool IsDocumentEdited();
|
||||||
|
void SetIgnoreMouseEvents(bool ignore);
|
||||||
void CapturePage(mate::Arguments* args);
|
void CapturePage(mate::Arguments* args);
|
||||||
void SetProgressBar(double progress);
|
void SetProgressBar(double progress);
|
||||||
void SetOverlayIcon(const gfx::Image& overlay,
|
void SetOverlayIcon(const gfx::Image& overlay,
|
||||||
|
|
|
@ -24,12 +24,11 @@ bool FrameSubscriber::ShouldCaptureFrame(
|
||||||
base::TimeTicks present_time,
|
base::TimeTicks present_time,
|
||||||
scoped_refptr<media::VideoFrame>* storage,
|
scoped_refptr<media::VideoFrame>* storage,
|
||||||
DeliverFrameCallback* callback) {
|
DeliverFrameCallback* callback) {
|
||||||
*storage = media::VideoFrame::CreateFrame(media::VideoFrame::YV12, size_,
|
*storage = media::VideoFrame::CreateFrame(
|
||||||
gfx::Rect(size_), size_,
|
media::PIXEL_FORMAT_YV12,
|
||||||
base::TimeDelta());
|
size_, gfx::Rect(size_), size_, base::TimeDelta());
|
||||||
*callback = base::Bind(&FrameSubscriber::OnFrameDelivered,
|
*callback = base::Bind(&FrameSubscriber::OnFrameDelivered,
|
||||||
base::Unretained(this),
|
base::Unretained(this), *storage);
|
||||||
*storage);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,8 @@ class MenuItem
|
||||||
|
|
||||||
{click, @selector, @type, @role, @label, @sublabel, @accelerator, @icon, @enabled, @visible, @checked, @submenu} = options
|
{click, @selector, @type, @role, @label, @sublabel, @accelerator, @icon, @enabled, @visible, @checked, @submenu} = options
|
||||||
|
|
||||||
|
if @submenu? and @submenu.constructor isnt Menu
|
||||||
|
@submenu = Menu.buildFromTemplate @submenu
|
||||||
@type = 'submenu' if not @type? and @submenu?
|
@type = 'submenu' if not @type? and @submenu?
|
||||||
throw new Error('Invalid submenu') if @type is 'submenu' and @submenu?.constructor isnt Menu
|
throw new Error('Invalid submenu') if @type is 'submenu' and @submenu?.constructor isnt Menu
|
||||||
|
|
||||||
|
|
|
@ -169,9 +169,8 @@ Menu.buildFromTemplate = (template) ->
|
||||||
for item in positionedTemplate
|
for item in positionedTemplate
|
||||||
throw new TypeError('Invalid template for MenuItem') unless typeof item is 'object'
|
throw new TypeError('Invalid template for MenuItem') unless typeof item is 'object'
|
||||||
|
|
||||||
item.submenu = Menu.buildFromTemplate item.submenu if item.submenu?
|
|
||||||
menuItem = new MenuItem(item)
|
menuItem = new MenuItem(item)
|
||||||
menuItem[key] = value for key, value of item when not menuItem[key]?
|
menuItem[key] ?= value for key, value of item
|
||||||
menu.append menuItem
|
menu.append menuItem
|
||||||
|
|
||||||
menu
|
menu
|
||||||
|
|
|
@ -84,7 +84,7 @@ void AtomBrowserClient::SuppressRendererProcessRestartForOnce() {
|
||||||
|
|
||||||
void AtomBrowserClient::SetCustomSchemes(
|
void AtomBrowserClient::SetCustomSchemes(
|
||||||
const std::vector<std::string>& schemes) {
|
const std::vector<std::string>& schemes) {
|
||||||
g_custom_schemes = JoinString(schemes, ',');
|
g_custom_schemes = base::JoinString(schemes, ",");
|
||||||
}
|
}
|
||||||
|
|
||||||
AtomBrowserClient::AtomBrowserClient() : delegate_(nullptr) {
|
AtomBrowserClient::AtomBrowserClient() : delegate_(nullptr) {
|
||||||
|
@ -116,7 +116,6 @@ void AtomBrowserClient::OverrideWebkitPrefs(
|
||||||
prefs->javascript_can_open_windows_automatically = true;
|
prefs->javascript_can_open_windows_automatically = true;
|
||||||
prefs->plugins_enabled = true;
|
prefs->plugins_enabled = true;
|
||||||
prefs->dom_paste_enabled = true;
|
prefs->dom_paste_enabled = true;
|
||||||
prefs->java_enabled = false;
|
|
||||||
prefs->allow_scripts_to_close_windows = true;
|
prefs->allow_scripts_to_close_windows = true;
|
||||||
prefs->javascript_can_access_clipboard = true;
|
prefs->javascript_can_access_clipboard = true;
|
||||||
prefs->local_storage_enabled = true;
|
prefs->local_storage_enabled = true;
|
||||||
|
|
|
@ -61,7 +61,7 @@ std::string RemoveWhitespace(const std::string& str) {
|
||||||
AtomBrowserContext::AtomBrowserContext(const std::string& partition,
|
AtomBrowserContext::AtomBrowserContext(const std::string& partition,
|
||||||
bool in_memory)
|
bool in_memory)
|
||||||
: brightray::BrowserContext(partition, in_memory),
|
: brightray::BrowserContext(partition, in_memory),
|
||||||
cert_verifier_(new AtomCertVerifier),
|
cert_verifier_(nullptr),
|
||||||
job_factory_(new AtomURLRequestJobFactory),
|
job_factory_(new AtomURLRequestJobFactory),
|
||||||
allow_ntlm_everywhere_(false) {
|
allow_ntlm_everywhere_(false) {
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,8 @@ std::string AtomBrowserContext::GetUserAgent() {
|
||||||
return content::BuildUserAgentFromProduct(user_agent);
|
return content::BuildUserAgentFromProduct(user_agent);
|
||||||
}
|
}
|
||||||
|
|
||||||
net::URLRequestJobFactory* AtomBrowserContext::CreateURLRequestJobFactory(
|
scoped_ptr<net::URLRequestJobFactory>
|
||||||
|
AtomBrowserContext::CreateURLRequestJobFactory(
|
||||||
content::ProtocolHandlerMap* handlers,
|
content::ProtocolHandlerMap* handlers,
|
||||||
content::URLRequestInterceptorScopedVector* interceptors) {
|
content::URLRequestInterceptorScopedVector* interceptors) {
|
||||||
scoped_ptr<AtomURLRequestJobFactory> job_factory(job_factory_);
|
scoped_ptr<AtomURLRequestJobFactory> job_factory(job_factory_);
|
||||||
|
@ -131,7 +132,7 @@ net::URLRequestJobFactory* AtomBrowserContext::CreateURLRequestJobFactory(
|
||||||
top_job_factory.Pass(), make_scoped_ptr(*it)));
|
top_job_factory.Pass(), make_scoped_ptr(*it)));
|
||||||
interceptors->weak_clear();
|
interceptors->weak_clear();
|
||||||
|
|
||||||
return top_job_factory.release();
|
return top_job_factory.Pass();
|
||||||
}
|
}
|
||||||
|
|
||||||
net::HttpCache::BackendFactory*
|
net::HttpCache::BackendFactory*
|
||||||
|
@ -160,8 +161,10 @@ content::BrowserPluginGuestManager* AtomBrowserContext::GetGuestManager() {
|
||||||
return guest_manager_.get();
|
return guest_manager_.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
net::CertVerifier* AtomBrowserContext::CreateCertVerifier() {
|
scoped_ptr<net::CertVerifier> AtomBrowserContext::CreateCertVerifier() {
|
||||||
return cert_verifier_;
|
DCHECK(!cert_verifier_);
|
||||||
|
cert_verifier_ = new AtomCertVerifier;
|
||||||
|
return make_scoped_ptr(cert_verifier_);
|
||||||
}
|
}
|
||||||
|
|
||||||
net::SSLConfigService* AtomBrowserContext::CreateSSLConfigService() {
|
net::SSLConfigService* AtomBrowserContext::CreateSSLConfigService() {
|
||||||
|
|
|
@ -23,12 +23,12 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
||||||
|
|
||||||
// brightray::URLRequestContextGetter::Delegate:
|
// brightray::URLRequestContextGetter::Delegate:
|
||||||
std::string GetUserAgent() override;
|
std::string GetUserAgent() override;
|
||||||
net::URLRequestJobFactory* CreateURLRequestJobFactory(
|
scoped_ptr<net::URLRequestJobFactory> CreateURLRequestJobFactory(
|
||||||
content::ProtocolHandlerMap* handlers,
|
content::ProtocolHandlerMap* handlers,
|
||||||
content::URLRequestInterceptorScopedVector* interceptors) override;
|
content::URLRequestInterceptorScopedVector* interceptors) override;
|
||||||
net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory(
|
net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory(
|
||||||
const base::FilePath& base_path) override;
|
const base::FilePath& base_path) override;
|
||||||
net::CertVerifier* CreateCertVerifier() override;
|
scoped_ptr<net::CertVerifier> CreateCertVerifier() override;
|
||||||
net::SSLConfigService* CreateSSLConfigService() override;
|
net::SSLConfigService* CreateSSLConfigService() override;
|
||||||
bool AllowNTLMCredentialsForDomain(const GURL& auth_origin) override;
|
bool AllowNTLMCredentialsForDomain(const GURL& auth_origin) override;
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,7 @@ void Browser::SetUserTasks(const std::vector<UserTask>& tasks) {
|
||||||
|
|
||||||
PCWSTR Browser::GetAppUserModelID() {
|
PCWSTR Browser::GetAppUserModelID() {
|
||||||
if (app_user_model_id_.empty()) {
|
if (app_user_model_id_.empty()) {
|
||||||
SetAppUserModelID(ReplaceStringPlaceholders(
|
SetAppUserModelID(base::ReplaceStringPlaceholders(
|
||||||
kAppUserModelIDFormat, base::UTF8ToUTF16(GetName()), nullptr));
|
kAppUserModelIDFormat, base::UTF8ToUTF16(GetName()), nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -380,7 +380,7 @@ gfx::ImageSkia CommonWebContentsDelegate::GetDevToolsWindowIcon() {
|
||||||
void CommonWebContentsDelegate::GetDevToolsWindowWMClass(
|
void CommonWebContentsDelegate::GetDevToolsWindowWMClass(
|
||||||
std::string* name, std::string* class_name) {
|
std::string* name, std::string* class_name) {
|
||||||
*class_name = Browser::Get()->GetName();
|
*class_name = Browser::Get()->GetName();
|
||||||
*name = base::StringToLowerASCII(*class_name);
|
*name = base::ToLowerASCII(*class_name);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
37
atom/browser/lib/desktop-capturer.coffee
Normal file
37
atom/browser/lib/desktop-capturer.coffee
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
{ipcMain} = require 'electron'
|
||||||
|
{desktopCapturer} = process.atomBinding 'desktop_capturer'
|
||||||
|
|
||||||
|
deepEqual = (opt1, opt2) ->
|
||||||
|
return JSON.stringify(opt1) is JSON.stringify(opt2)
|
||||||
|
|
||||||
|
# A queue for holding all requests from renderer process.
|
||||||
|
requestsQueue = []
|
||||||
|
|
||||||
|
ipcMain.on 'ATOM_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', (event, captureWindow, captureScreen, thumbnailSize, id) ->
|
||||||
|
request = id: id, options: {captureWindow, captureScreen, thumbnailSize}, webContents: event.sender
|
||||||
|
requestsQueue.push request
|
||||||
|
desktopCapturer.startHandling captureWindow, captureScreen, thumbnailSize if requestsQueue.length is 1
|
||||||
|
# If the WebContents is destroyed before receiving result, just remove the
|
||||||
|
# reference from requestsQueue to make the module not send the result to it.
|
||||||
|
event.sender.once 'destroyed', ->
|
||||||
|
request.webContents = null
|
||||||
|
|
||||||
|
desktopCapturer.emit = (event, name, sources) ->
|
||||||
|
# Receiving sources result from main process, now send them back to renderer.
|
||||||
|
handledRequest = requestsQueue.shift 0
|
||||||
|
result = ({ id: source.id, name: source.name, thumbnail: source.thumbnail.toDataUrl() } for source in sources)
|
||||||
|
handledRequest.webContents?.send "ATOM_RENDERER_DESKTOP_CAPTURER_RESULT_#{handledRequest.id}", result
|
||||||
|
|
||||||
|
# Check the queue to see whether there is other same request. If has, handle
|
||||||
|
# it for reducing redunplicated `desktopCaptuer.startHandling` calls.
|
||||||
|
unhandledRequestsQueue = []
|
||||||
|
for request in requestsQueue
|
||||||
|
if deepEqual handledRequest.options, request.options
|
||||||
|
request.webContents?.send "ATOM_RENDERER_DESKTOP_CAPTURER_RESULT_#{request.id}", errorMessage, result
|
||||||
|
else
|
||||||
|
unhandledRequestsQueue.push request
|
||||||
|
requestsQueue = unhandledRequestsQueue
|
||||||
|
# If the requestsQueue is not empty, start a new request handling.
|
||||||
|
if requestsQueue.length > 0
|
||||||
|
{captureWindow, captureScreen, thumbnailSize} = requestsQueue[0].options
|
||||||
|
desktopCapturer.startHandling captureWindow, captureScreen, thumbnailSize
|
|
@ -5,7 +5,7 @@ frameToGuest = {}
|
||||||
|
|
||||||
# Copy attribute of |parent| to |child| if it is not defined in |child|.
|
# Copy attribute of |parent| to |child| if it is not defined in |child|.
|
||||||
mergeOptions = (child, parent) ->
|
mergeOptions = (child, parent) ->
|
||||||
for own key, value of parent when key not in Object.keys child
|
for own key, value of parent when key not of child
|
||||||
if typeof value is 'object'
|
if typeof value is 'object'
|
||||||
child[key] = mergeOptions {}, value
|
child[key] = mergeOptions {}, value
|
||||||
else
|
else
|
||||||
|
@ -44,7 +44,7 @@ createGuest = (embedder, url, frameName, options) ->
|
||||||
guest.removeListener 'closed', closedByUser
|
guest.removeListener 'closed', closedByUser
|
||||||
guest.destroy()
|
guest.destroy()
|
||||||
closedByUser = ->
|
closedByUser = ->
|
||||||
embedder.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSED', guestId
|
embedder.send "ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSED_#{guestId}"
|
||||||
embedder.removeListener 'render-view-deleted', closedByEmbedder
|
embedder.removeListener 'render-view-deleted', closedByEmbedder
|
||||||
embedder.once 'render-view-deleted', closedByEmbedder
|
embedder.once 'render-view-deleted', closedByEmbedder
|
||||||
guest.once 'closed', closedByUser
|
guest.once 'closed', closedByUser
|
||||||
|
|
|
@ -108,6 +108,9 @@ app.setAppPath packagePath
|
||||||
# Load the chrome extension support.
|
# Load the chrome extension support.
|
||||||
require './chrome-extension'
|
require './chrome-extension'
|
||||||
|
|
||||||
|
# Load internal desktop-capturer module.
|
||||||
|
require './desktop-capturer'
|
||||||
|
|
||||||
# Set main startup script of the app.
|
# Set main startup script of the app.
|
||||||
mainStartupScript = packageJson.main or 'index.js'
|
mainStartupScript = packageJson.main or 'index.js'
|
||||||
|
|
||||||
|
|
|
@ -245,6 +245,9 @@ bool NativeWindow::IsDocumentEdited() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NativeWindow::SetIgnoreMouseEvents(bool ignore) {
|
||||||
|
}
|
||||||
|
|
||||||
void NativeWindow::SetMenu(ui::MenuModel* menu) {
|
void NativeWindow::SetMenu(ui::MenuModel* menu) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,10 +294,10 @@ void NativeWindow::CapturePage(const gfx::Rect& rect,
|
||||||
const float scale =
|
const float scale =
|
||||||
screen->GetDisplayNearestWindow(native_view).device_scale_factor();
|
screen->GetDisplayNearestWindow(native_view).device_scale_factor();
|
||||||
if (scale > 1.0f)
|
if (scale > 1.0f)
|
||||||
bitmap_size = gfx::ToCeiledSize(gfx::ScaleSize(view_size, scale));
|
bitmap_size = gfx::ScaleToCeiledSize(view_size, scale);
|
||||||
|
|
||||||
host->CopyFromBackingStore(
|
host->CopyFromBackingStore(
|
||||||
rect.IsEmpty() ? gfx::Rect(view_size) : rect,
|
gfx::Rect(view_size),
|
||||||
bitmap_size,
|
bitmap_size,
|
||||||
base::Bind(&NativeWindow::OnCapturePageDone,
|
base::Bind(&NativeWindow::OnCapturePageDone,
|
||||||
weak_factory_.GetWeakPtr(),
|
weak_factory_.GetWeakPtr(),
|
||||||
|
|
|
@ -139,6 +139,7 @@ class NativeWindow : public base::SupportsUserData,
|
||||||
virtual std::string GetRepresentedFilename();
|
virtual std::string GetRepresentedFilename();
|
||||||
virtual void SetDocumentEdited(bool edited);
|
virtual void SetDocumentEdited(bool edited);
|
||||||
virtual bool IsDocumentEdited();
|
virtual bool IsDocumentEdited();
|
||||||
|
virtual void SetIgnoreMouseEvents(bool ignore);
|
||||||
virtual void SetMenu(ui::MenuModel* menu);
|
virtual void SetMenu(ui::MenuModel* menu);
|
||||||
virtual bool HasModalDialog();
|
virtual bool HasModalDialog();
|
||||||
virtual gfx::NativeWindow GetNativeWindow() = 0;
|
virtual gfx::NativeWindow GetNativeWindow() = 0;
|
||||||
|
|
|
@ -62,6 +62,7 @@ class NativeWindowMac : public NativeWindow {
|
||||||
std::string GetRepresentedFilename() override;
|
std::string GetRepresentedFilename() override;
|
||||||
void SetDocumentEdited(bool edited) override;
|
void SetDocumentEdited(bool edited) override;
|
||||||
bool IsDocumentEdited() override;
|
bool IsDocumentEdited() override;
|
||||||
|
void SetIgnoreMouseEvents(bool ignore) override;
|
||||||
bool HasModalDialog() override;
|
bool HasModalDialog() override;
|
||||||
gfx::NativeWindow GetNativeWindow() override;
|
gfx::NativeWindow GetNativeWindow() override;
|
||||||
void SetProgressBar(double progress) override;
|
void SetProgressBar(double progress) override;
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#import "atom/browser/ui/cocoa/event_processing_window.h"
|
|
||||||
#include "atom/common/draggable_region.h"
|
#include "atom/common/draggable_region.h"
|
||||||
#include "atom/common/options_switches.h"
|
#include "atom/common/options_switches.h"
|
||||||
#include "base/mac/mac_util.h"
|
#include "base/mac/mac_util.h"
|
||||||
|
@ -209,7 +208,7 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface AtomNSWindow : EventProcessingWindow {
|
@interface AtomNSWindow : NSWindow {
|
||||||
@private
|
@private
|
||||||
atom::NativeWindowMac* shell_;
|
atom::NativeWindowMac* shell_;
|
||||||
bool enable_larger_than_screen_;
|
bool enable_larger_than_screen_;
|
||||||
|
@ -232,6 +231,8 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||||
enable_larger_than_screen_ = enable;
|
enable_larger_than_screen_ = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NSWindow overrides.
|
||||||
|
|
||||||
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen*)screen {
|
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen*)screen {
|
||||||
// Resizing is disabled.
|
// Resizing is disabled.
|
||||||
if (ScopedDisableResize::IsResizeDisabled())
|
if (ScopedDisableResize::IsResizeDisabled())
|
||||||
|
@ -687,6 +688,10 @@ bool NativeWindowMac::IsDocumentEdited() {
|
||||||
return [window_ isDocumentEdited];
|
return [window_ isDocumentEdited];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NativeWindowMac::SetIgnoreMouseEvents(bool ignore) {
|
||||||
|
[window_ setIgnoresMouseEvents:ignore];
|
||||||
|
}
|
||||||
|
|
||||||
bool NativeWindowMac::HasModalDialog() {
|
bool NativeWindowMac::HasModalDialog() {
|
||||||
return [window_ attachedSheet] != nil;
|
return [window_ attachedSheet] != nil;
|
||||||
}
|
}
|
||||||
|
@ -766,20 +771,14 @@ void NativeWindowMac::HandleKeyboardEvent(
|
||||||
event.type == content::NativeWebKeyboardEvent::Char)
|
event.type == content::NativeWebKeyboardEvent::Char)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (event.os_event.window == window_.get()) {
|
BOOL handled = [[NSApp mainMenu] performKeyEquivalent:event.os_event];
|
||||||
EventProcessingWindow* event_window =
|
if (!handled && event.os_event.window != window_.get()) {
|
||||||
static_cast<EventProcessingWindow*>(window_);
|
|
||||||
DCHECK([event_window isKindOfClass:[EventProcessingWindow class]]);
|
|
||||||
[event_window redispatchKeyEvent:event.os_event];
|
|
||||||
} else {
|
|
||||||
// The event comes from detached devtools view, and it has already been
|
// The event comes from detached devtools view, and it has already been
|
||||||
// handled by the devtools itself, we now send it to application menu to
|
|
||||||
// make menu acclerators work.
|
|
||||||
BOOL handled = [[NSApp mainMenu] performKeyEquivalent:event.os_event];
|
|
||||||
// Handle the cmd+~ shortcut.
|
|
||||||
if (!handled && (event.os_event.modifierFlags & NSCommandKeyMask) &&
|
if (!handled && (event.os_event.modifierFlags & NSCommandKeyMask) &&
|
||||||
(event.os_event.keyCode == 50 /* ~ key */))
|
(event.os_event.keyCode == 50 /* ~ key */)) {
|
||||||
|
// Handle the cmd+~ shortcut.
|
||||||
Focus(true);
|
Focus(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -180,7 +180,7 @@ NativeWindowViews::NativeWindowViews(
|
||||||
// Set WM_WINDOW_ROLE.
|
// Set WM_WINDOW_ROLE.
|
||||||
params.wm_role_name = "browser-window";
|
params.wm_role_name = "browser-window";
|
||||||
// Set WM_CLASS.
|
// Set WM_CLASS.
|
||||||
params.wm_class_name = base::StringToLowerASCII(name);
|
params.wm_class_name = base::ToLowerASCII(name);
|
||||||
params.wm_class_class = name;
|
params.wm_class_class = name;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "net/http/http_response_headers.h"
|
#include "net/http/http_response_headers.h"
|
||||||
#include "net/url_request/url_fetcher.h"
|
#include "net/url_request/url_fetcher.h"
|
||||||
#include "net/url_request/url_fetcher_response_writer.h"
|
#include "net/url_request/url_fetcher_response_writer.h"
|
||||||
|
#include "net/url_request/url_request_context.h"
|
||||||
#include "net/url_request/url_request_context_builder.h"
|
#include "net/url_request/url_request_context_builder.h"
|
||||||
#include "net/url_request/url_request_status.h"
|
#include "net/url_request/url_request_status.h"
|
||||||
|
|
||||||
|
@ -23,7 +24,7 @@ namespace {
|
||||||
|
|
||||||
// Convert string to RequestType.
|
// Convert string to RequestType.
|
||||||
net::URLFetcher::RequestType GetRequestType(const std::string& raw) {
|
net::URLFetcher::RequestType GetRequestType(const std::string& raw) {
|
||||||
std::string method = base::StringToUpperASCII(raw);
|
std::string method = base::ToUpperASCII(raw);
|
||||||
if (method.empty() || method == "GET")
|
if (method.empty() || method == "GET")
|
||||||
return net::URLFetcher::GET;
|
return net::URLFetcher::GET;
|
||||||
else if (method == "POST")
|
else if (method == "POST")
|
||||||
|
@ -138,8 +139,9 @@ net::URLRequestContextGetter* URLRequestFetchJob::CreateRequestContext() {
|
||||||
auto task_runner = base::ThreadTaskRunnerHandle::Get();
|
auto task_runner = base::ThreadTaskRunnerHandle::Get();
|
||||||
net::URLRequestContextBuilder builder;
|
net::URLRequestContextBuilder builder;
|
||||||
builder.set_proxy_service(net::ProxyService::CreateDirect());
|
builder.set_proxy_service(net::ProxyService::CreateDirect());
|
||||||
url_request_context_getter_ =
|
request_context_ = builder.Build();
|
||||||
new net::TrivialURLRequestContextGetter(builder.Build(), task_runner);
|
url_request_context_getter_ = new net::TrivialURLRequestContextGetter(
|
||||||
|
request_context_.get(), task_runner);
|
||||||
}
|
}
|
||||||
return url_request_context_getter_.get();
|
return url_request_context_getter_.get();
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ class URLRequestFetchJob : public JsAsker<net::URLRequestJob>,
|
||||||
// Create a independent request context.
|
// Create a independent request context.
|
||||||
net::URLRequestContextGetter* CreateRequestContext();
|
net::URLRequestContextGetter* CreateRequestContext();
|
||||||
|
|
||||||
|
scoped_ptr<net::URLRequestContext> request_context_;
|
||||||
scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
|
scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
|
||||||
scoped_ptr<net::URLFetcher> fetcher_;
|
scoped_ptr<net::URLFetcher> fetcher_;
|
||||||
scoped_refptr<net::IOBuffer> pending_buffer_;
|
scoped_refptr<net::IOBuffer> pending_buffer_;
|
||||||
|
|
|
@ -17,9 +17,9 @@
|
||||||
<key>CFBundleIconFile</key>
|
<key>CFBundleIconFile</key>
|
||||||
<string>atom.icns</string>
|
<string>atom.icns</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>0.35.2</string>
|
<string>0.35.4</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>0.35.2</string>
|
<string>0.35.4</string>
|
||||||
<key>LSApplicationCategoryType</key>
|
<key>LSApplicationCategoryType</key>
|
||||||
<string>public.app-category.developer-tools</string>
|
<string>public.app-category.developer-tools</string>
|
||||||
<key>LSMinimumSystemVersion</key>
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
|
|
@ -56,8 +56,8 @@ END
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 0,35,2,0
|
FILEVERSION 0,35,4,0
|
||||||
PRODUCTVERSION 0,35,2,0
|
PRODUCTVERSION 0,35,4,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -74,12 +74,12 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "GitHub, Inc."
|
VALUE "CompanyName", "GitHub, Inc."
|
||||||
VALUE "FileDescription", "Electron"
|
VALUE "FileDescription", "Electron"
|
||||||
VALUE "FileVersion", "0.35.2"
|
VALUE "FileVersion", "0.35.4"
|
||||||
VALUE "InternalName", "electron.exe"
|
VALUE "InternalName", "electron.exe"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
||||||
VALUE "OriginalFilename", "electron.exe"
|
VALUE "OriginalFilename", "electron.exe"
|
||||||
VALUE "ProductName", "Electron"
|
VALUE "ProductName", "Electron"
|
||||||
VALUE "ProductVersion", "0.35.2"
|
VALUE "ProductVersion", "0.35.4"
|
||||||
VALUE "SquirrelAwareVersion", "1"
|
VALUE "SquirrelAwareVersion", "1"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|
|
@ -24,10 +24,10 @@ bool StringToAccelerator(const std::string& description,
|
||||||
LOG(ERROR) << "The accelerator string can only contain ASCII characters";
|
LOG(ERROR) << "The accelerator string can only contain ASCII characters";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::string shortcut(base::StringToLowerASCII(description));
|
std::string shortcut(base::ToLowerASCII(description));
|
||||||
|
|
||||||
std::vector<std::string> tokens;
|
std::vector<std::string> tokens = base::SplitString(
|
||||||
base::SplitString(shortcut, '+', &tokens);
|
shortcut, "+", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||||
|
|
||||||
// Now, parse it into an accelerator.
|
// Now, parse it into an accelerator.
|
||||||
int modifiers = ui::EF_NONE;
|
int modifiers = ui::EF_NONE;
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
// Copyright (c) 2013 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_COCOA_EVENT_PROCESSING_WINDOW_H_
|
|
||||||
#define ATOM_BROWSER_UI_COCOA_EVENT_PROCESSING_WINDOW_H_
|
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
|
||||||
|
|
||||||
// Override NSWindow to access unhandled keyboard events (for command
|
|
||||||
// processing); subclassing NSWindow is the only method to do
|
|
||||||
// this.
|
|
||||||
@interface EventProcessingWindow : NSWindow {
|
|
||||||
@private
|
|
||||||
BOOL redispatchingEvent_;
|
|
||||||
BOOL eventHandled_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sends a key event to |NSApp sendEvent:|, but also makes sure that it's not
|
|
||||||
// short-circuited to the RWHV. This is used to send keyboard events to the menu
|
|
||||||
// and the cmd-` handler if a keyboard event comes back unhandled from the
|
|
||||||
// renderer. The event must be of type |NSKeyDown|, |NSKeyUp|, or
|
|
||||||
// |NSFlagsChanged|.
|
|
||||||
// Returns |YES| if |event| has been handled.
|
|
||||||
- (BOOL)redispatchKeyEvent:(NSEvent*)event;
|
|
||||||
|
|
||||||
- (BOOL)performKeyEquivalent:(NSEvent*)theEvent;
|
|
||||||
@end
|
|
||||||
|
|
||||||
#endif // ATOM_BROWSER_UI_COCOA_EVENT_PROCESSING_WINDOW_H_
|
|
|
@ -1,106 +0,0 @@
|
||||||
// Copyright (c) 2013 GitHub, Inc.
|
|
||||||
// Use of this source code is governed by the MIT license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#import "atom/browser/ui/cocoa/event_processing_window.h"
|
|
||||||
|
|
||||||
#include "base/logging.h"
|
|
||||||
#import "content/public/browser/render_widget_host_view_mac_base.h"
|
|
||||||
|
|
||||||
@interface EventProcessingWindow ()
|
|
||||||
// Duplicate the given key event, but changing the associated window.
|
|
||||||
- (NSEvent*)keyEventForWindow:(NSWindow*)window fromKeyEvent:(NSEvent*)event;
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation EventProcessingWindow
|
|
||||||
|
|
||||||
- (BOOL)redispatchKeyEvent:(NSEvent*)event {
|
|
||||||
DCHECK(event);
|
|
||||||
NSEventType eventType = [event type];
|
|
||||||
if (eventType != NSKeyDown &&
|
|
||||||
eventType != NSKeyUp &&
|
|
||||||
eventType != NSFlagsChanged) {
|
|
||||||
NOTREACHED();
|
|
||||||
return YES; // Pretend it's been handled in an effort to limit damage.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ordinarily, the event's window should be this window. However, when
|
|
||||||
// switching between normal and fullscreen mode, we switch out the window, and
|
|
||||||
// the event's window might be the previous window (or even an earlier one if
|
|
||||||
// the renderer is running slowly and several mode switches occur). In this
|
|
||||||
// rare case, we synthesize a new key event so that its associate window
|
|
||||||
// (number) is our own.
|
|
||||||
if ([event window] != self)
|
|
||||||
event = [self keyEventForWindow:self fromKeyEvent:event];
|
|
||||||
|
|
||||||
// Redispatch the event.
|
|
||||||
eventHandled_ = YES;
|
|
||||||
redispatchingEvent_ = YES;
|
|
||||||
[NSApp sendEvent:event];
|
|
||||||
redispatchingEvent_ = NO;
|
|
||||||
|
|
||||||
// If the event was not handled by [NSApp sendEvent:], the sendEvent:
|
|
||||||
// method below will be called, and because |redispatchingEvent_| is YES,
|
|
||||||
// |eventHandled_| will be set to NO.
|
|
||||||
return eventHandled_;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)sendEvent:(NSEvent*)event {
|
|
||||||
if (!redispatchingEvent_)
|
|
||||||
[super sendEvent:event];
|
|
||||||
else
|
|
||||||
eventHandled_ = NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSEvent*)keyEventForWindow:(NSWindow*)window fromKeyEvent:(NSEvent*)event {
|
|
||||||
NSEventType eventType = [event type];
|
|
||||||
|
|
||||||
// Convert the event's location from the original window's coordinates into
|
|
||||||
// our own.
|
|
||||||
NSPoint eventLoc = [event locationInWindow];
|
|
||||||
eventLoc = [self convertRectFromScreen:
|
|
||||||
[[event window] convertRectToScreen:NSMakeRect(eventLoc.x, eventLoc.y, 0, 0)]].origin;
|
|
||||||
|
|
||||||
// Various things *only* apply to key down/up.
|
|
||||||
BOOL eventIsARepeat = NO;
|
|
||||||
NSString* eventCharacters = nil;
|
|
||||||
NSString* eventUnmodCharacters = nil;
|
|
||||||
if (eventType == NSKeyDown || eventType == NSKeyUp) {
|
|
||||||
eventIsARepeat = [event isARepeat];
|
|
||||||
eventCharacters = [event characters];
|
|
||||||
eventUnmodCharacters = [event charactersIgnoringModifiers];
|
|
||||||
}
|
|
||||||
|
|
||||||
// This synthesis may be slightly imperfect: we provide nil for the context,
|
|
||||||
// since I (viettrungluu) am sceptical that putting in the original context
|
|
||||||
// (if one is given) is valid.
|
|
||||||
return [NSEvent keyEventWithType:eventType
|
|
||||||
location:eventLoc
|
|
||||||
modifierFlags:[event modifierFlags]
|
|
||||||
timestamp:[event timestamp]
|
|
||||||
windowNumber:[window windowNumber]
|
|
||||||
context:nil
|
|
||||||
characters:eventCharacters
|
|
||||||
charactersIgnoringModifiers:eventUnmodCharacters
|
|
||||||
isARepeat:eventIsARepeat
|
|
||||||
keyCode:[event keyCode]];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
- (BOOL)performKeyEquivalent:(NSEvent*)event {
|
|
||||||
if (redispatchingEvent_)
|
|
||||||
return NO;
|
|
||||||
|
|
||||||
// Give the web site a chance to handle the event. If it doesn't want to
|
|
||||||
// handle it, it will call us back with one of the |handle*| methods above.
|
|
||||||
NSResponder* r = [self firstResponder];
|
|
||||||
if ([r conformsToProtocol:@protocol(RenderWidgetHostViewMacBase)])
|
|
||||||
return [r performKeyEquivalent:event];
|
|
||||||
|
|
||||||
if ([super performKeyEquivalent:event])
|
|
||||||
return YES;
|
|
||||||
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end // EventProcessingWindow
|
|
|
@ -22,7 +22,9 @@ gboolean FileFilterCaseInsensitive(const GtkFileFilterInfo* file_info,
|
||||||
// Makes .* file extension matches all file types.
|
// Makes .* file extension matches all file types.
|
||||||
if (*file_extension == ".*")
|
if (*file_extension == ".*")
|
||||||
return true;
|
return true;
|
||||||
return base::EndsWith(file_info->filename, *file_extension, false);
|
return base::EndsWith(
|
||||||
|
file_info->filename,
|
||||||
|
*file_extension, base::CompareCase::INSENSITIVE_ASCII);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deletes |data| when gtk_file_filter_add_custom() is done with it.
|
// Deletes |data| when gtk_file_filter_add_custom() is done with it.
|
||||||
|
|
|
@ -51,7 +51,7 @@ void ConvertFilters(const Filters& filters,
|
||||||
std::vector<std::string> extensions(filter.second);
|
std::vector<std::string> extensions(filter.second);
|
||||||
for (size_t j = 0; j < extensions.size(); ++j)
|
for (size_t j = 0; j < extensions.size(); ++j)
|
||||||
extensions[j].insert(0, "*.");
|
extensions[j].insert(0, "*.");
|
||||||
buffer->push_back(base::UTF8ToWide(JoinString(extensions, ";")));
|
buffer->push_back(base::UTF8ToWide(base::JoinString(extensions, ";")));
|
||||||
spec.pszSpec = buffer->back().c_str();
|
spec.pszSpec = buffer->back().c_str();
|
||||||
|
|
||||||
filterspec->push_back(spec);
|
filterspec->push_back(spec);
|
||||||
|
@ -273,7 +273,9 @@ bool ShowSaveDialog(atom::NativeWindow* parent_window,
|
||||||
bool matched = false;
|
bool matched = false;
|
||||||
for (size_t i = 0; i < filter.second.size(); ++i) {
|
for (size_t i = 0; i < filter.second.size(); ++i) {
|
||||||
if (filter.second[i] == "*" ||
|
if (filter.second[i] == "*" ||
|
||||||
base::EndsWith(file_name, filter.second[i], false)) {
|
base::EndsWith(
|
||||||
|
file_name, filter.second[i],
|
||||||
|
base::CompareCase::INSENSITIVE_ASCII)) {
|
||||||
matched = true;
|
matched = true;
|
||||||
break;;
|
break;;
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,7 @@ class GtkMessageBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* TranslateToStock(int id, const std::string& text) {
|
const char* TranslateToStock(int id, const std::string& text) {
|
||||||
std::string lower = base::StringToLowerASCII(text);
|
std::string lower = base::ToLowerASCII(text);
|
||||||
if (lower == "cancel")
|
if (lower == "cancel")
|
||||||
return GTK_STOCK_CANCEL;
|
return GTK_STOCK_CANCEL;
|
||||||
else if (lower == "no")
|
else if (lower == "no")
|
||||||
|
|
|
@ -34,7 +34,7 @@ struct CommonButtonID {
|
||||||
int id;
|
int id;
|
||||||
};
|
};
|
||||||
CommonButtonID GetCommonID(const base::string16& button) {
|
CommonButtonID GetCommonID(const base::string16& button) {
|
||||||
base::string16 lower = base::StringToLowerASCII(button);
|
base::string16 lower = base::ToLowerASCII(button);
|
||||||
if (lower == L"ok")
|
if (lower == L"ok")
|
||||||
return { TDCBF_OK_BUTTON, IDOK };
|
return { TDCBF_OK_BUTTON, IDOK };
|
||||||
else if (lower == L"yes")
|
else if (lower == L"yes")
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
#include "ui/gfx/color_utils.h"
|
#include "ui/gfx/color_utils.h"
|
||||||
#elif defined(USE_X11)
|
#elif defined(USE_X11)
|
||||||
#include "chrome/browser/ui/libgtk2ui/owned_widget_gtk2.h"
|
|
||||||
#include "chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h"
|
#include "chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -33,15 +32,16 @@ const SkColor kDefaultColor = SkColorSetARGB(255, 233, 233, 233);
|
||||||
#if defined(USE_X11)
|
#if defined(USE_X11)
|
||||||
void GetMenuBarColor(SkColor* enabled, SkColor* disabled, SkColor* highlight,
|
void GetMenuBarColor(SkColor* enabled, SkColor* disabled, SkColor* highlight,
|
||||||
SkColor* hover, SkColor* background) {
|
SkColor* hover, SkColor* background) {
|
||||||
libgtk2ui::OwnedWidgetGtk fake_menu_bar;
|
GtkWidget* menu_bar = gtk_menu_bar_new();
|
||||||
fake_menu_bar.Own(gtk_menu_bar_new());
|
|
||||||
|
|
||||||
GtkStyle* style = gtk_rc_get_style(fake_menu_bar.get());
|
GtkStyle* style = gtk_rc_get_style(menu_bar);
|
||||||
*enabled = libgtk2ui::GdkColorToSkColor(style->fg[GTK_STATE_NORMAL]);
|
*enabled = libgtk2ui::GdkColorToSkColor(style->fg[GTK_STATE_NORMAL]);
|
||||||
*disabled = libgtk2ui::GdkColorToSkColor(style->fg[GTK_STATE_INSENSITIVE]);
|
*disabled = libgtk2ui::GdkColorToSkColor(style->fg[GTK_STATE_INSENSITIVE]);
|
||||||
*highlight = libgtk2ui::GdkColorToSkColor(style->fg[GTK_STATE_SELECTED]);
|
*highlight = libgtk2ui::GdkColorToSkColor(style->fg[GTK_STATE_SELECTED]);
|
||||||
*hover = libgtk2ui::GdkColorToSkColor(style->fg[GTK_STATE_PRELIGHT]);
|
*hover = libgtk2ui::GdkColorToSkColor(style->fg[GTK_STATE_PRELIGHT]);
|
||||||
*background = libgtk2ui::GdkColorToSkColor(style->bg[GTK_STATE_NORMAL]);
|
*background = libgtk2ui::GdkColorToSkColor(style->bg[GTK_STATE_NORMAL]);
|
||||||
|
|
||||||
|
gtk_widget_destroy(menu_bar);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ void SetWindowType(::Window xwindow, const std::string& type) {
|
||||||
XDisplay* xdisplay = gfx::GetXDisplay();
|
XDisplay* xdisplay = gfx::GetXDisplay();
|
||||||
std::string type_prefix = "_NET_WM_WINDOW_TYPE_";
|
std::string type_prefix = "_NET_WM_WINDOW_TYPE_";
|
||||||
::Atom window_type = XInternAtom(
|
::Atom window_type = XInternAtom(
|
||||||
xdisplay, (type_prefix + base::StringToUpperASCII(type)).c_str(), False);
|
xdisplay, (type_prefix + base::ToUpperASCII(type)).c_str(), False);
|
||||||
XChangeProperty(xdisplay, xwindow,
|
XChangeProperty(xdisplay, xwindow,
|
||||||
XInternAtom(xdisplay, "_NET_WM_WINDOW_TYPE", False),
|
XInternAtom(xdisplay, "_NET_WM_WINDOW_TYPE", False),
|
||||||
XA_ATOM,
|
XA_ATOM,
|
||||||
|
|
|
@ -36,8 +36,6 @@ FeaturePair kWebRuntimeFeatures[] = {
|
||||||
switches::kExperimentalCanvasFeatures },
|
switches::kExperimentalCanvasFeatures },
|
||||||
{ options::kOverlayScrollbars,
|
{ options::kOverlayScrollbars,
|
||||||
switches::kOverlayScrollbars },
|
switches::kOverlayScrollbars },
|
||||||
{ options::kOverlayFullscreenVideo,
|
|
||||||
switches::kOverlayFullscreenVideo },
|
|
||||||
{ options::kSharedWorker,
|
{ options::kSharedWorker,
|
||||||
switches::kSharedWorker },
|
switches::kSharedWorker },
|
||||||
{ options::kPageVisibility,
|
{ options::kPageVisibility,
|
||||||
|
@ -148,8 +146,6 @@ void WebContentsPreferences::OverrideWebkitPrefs(
|
||||||
prefs->javascript_enabled = b;
|
prefs->javascript_enabled = b;
|
||||||
if (self->web_preferences_.GetBoolean("images", &b))
|
if (self->web_preferences_.GetBoolean("images", &b))
|
||||||
prefs->images_enabled = b;
|
prefs->images_enabled = b;
|
||||||
if (self->web_preferences_.GetBoolean("java", &b))
|
|
||||||
prefs->java_enabled = b;
|
|
||||||
if (self->web_preferences_.GetBoolean("textAreasAreResizable", &b))
|
if (self->web_preferences_.GetBoolean("textAreasAreResizable", &b))
|
||||||
prefs->text_areas_are_resizable = b;
|
prefs->text_areas_are_resizable = b;
|
||||||
if (self->web_preferences_.GetBoolean("webgl", &b))
|
if (self->web_preferences_.GetBoolean("webgl", &b))
|
||||||
|
|
|
@ -63,7 +63,8 @@ float GetScaleFactorFromPath(const base::FilePath& path) {
|
||||||
// We don't try to convert string to float here because it is very very
|
// We don't try to convert string to float here because it is very very
|
||||||
// expensive.
|
// expensive.
|
||||||
for (unsigned i = 0; i < arraysize(kScaleFactorPairs); ++i) {
|
for (unsigned i = 0; i < arraysize(kScaleFactorPairs); ++i) {
|
||||||
if (base::EndsWith(filename, kScaleFactorPairs[i].name, true))
|
if (base::EndsWith(filename, kScaleFactorPairs[i].name,
|
||||||
|
base::CompareCase::INSENSITIVE_ASCII))
|
||||||
return kScaleFactorPairs[i].scale;
|
return kScaleFactorPairs[i].scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ v8::Local<v8::Value> CallEmitWithArgs(v8::Isolate* isolate,
|
||||||
// Perform microtask checkpoint after running JavaScript.
|
// Perform microtask checkpoint after running JavaScript.
|
||||||
scoped_ptr<blink::WebScopedRunV8Script> script_scope(
|
scoped_ptr<blink::WebScopedRunV8Script> script_scope(
|
||||||
Locker::IsBrowserProcess() ?
|
Locker::IsBrowserProcess() ?
|
||||||
nullptr : new blink::WebScopedRunV8Script(isolate));
|
nullptr : new blink::WebScopedRunV8Script);
|
||||||
// Use node::MakeCallback to call the callback, and it will also run pending
|
// Use node::MakeCallback to call the callback, and it will also run pending
|
||||||
// tasks in Node.js.
|
// tasks in Node.js.
|
||||||
return node::MakeCallback(
|
return node::MakeCallback(
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
#define ATOM_MAJOR_VERSION 0
|
#define ATOM_MAJOR_VERSION 0
|
||||||
#define ATOM_MINOR_VERSION 35
|
#define ATOM_MINOR_VERSION 35
|
||||||
#define ATOM_PATCH_VERSION 2
|
#define ATOM_PATCH_VERSION 4
|
||||||
|
|
||||||
#define ATOM_VERSION_IS_RELEASE 1
|
#define ATOM_VERSION_IS_RELEASE 1
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#ifndef ATOM_COMMON_CHROME_VERSION_H_
|
#ifndef ATOM_COMMON_CHROME_VERSION_H_
|
||||||
#define ATOM_COMMON_CHROME_VERSION_H_
|
#define ATOM_COMMON_CHROME_VERSION_H_
|
||||||
|
|
||||||
#define CHROME_VERSION_STRING "45.0.2454.85"
|
#define CHROME_VERSION_STRING "47.0.2526.73"
|
||||||
#define CHROME_VERSION "v" CHROME_VERSION_STRING
|
#define CHROME_VERSION "v" CHROME_VERSION_STRING
|
||||||
|
|
||||||
#endif // ATOM_COMMON_CHROME_VERSION_H_
|
#endif // ATOM_COMMON_CHROME_VERSION_H_
|
||||||
|
|
|
@ -48,11 +48,11 @@ CrashReporter::GetUploadedReports(const std::string& path) {
|
||||||
std::vector<CrashReporter::UploadReportResult> result;
|
std::vector<CrashReporter::UploadReportResult> result;
|
||||||
if (base::ReadFileToString(base::FilePath::FromUTF8Unsafe(path),
|
if (base::ReadFileToString(base::FilePath::FromUTF8Unsafe(path),
|
||||||
&file_content)) {
|
&file_content)) {
|
||||||
std::vector<std::string> reports;
|
std::vector<std::string> reports = base::SplitString(
|
||||||
base::SplitString(file_content, '\n', &reports);
|
file_content, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||||
for (const std::string& report : reports) {
|
for (const std::string& report : reports) {
|
||||||
std::vector<std::string> report_item;
|
std::vector<std::string> report_item = base::SplitString(
|
||||||
base::SplitString(report, ',', &report_item);
|
report, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||||
int report_time = 0;
|
int report_time = 0;
|
||||||
if (report_item.size() >= 2 && base::StringToInt(report_item[0],
|
if (report_item.size() >= 2 && base::StringToInt(report_item[0],
|
||||||
&report_time)) {
|
&report_time)) {
|
||||||
|
|
|
@ -130,7 +130,7 @@ bool CrashReporterLinux::CrashDone(const MinidumpDescriptor& minidump,
|
||||||
|
|
||||||
// static
|
// static
|
||||||
CrashReporterLinux* CrashReporterLinux::GetInstance() {
|
CrashReporterLinux* CrashReporterLinux::GetInstance() {
|
||||||
return Singleton<CrashReporterLinux>::get();
|
return base::Singleton<CrashReporterLinux>::get();
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
|
|
@ -12,7 +12,9 @@
|
||||||
#include "base/compiler_specific.h"
|
#include "base/compiler_specific.h"
|
||||||
#include "base/memory/scoped_ptr.h"
|
#include "base/memory/scoped_ptr.h"
|
||||||
|
|
||||||
|
namespace base {
|
||||||
template <typename T> struct DefaultSingletonTraits;
|
template <typename T> struct DefaultSingletonTraits;
|
||||||
|
}
|
||||||
|
|
||||||
namespace google_breakpad {
|
namespace google_breakpad {
|
||||||
class ExceptionHandler;
|
class ExceptionHandler;
|
||||||
|
@ -34,7 +36,7 @@ class CrashReporterLinux : public CrashReporter {
|
||||||
void SetUploadParameters() override;
|
void SetUploadParameters() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend struct DefaultSingletonTraits<CrashReporterLinux>;
|
friend struct base::DefaultSingletonTraits<CrashReporterLinux>;
|
||||||
|
|
||||||
CrashReporterLinux();
|
CrashReporterLinux();
|
||||||
virtual ~CrashReporterLinux();
|
virtual ~CrashReporterLinux();
|
||||||
|
|
|
@ -14,7 +14,9 @@
|
||||||
#include "base/strings/string_piece.h"
|
#include "base/strings/string_piece.h"
|
||||||
#include "vendor/crashpad/client/simple_string_dictionary.h"
|
#include "vendor/crashpad/client/simple_string_dictionary.h"
|
||||||
|
|
||||||
|
namespace base {
|
||||||
template <typename T> struct DefaultSingletonTraits;
|
template <typename T> struct DefaultSingletonTraits;
|
||||||
|
}
|
||||||
|
|
||||||
namespace crash_reporter {
|
namespace crash_reporter {
|
||||||
|
|
||||||
|
@ -31,7 +33,7 @@ class CrashReporterMac : public CrashReporter {
|
||||||
void SetUploadParameters() override;
|
void SetUploadParameters() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend struct DefaultSingletonTraits<CrashReporterMac>;
|
friend struct base::DefaultSingletonTraits<CrashReporterMac>;
|
||||||
|
|
||||||
CrashReporterMac();
|
CrashReporterMac();
|
||||||
virtual ~CrashReporterMac();
|
virtual ~CrashReporterMac();
|
||||||
|
|
|
@ -126,7 +126,7 @@ CrashReporterMac::GetUploadedReports(const std::string& path) {
|
||||||
|
|
||||||
// static
|
// static
|
||||||
CrashReporterMac* CrashReporterMac::GetInstance() {
|
CrashReporterMac* CrashReporterMac::GetInstance() {
|
||||||
return Singleton<CrashReporterMac>::get();
|
return base::Singleton<CrashReporterMac>::get();
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
|
|
@ -153,9 +153,9 @@ void CrashReporterWin::InitBreakpad(const std::string& product_name,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
base::string16 pipe_name = ReplaceStringPlaceholders(
|
base::string16 pipe_name = base::ReplaceStringPlaceholders(
|
||||||
kPipeNameFormat, base::UTF8ToUTF16(product_name), NULL);
|
kPipeNameFormat, base::UTF8ToUTF16(product_name), NULL);
|
||||||
base::string16 wait_name = ReplaceStringPlaceholders(
|
base::string16 wait_name = base::ReplaceStringPlaceholders(
|
||||||
kWaitEventFormat, base::UTF8ToUTF16(product_name), NULL);
|
kWaitEventFormat, base::UTF8ToUTF16(product_name), NULL);
|
||||||
|
|
||||||
// Wait until the crash service is started.
|
// Wait until the crash service is started.
|
||||||
|
@ -259,7 +259,7 @@ google_breakpad::CustomClientInfo* CrashReporterWin::GetCustomInfo(
|
||||||
|
|
||||||
// static
|
// static
|
||||||
CrashReporterWin* CrashReporterWin::GetInstance() {
|
CrashReporterWin* CrashReporterWin::GetInstance() {
|
||||||
return Singleton<CrashReporterWin>::get();
|
return base::Singleton<CrashReporterWin>::get();
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
|
|
@ -13,7 +13,9 @@
|
||||||
#include "base/memory/scoped_ptr.h"
|
#include "base/memory/scoped_ptr.h"
|
||||||
#include "vendor/breakpad/src/client/windows/handler/exception_handler.h"
|
#include "vendor/breakpad/src/client/windows/handler/exception_handler.h"
|
||||||
|
|
||||||
|
namespace base {
|
||||||
template <typename T> struct DefaultSingletonTraits;
|
template <typename T> struct DefaultSingletonTraits;
|
||||||
|
}
|
||||||
|
|
||||||
namespace crash_reporter {
|
namespace crash_reporter {
|
||||||
|
|
||||||
|
@ -33,7 +35,7 @@ class CrashReporterWin : public CrashReporter {
|
||||||
int CrashForException(EXCEPTION_POINTERS* info);
|
int CrashForException(EXCEPTION_POINTERS* info);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend struct DefaultSingletonTraits<CrashReporterWin>;
|
friend struct base::DefaultSingletonTraits<CrashReporterWin>;
|
||||||
|
|
||||||
CrashReporterWin();
|
CrashReporterWin();
|
||||||
virtual ~CrashReporterWin();
|
virtual ~CrashReporterWin();
|
||||||
|
|
|
@ -118,7 +118,7 @@ HWND g_top_window = NULL;
|
||||||
bool CreateTopWindow(HINSTANCE instance,
|
bool CreateTopWindow(HINSTANCE instance,
|
||||||
const base::string16& application_name,
|
const base::string16& application_name,
|
||||||
bool visible) {
|
bool visible) {
|
||||||
base::string16 class_name = ReplaceStringPlaceholders(
|
base::string16 class_name = base::ReplaceStringPlaceholders(
|
||||||
kClassNameFormat, application_name, NULL);
|
kClassNameFormat, application_name, NULL);
|
||||||
|
|
||||||
WNDCLASSEXW wcx = {0};
|
WNDCLASSEXW wcx = {0};
|
||||||
|
@ -309,7 +309,7 @@ bool CrashService::Initialize(const base::string16& application_name,
|
||||||
|
|
||||||
// Create or open an event to signal the browser process that the crash
|
// Create or open an event to signal the browser process that the crash
|
||||||
// service is initialized.
|
// service is initialized.
|
||||||
base::string16 wait_name = ReplaceStringPlaceholders(
|
base::string16 wait_name = base::ReplaceStringPlaceholders(
|
||||||
kWaitEventFormat, application_name, NULL);
|
kWaitEventFormat, application_name, NULL);
|
||||||
HANDLE wait_event = ::CreateEventW(NULL, TRUE, TRUE, wait_name.c_str());
|
HANDLE wait_event = ::CreateEventW(NULL, TRUE, TRUE, wait_name.c_str());
|
||||||
::SetEvent(wait_event);
|
::SetEvent(wait_event);
|
||||||
|
@ -524,4 +524,3 @@ PSECURITY_DESCRIPTOR CrashService::GetSecurityDescriptorForLowIntegrity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace breakpad
|
} // namespace breakpad
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ int Main(const wchar_t* cmd) {
|
||||||
VLOG(1) << "Session start. cmdline is [" << cmd << "]";
|
VLOG(1) << "Session start. cmdline is [" << cmd << "]";
|
||||||
|
|
||||||
// Setting the crash reporter.
|
// Setting the crash reporter.
|
||||||
base::string16 pipe_name = ReplaceStringPlaceholders(kPipeNameFormat,
|
base::string16 pipe_name = base::ReplaceStringPlaceholders(kPipeNameFormat,
|
||||||
application_name,
|
application_name,
|
||||||
NULL);
|
NULL);
|
||||||
cmd_line.AppendSwitch("no-window");
|
cmd_line.AppendSwitch("no-window");
|
||||||
|
|
|
@ -45,7 +45,7 @@ template<>
|
||||||
struct Converter<blink::WebInputEvent::Type> {
|
struct Converter<blink::WebInputEvent::Type> {
|
||||||
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
|
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
|
||||||
blink::WebInputEvent::Type* out) {
|
blink::WebInputEvent::Type* out) {
|
||||||
std::string type = base::StringToLowerASCII(V8ToString(val));
|
std::string type = base::ToLowerASCII(V8ToString(val));
|
||||||
if (type == "mousedown")
|
if (type == "mousedown")
|
||||||
*out = blink::WebInputEvent::MouseDown;
|
*out = blink::WebInputEvent::MouseDown;
|
||||||
else if (type == "mouseup")
|
else if (type == "mouseup")
|
||||||
|
@ -82,7 +82,7 @@ template<>
|
||||||
struct Converter<blink::WebMouseEvent::Button> {
|
struct Converter<blink::WebMouseEvent::Button> {
|
||||||
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
|
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
|
||||||
blink::WebMouseEvent::Button* out) {
|
blink::WebMouseEvent::Button* out) {
|
||||||
std::string button = base::StringToLowerASCII(V8ToString(val));
|
std::string button = base::ToLowerASCII(V8ToString(val));
|
||||||
if (button == "left")
|
if (button == "left")
|
||||||
*out = blink::WebMouseEvent::Button::ButtonLeft;
|
*out = blink::WebMouseEvent::Button::ButtonLeft;
|
||||||
else if (button == "middle")
|
else if (button == "middle")
|
||||||
|
@ -97,7 +97,7 @@ template<>
|
||||||
struct Converter<blink::WebInputEvent::Modifiers> {
|
struct Converter<blink::WebInputEvent::Modifiers> {
|
||||||
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
|
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
|
||||||
blink::WebInputEvent::Modifiers* out) {
|
blink::WebInputEvent::Modifiers* out) {
|
||||||
std::string modifier = base::StringToLowerASCII(V8ToString(val));
|
std::string modifier = base::ToLowerASCII(V8ToString(val));
|
||||||
if (modifier == "shift")
|
if (modifier == "shift")
|
||||||
*out = blink::WebInputEvent::ShiftKey;
|
*out = blink::WebInputEvent::ShiftKey;
|
||||||
else if (modifier == "control" || modifier == "ctrl")
|
else if (modifier == "control" || modifier == "ctrl")
|
||||||
|
@ -166,7 +166,7 @@ bool Converter<blink::WebKeyboardEvent>::FromV8(
|
||||||
out->windowsKeyCode = atom::KeyboardCodeFromCharCode(code, &shifted);
|
out->windowsKeyCode = atom::KeyboardCodeFromCharCode(code, &shifted);
|
||||||
else if (dict.Get("keyCode", &identifier))
|
else if (dict.Get("keyCode", &identifier))
|
||||||
out->windowsKeyCode = atom::KeyboardCodeFromKeyIdentifier(
|
out->windowsKeyCode = atom::KeyboardCodeFromKeyIdentifier(
|
||||||
base::StringToLowerASCII(identifier));
|
base::ToLowerASCII(identifier));
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -263,7 +263,7 @@ bool Converter<blink::WebDeviceEmulationParams>::FromV8(
|
||||||
|
|
||||||
std::string screen_position;
|
std::string screen_position;
|
||||||
if (dict.Get("screenPosition", &screen_position)) {
|
if (dict.Get("screenPosition", &screen_position)) {
|
||||||
screen_position = base::StringToLowerASCII(screen_position);
|
screen_position = base::ToLowerASCII(screen_position);
|
||||||
if (screen_position == "mobile")
|
if (screen_position == "mobile")
|
||||||
out->screenPosition = blink::WebDeviceEmulationParams::Mobile;
|
out->screenPosition = blink::WebDeviceEmulationParams::Mobile;
|
||||||
else if (screen_position == "desktop")
|
else if (screen_position == "desktop")
|
||||||
|
|
|
@ -51,7 +51,7 @@ struct V8FunctionInvoker<v8::Local<v8::Value>(ArgTypes...)> {
|
||||||
return v8::Null(isolate);
|
return v8::Null(isolate);
|
||||||
scoped_ptr<blink::WebScopedRunV8Script> script_scope(
|
scoped_ptr<blink::WebScopedRunV8Script> script_scope(
|
||||||
Locker::IsBrowserProcess() ?
|
Locker::IsBrowserProcess() ?
|
||||||
nullptr : new blink::WebScopedRunV8Script(isolate));
|
nullptr : new blink::WebScopedRunV8Script);
|
||||||
v8::Local<v8::Function> holder = function.NewHandle(isolate);
|
v8::Local<v8::Function> holder = function.NewHandle(isolate);
|
||||||
v8::Local<v8::Context> context = holder->CreationContext();
|
v8::Local<v8::Context> context = holder->CreationContext();
|
||||||
v8::Context::Scope context_scope(context);
|
v8::Context::Scope context_scope(context);
|
||||||
|
@ -72,7 +72,7 @@ struct V8FunctionInvoker<void(ArgTypes...)> {
|
||||||
return;
|
return;
|
||||||
scoped_ptr<blink::WebScopedRunV8Script> script_scope(
|
scoped_ptr<blink::WebScopedRunV8Script> script_scope(
|
||||||
Locker::IsBrowserProcess() ?
|
Locker::IsBrowserProcess() ?
|
||||||
nullptr : new blink::WebScopedRunV8Script(isolate));
|
nullptr : new blink::WebScopedRunV8Script);
|
||||||
v8::Local<v8::Function> holder = function.NewHandle(isolate);
|
v8::Local<v8::Function> holder = function.NewHandle(isolate);
|
||||||
v8::Local<v8::Context> context = holder->CreationContext();
|
v8::Local<v8::Context> context = holder->CreationContext();
|
||||||
v8::Context::Scope context_scope(context);
|
v8::Context::Scope context_scope(context);
|
||||||
|
@ -93,7 +93,7 @@ struct V8FunctionInvoker<ReturnType(ArgTypes...)> {
|
||||||
return ret;
|
return ret;
|
||||||
scoped_ptr<blink::WebScopedRunV8Script> script_scope(
|
scoped_ptr<blink::WebScopedRunV8Script> script_scope(
|
||||||
Locker::IsBrowserProcess() ?
|
Locker::IsBrowserProcess() ?
|
||||||
nullptr : new blink::WebScopedRunV8Script(isolate));
|
nullptr : new blink::WebScopedRunV8Script);
|
||||||
v8::Local<v8::Function> holder = function.NewHandle(isolate);
|
v8::Local<v8::Function> holder = function.NewHandle(isolate);
|
||||||
v8::Local<v8::Context> context = holder->CreationContext();
|
v8::Local<v8::Context> context = holder->CreationContext();
|
||||||
v8::Context::Scope context_scope(context);
|
v8::Context::Scope context_scope(context);
|
||||||
|
|
|
@ -35,6 +35,7 @@ REFERENCE_MODULE(atom_browser_app);
|
||||||
REFERENCE_MODULE(atom_browser_auto_updater);
|
REFERENCE_MODULE(atom_browser_auto_updater);
|
||||||
REFERENCE_MODULE(atom_browser_content_tracing);
|
REFERENCE_MODULE(atom_browser_content_tracing);
|
||||||
REFERENCE_MODULE(atom_browser_dialog);
|
REFERENCE_MODULE(atom_browser_dialog);
|
||||||
|
REFERENCE_MODULE(atom_browser_desktop_capturer);
|
||||||
REFERENCE_MODULE(atom_browser_download_item);
|
REFERENCE_MODULE(atom_browser_download_item);
|
||||||
REFERENCE_MODULE(atom_browser_menu);
|
REFERENCE_MODULE(atom_browser_menu);
|
||||||
REFERENCE_MODULE(atom_browser_power_monitor);
|
REFERENCE_MODULE(atom_browser_power_monitor);
|
||||||
|
@ -227,7 +228,7 @@ void NodeBindings::UvRunOnce() {
|
||||||
|
|
||||||
// Perform microtask checkpoint after running JavaScript.
|
// Perform microtask checkpoint after running JavaScript.
|
||||||
scoped_ptr<blink::WebScopedRunV8Script> script_scope(
|
scoped_ptr<blink::WebScopedRunV8Script> script_scope(
|
||||||
is_browser_ ? nullptr : new blink::WebScopedRunV8Script(env->isolate()));
|
is_browser_ ? nullptr : new blink::WebScopedRunV8Script);
|
||||||
|
|
||||||
// Deal with uv events.
|
// Deal with uv events.
|
||||||
int r = uv_run(uv_loop_, UV_RUN_NOWAIT);
|
int r = uv_run(uv_loop_, UV_RUN_NOWAIT);
|
||||||
|
|
|
@ -95,7 +95,6 @@ const char kDirectWrite[] = "directWrite";
|
||||||
const char kExperimentalFeatures[] = "experimentalFeatures";
|
const char kExperimentalFeatures[] = "experimentalFeatures";
|
||||||
const char kExperimentalCanvasFeatures[] = "experimentalCanvasFeatures";
|
const char kExperimentalCanvasFeatures[] = "experimentalCanvasFeatures";
|
||||||
const char kOverlayScrollbars[] = "overlayScrollbars";
|
const char kOverlayScrollbars[] = "overlayScrollbars";
|
||||||
const char kOverlayFullscreenVideo[] = "overlayFullscreenVideo";
|
|
||||||
const char kSharedWorker[] = "sharedWorker";
|
const char kSharedWorker[] = "sharedWorker";
|
||||||
|
|
||||||
} // namespace options
|
} // namespace options
|
||||||
|
@ -139,7 +138,6 @@ const char kGuestInstanceID[] = "guest-instance-id";
|
||||||
const char kExperimentalFeatures[] = "experimental-features";
|
const char kExperimentalFeatures[] = "experimental-features";
|
||||||
const char kExperimentalCanvasFeatures[] = "experimental-canvas-features";
|
const char kExperimentalCanvasFeatures[] = "experimental-canvas-features";
|
||||||
const char kOverlayScrollbars[] = "overlay-scrollbars";
|
const char kOverlayScrollbars[] = "overlay-scrollbars";
|
||||||
const char kOverlayFullscreenVideo[] = "overlay-fullscreen-video";
|
|
||||||
const char kSharedWorker[] = "shared-worker";
|
const char kSharedWorker[] = "shared-worker";
|
||||||
const char kPageVisibility[] = "page-visiblity";
|
const char kPageVisibility[] = "page-visiblity";
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,6 @@ extern const char kGuestInstanceID[];
|
||||||
extern const char kExperimentalFeatures[];
|
extern const char kExperimentalFeatures[];
|
||||||
extern const char kExperimentalCanvasFeatures[];
|
extern const char kExperimentalCanvasFeatures[];
|
||||||
extern const char kOverlayScrollbars[];
|
extern const char kOverlayScrollbars[];
|
||||||
extern const char kOverlayFullscreenVideo[];
|
|
||||||
extern const char kSharedWorker[];
|
extern const char kSharedWorker[];
|
||||||
extern const char kPageVisibility[];
|
extern const char kPageVisibility[];
|
||||||
|
|
||||||
|
@ -79,7 +78,6 @@ extern const char kGuestInstanceID[];
|
||||||
extern const char kExperimentalFeatures[];
|
extern const char kExperimentalFeatures[];
|
||||||
extern const char kExperimentalCanvasFeatures[];
|
extern const char kExperimentalCanvasFeatures[];
|
||||||
extern const char kOverlayScrollbars[];
|
extern const char kOverlayScrollbars[];
|
||||||
extern const char kOverlayFullscreenVideo[];
|
|
||||||
extern const char kSharedWorker[];
|
extern const char kSharedWorker[];
|
||||||
extern const char kPageVisibility[];
|
extern const char kPageVisibility[];
|
||||||
|
|
||||||
|
|
20
atom/renderer/api/lib/desktop-capturer.coffee
Normal file
20
atom/renderer/api/lib/desktop-capturer.coffee
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{ipcRenderer, nativeImage} = require 'electron'
|
||||||
|
|
||||||
|
nextId = 0
|
||||||
|
getNextId = -> ++nextId
|
||||||
|
|
||||||
|
# |options.type| can not be empty and has to include 'window' or 'screen'.
|
||||||
|
isValid = (options) ->
|
||||||
|
return options?.types? and Array.isArray options.types
|
||||||
|
|
||||||
|
exports.getSources = (options, callback) ->
|
||||||
|
return callback new Error('Invalid options') unless isValid options
|
||||||
|
|
||||||
|
captureWindow = 'window' in options.types
|
||||||
|
captureScreen = 'screen' in options.types
|
||||||
|
options.thumbnailSize ?= width: 150, height: 150
|
||||||
|
|
||||||
|
id = getNextId()
|
||||||
|
ipcRenderer.send 'ATOM_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', captureWindow, captureScreen, options.thumbnailSize, id
|
||||||
|
ipcRenderer.once "ATOM_RENDERER_DESKTOP_CAPTURER_RESULT_#{id}", (event, sources) ->
|
||||||
|
callback null, ({id: source.id, name: source.name, thumbnail: nativeImage.createFromDataURL source.thumbnail} for source in sources)
|
|
@ -3,6 +3,9 @@ module.exports = require '../../../../common/api/lib/exports/electron'
|
||||||
|
|
||||||
Object.defineProperties module.exports,
|
Object.defineProperties module.exports,
|
||||||
# Renderer side modules, please sort with alphabet order.
|
# Renderer side modules, please sort with alphabet order.
|
||||||
|
desktopCapturer:
|
||||||
|
enumerable: true
|
||||||
|
get: -> require '../desktop-capturer'
|
||||||
ipcRenderer:
|
ipcRenderer:
|
||||||
enumerable: true
|
enumerable: true
|
||||||
get: -> require '../ipc-renderer'
|
get: -> require '../ipc-renderer'
|
||||||
|
|
|
@ -1,9 +1,17 @@
|
||||||
|
{EventEmitter} = require 'events'
|
||||||
|
|
||||||
binding = process.atomBinding 'ipc'
|
binding = process.atomBinding 'ipc'
|
||||||
v8Util = process.atomBinding 'v8_util'
|
v8Util = process.atomBinding 'v8_util'
|
||||||
|
|
||||||
# Created by init.coffee.
|
# Created by init.coffee.
|
||||||
ipcRenderer = v8Util.getHiddenValue global, 'ipc'
|
ipcRenderer = v8Util.getHiddenValue global, 'ipc'
|
||||||
|
|
||||||
|
# Delay the callback to next tick in case the browser is still in the middle
|
||||||
|
# of sending a message while the callback sends a sync message to browser,
|
||||||
|
# which can fail sometimes.
|
||||||
|
ipcRenderer.emit = (args...) ->
|
||||||
|
setTimeout (-> EventEmitter::emit.call ipcRenderer, args...), 0
|
||||||
|
|
||||||
ipcRenderer.send = (args...) ->
|
ipcRenderer.send = (args...) ->
|
||||||
binding.send 'ipc-message', [args...]
|
binding.send 'ipc-message', [args...]
|
||||||
|
|
||||||
|
|
|
@ -226,8 +226,6 @@ void AtomRendererClient::EnableWebRuntimeFeatures() {
|
||||||
blink::WebRuntimeFeatures::enableExperimentalCanvasFeatures(true);
|
blink::WebRuntimeFeatures::enableExperimentalCanvasFeatures(true);
|
||||||
if (IsSwitchEnabled(command_line, switches::kOverlayScrollbars))
|
if (IsSwitchEnabled(command_line, switches::kOverlayScrollbars))
|
||||||
blink::WebRuntimeFeatures::enableOverlayScrollbars(true);
|
blink::WebRuntimeFeatures::enableOverlayScrollbars(true);
|
||||||
if (IsSwitchEnabled(command_line, switches::kOverlayFullscreenVideo))
|
|
||||||
blink::WebRuntimeFeatures::enableOverlayFullscreenVideo(true);
|
|
||||||
if (IsSwitchEnabled(command_line, switches::kSharedWorker))
|
if (IsSwitchEnabled(command_line, switches::kSharedWorker))
|
||||||
blink::WebRuntimeFeatures::enableSharedWorker(true);
|
blink::WebRuntimeFeatures::enableSharedWorker(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,8 @@ resolveURL = (url) ->
|
||||||
class BrowserWindowProxy
|
class BrowserWindowProxy
|
||||||
constructor: (@guestId) ->
|
constructor: (@guestId) ->
|
||||||
@closed = false
|
@closed = false
|
||||||
ipcRenderer.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSED', (event, guestId) =>
|
ipcRenderer.once "ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSED_#{@guestId}", =>
|
||||||
if guestId is @guestId
|
@closed = true
|
||||||
@closed = true
|
|
||||||
|
|
||||||
close: ->
|
close: ->
|
||||||
ipcRenderer.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSE', @guestId
|
ipcRenderer.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSE', @guestId
|
||||||
|
|
62
chromium_src/chrome/browser/media/desktop_media_list.h
Normal file
62
chromium_src/chrome/browser/media/desktop_media_list.h
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
// Copyright 2013 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef CHROME_BROWSER_MEDIA_DESKTOP_MEDIA_LIST_H_
|
||||||
|
#define CHROME_BROWSER_MEDIA_DESKTOP_MEDIA_LIST_H_
|
||||||
|
|
||||||
|
#include "base/basictypes.h"
|
||||||
|
#include "base/strings/string16.h"
|
||||||
|
#include "base/time/time.h"
|
||||||
|
#include "content/public/browser/desktop_media_id.h"
|
||||||
|
#include "ui/gfx/image/image_skia.h"
|
||||||
|
|
||||||
|
class DesktopMediaListObserver;
|
||||||
|
|
||||||
|
// DesktopMediaList provides the list of desktop media source (screens, windows,
|
||||||
|
// tabs), and their thumbnails, to the desktop media picker dialog. It
|
||||||
|
// transparently updates the list in the background, and notifies the desktop
|
||||||
|
// media picker when something changes.
|
||||||
|
class DesktopMediaList {
|
||||||
|
public:
|
||||||
|
// Struct used to represent each entry in the list.
|
||||||
|
struct Source {
|
||||||
|
// Id of the source.
|
||||||
|
content::DesktopMediaID id;
|
||||||
|
|
||||||
|
// Name of the source that should be shown to the user.
|
||||||
|
base::string16 name;
|
||||||
|
|
||||||
|
// The thumbnail for the source.
|
||||||
|
gfx::ImageSkia thumbnail;
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual ~DesktopMediaList() {}
|
||||||
|
|
||||||
|
// Sets time interval between updates. By default list of sources and their
|
||||||
|
// thumbnail are updated once per second. If called after StartUpdating() then
|
||||||
|
// it will take effect only after the next update.
|
||||||
|
virtual void SetUpdatePeriod(base::TimeDelta period) = 0;
|
||||||
|
|
||||||
|
// Sets size to which the thumbnails should be scaled. If called after
|
||||||
|
// StartUpdating() then some thumbnails may be still scaled to the old size
|
||||||
|
// until they are updated.
|
||||||
|
virtual void SetThumbnailSize(const gfx::Size& thumbnail_size) = 0;
|
||||||
|
|
||||||
|
// Sets ID of the hosting desktop picker dialog. The window with this ID will
|
||||||
|
// be filtered out from the list of sources.
|
||||||
|
virtual void SetViewDialogWindowId(content::DesktopMediaID::Id dialog_id) = 0;
|
||||||
|
|
||||||
|
// Starts updating the model. The model is initially empty, so OnSourceAdded()
|
||||||
|
// notifications will be generated for each existing source as it is
|
||||||
|
// enumerated. After the initial enumeration the model will be refreshed based
|
||||||
|
// on the update period, and notifications generated only for changes in the
|
||||||
|
// model.
|
||||||
|
virtual void StartUpdating(DesktopMediaListObserver* observer) = 0;
|
||||||
|
|
||||||
|
virtual int GetSourceCount() const = 0;
|
||||||
|
virtual const Source& GetSource(int index) const = 0;
|
||||||
|
virtual std::vector<Source> GetSources() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CHROME_BROWSER_MEDIA_DESKTOP_MEDIA_LIST_H_
|
|
@ -0,0 +1,23 @@
|
||||||
|
// Copyright 2013 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef CHROME_BROWSER_MEDIA_DESKTOP_MEDIA_LIST_OBSERVER_H_
|
||||||
|
#define CHROME_BROWSER_MEDIA_DESKTOP_MEDIA_LIST_OBSERVER_H_
|
||||||
|
|
||||||
|
// Interface implemented by the desktop media picker dialog to receive
|
||||||
|
// notifications about changes in DesktopMediaList.
|
||||||
|
class DesktopMediaListObserver {
|
||||||
|
public:
|
||||||
|
virtual void OnSourceAdded(int index) = 0;
|
||||||
|
virtual void OnSourceRemoved(int index) = 0;
|
||||||
|
virtual void OnSourceMoved(int old_index, int new_index) = 0;
|
||||||
|
virtual void OnSourceNameChanged(int index) = 0;
|
||||||
|
virtual void OnSourceThumbnailChanged(int index) = 0;
|
||||||
|
virtual bool OnRefreshFinished() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ~DesktopMediaListObserver() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CHROME_BROWSER_MEDIA_DESKTOP_MEDIA_LIST_OBSERVER_H_
|
375
chromium_src/chrome/browser/media/native_desktop_media_list.cc
Normal file
375
chromium_src/chrome/browser/media/native_desktop_media_list.cc
Normal file
|
@ -0,0 +1,375 @@
|
||||||
|
// Copyright 2013 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "chrome/browser/media/native_desktop_media_list.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "base/hash.h"
|
||||||
|
#include "base/logging.h"
|
||||||
|
#include "base/strings/string_number_conversions.h"
|
||||||
|
#include "base/strings/utf_string_conversions.h"
|
||||||
|
#include "base/threading/sequenced_worker_pool.h"
|
||||||
|
#include "chrome/browser/media/desktop_media_list_observer.h"
|
||||||
|
#include "content/public/browser/browser_thread.h"
|
||||||
|
#include "media/base/video_util.h"
|
||||||
|
#include "third_party/libyuv/include/libyuv/scale_argb.h"
|
||||||
|
#include "third_party/skia/include/core/SkBitmap.h"
|
||||||
|
#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
|
||||||
|
#include "third_party/webrtc/modules/desktop_capture/screen_capturer.h"
|
||||||
|
#include "third_party/webrtc/modules/desktop_capture/window_capturer.h"
|
||||||
|
#include "ui/base/l10n/l10n_util.h"
|
||||||
|
#include "ui/gfx/skia_util.h"
|
||||||
|
|
||||||
|
using content::BrowserThread;
|
||||||
|
using content::DesktopMediaID;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Update the list every second.
|
||||||
|
const int kDefaultUpdatePeriod = 1000;
|
||||||
|
|
||||||
|
// Returns a hash of a DesktopFrame content to detect when image for a desktop
|
||||||
|
// media source has changed.
|
||||||
|
uint32 GetFrameHash(webrtc::DesktopFrame* frame) {
|
||||||
|
int data_size = frame->stride() * frame->size().height();
|
||||||
|
return base::SuperFastHash(reinterpret_cast<char*>(frame->data()), data_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx::ImageSkia ScaleDesktopFrame(scoped_ptr<webrtc::DesktopFrame> frame,
|
||||||
|
gfx::Size size) {
|
||||||
|
gfx::Rect scaled_rect = media::ComputeLetterboxRegion(
|
||||||
|
gfx::Rect(0, 0, size.width(), size.height()),
|
||||||
|
gfx::Size(frame->size().width(), frame->size().height()));
|
||||||
|
|
||||||
|
SkBitmap result;
|
||||||
|
result.allocN32Pixels(scaled_rect.width(), scaled_rect.height(), true);
|
||||||
|
result.lockPixels();
|
||||||
|
|
||||||
|
uint8* pixels_data = reinterpret_cast<uint8*>(result.getPixels());
|
||||||
|
libyuv::ARGBScale(frame->data(), frame->stride(),
|
||||||
|
frame->size().width(), frame->size().height(),
|
||||||
|
pixels_data, result.rowBytes(),
|
||||||
|
scaled_rect.width(), scaled_rect.height(),
|
||||||
|
libyuv::kFilterBilinear);
|
||||||
|
|
||||||
|
// Set alpha channel values to 255 for all pixels.
|
||||||
|
// TODO(sergeyu): Fix screen/window capturers to capture alpha channel and
|
||||||
|
// remove this code. Currently screen/window capturers (at least some
|
||||||
|
// implementations) only capture R, G and B channels and set Alpha to 0.
|
||||||
|
// crbug.com/264424
|
||||||
|
for (int y = 0; y < result.height(); ++y) {
|
||||||
|
for (int x = 0; x < result.width(); ++x) {
|
||||||
|
pixels_data[result.rowBytes() * y + x * result.bytesPerPixel() + 3] =
|
||||||
|
0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.unlockPixels();
|
||||||
|
|
||||||
|
return gfx::ImageSkia::CreateFrom1xBitmap(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
NativeDesktopMediaList::SourceDescription::SourceDescription(
|
||||||
|
DesktopMediaID id,
|
||||||
|
const base::string16& name)
|
||||||
|
: id(id),
|
||||||
|
name(name) {
|
||||||
|
}
|
||||||
|
|
||||||
|
class NativeDesktopMediaList::Worker
|
||||||
|
: public webrtc::DesktopCapturer::Callback {
|
||||||
|
public:
|
||||||
|
Worker(base::WeakPtr<NativeDesktopMediaList> media_list,
|
||||||
|
scoped_ptr<webrtc::ScreenCapturer> screen_capturer,
|
||||||
|
scoped_ptr<webrtc::WindowCapturer> window_capturer);
|
||||||
|
~Worker() override;
|
||||||
|
|
||||||
|
void Refresh(const gfx::Size& thumbnail_size,
|
||||||
|
content::DesktopMediaID::Id view_dialog_id);
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef std::map<DesktopMediaID, uint32> ImageHashesMap;
|
||||||
|
|
||||||
|
// webrtc::DesktopCapturer::Callback interface.
|
||||||
|
webrtc::SharedMemory* CreateSharedMemory(size_t size) override;
|
||||||
|
void OnCaptureCompleted(webrtc::DesktopFrame* frame) override;
|
||||||
|
|
||||||
|
base::WeakPtr<NativeDesktopMediaList> media_list_;
|
||||||
|
|
||||||
|
scoped_ptr<webrtc::ScreenCapturer> screen_capturer_;
|
||||||
|
scoped_ptr<webrtc::WindowCapturer> window_capturer_;
|
||||||
|
|
||||||
|
scoped_ptr<webrtc::DesktopFrame> current_frame_;
|
||||||
|
|
||||||
|
ImageHashesMap image_hashes_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(Worker);
|
||||||
|
};
|
||||||
|
|
||||||
|
NativeDesktopMediaList::Worker::Worker(
|
||||||
|
base::WeakPtr<NativeDesktopMediaList> media_list,
|
||||||
|
scoped_ptr<webrtc::ScreenCapturer> screen_capturer,
|
||||||
|
scoped_ptr<webrtc::WindowCapturer> window_capturer)
|
||||||
|
: media_list_(media_list),
|
||||||
|
screen_capturer_(screen_capturer.Pass()),
|
||||||
|
window_capturer_(window_capturer.Pass()) {
|
||||||
|
if (screen_capturer_)
|
||||||
|
screen_capturer_->Start(this);
|
||||||
|
if (window_capturer_)
|
||||||
|
window_capturer_->Start(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NativeDesktopMediaList::Worker::~Worker() {}
|
||||||
|
|
||||||
|
void NativeDesktopMediaList::Worker::Refresh(
|
||||||
|
const gfx::Size& thumbnail_size,
|
||||||
|
content::DesktopMediaID::Id view_dialog_id) {
|
||||||
|
std::vector<SourceDescription> sources;
|
||||||
|
|
||||||
|
if (screen_capturer_) {
|
||||||
|
webrtc::ScreenCapturer::ScreenList screens;
|
||||||
|
if (screen_capturer_->GetScreenList(&screens)) {
|
||||||
|
bool mutiple_screens = screens.size() > 1;
|
||||||
|
base::string16 title;
|
||||||
|
for (size_t i = 0; i < screens.size(); ++i) {
|
||||||
|
if (mutiple_screens) {
|
||||||
|
title = base::UTF8ToUTF16("Screen " + base::IntToString(i+1));
|
||||||
|
} else {
|
||||||
|
title = base::UTF8ToUTF16("Entire screen");
|
||||||
|
}
|
||||||
|
sources.push_back(SourceDescription(DesktopMediaID(
|
||||||
|
DesktopMediaID::TYPE_SCREEN, screens[i].id), title));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window_capturer_) {
|
||||||
|
webrtc::WindowCapturer::WindowList windows;
|
||||||
|
if (window_capturer_->GetWindowList(&windows)) {
|
||||||
|
for (webrtc::WindowCapturer::WindowList::iterator it = windows.begin();
|
||||||
|
it != windows.end(); ++it) {
|
||||||
|
// Skip the picker dialog window.
|
||||||
|
if (it->id != view_dialog_id) {
|
||||||
|
sources.push_back(SourceDescription(
|
||||||
|
DesktopMediaID(DesktopMediaID::TYPE_WINDOW, it->id),
|
||||||
|
base::UTF8ToUTF16(it->title)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Update list of windows before updating thumbnails.
|
||||||
|
BrowserThread::PostTask(
|
||||||
|
BrowserThread::UI, FROM_HERE,
|
||||||
|
base::Bind(&NativeDesktopMediaList::OnSourcesList,
|
||||||
|
media_list_, sources));
|
||||||
|
|
||||||
|
ImageHashesMap new_image_hashes;
|
||||||
|
|
||||||
|
// Get a thumbnail for each source.
|
||||||
|
for (size_t i = 0; i < sources.size(); ++i) {
|
||||||
|
SourceDescription& source = sources[i];
|
||||||
|
switch (source.id.type) {
|
||||||
|
case DesktopMediaID::TYPE_SCREEN:
|
||||||
|
if (!screen_capturer_->SelectScreen(source.id.id))
|
||||||
|
continue;
|
||||||
|
screen_capturer_->Capture(webrtc::DesktopRegion());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DesktopMediaID::TYPE_WINDOW:
|
||||||
|
if (!window_capturer_->SelectWindow(source.id.id))
|
||||||
|
continue;
|
||||||
|
window_capturer_->Capture(webrtc::DesktopRegion());
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
NOTREACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expect that DesktopCapturer to always captures frames synchronously.
|
||||||
|
// |current_frame_| may be NULL if capture failed (e.g. because window has
|
||||||
|
// been closed).
|
||||||
|
if (current_frame_) {
|
||||||
|
uint32 frame_hash = GetFrameHash(current_frame_.get());
|
||||||
|
new_image_hashes[source.id] = frame_hash;
|
||||||
|
|
||||||
|
// Scale the image only if it has changed.
|
||||||
|
ImageHashesMap::iterator it = image_hashes_.find(source.id);
|
||||||
|
if (it == image_hashes_.end() || it->second != frame_hash) {
|
||||||
|
gfx::ImageSkia thumbnail =
|
||||||
|
ScaleDesktopFrame(current_frame_.Pass(), thumbnail_size);
|
||||||
|
BrowserThread::PostTask(
|
||||||
|
BrowserThread::UI, FROM_HERE,
|
||||||
|
base::Bind(&NativeDesktopMediaList::OnSourceThumbnail,
|
||||||
|
media_list_, i, thumbnail));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
image_hashes_.swap(new_image_hashes);
|
||||||
|
|
||||||
|
BrowserThread::PostTask(
|
||||||
|
BrowserThread::UI, FROM_HERE,
|
||||||
|
base::Bind(&NativeDesktopMediaList::OnRefreshFinished, media_list_));
|
||||||
|
}
|
||||||
|
|
||||||
|
webrtc::SharedMemory* NativeDesktopMediaList::Worker::CreateSharedMemory(
|
||||||
|
size_t size) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeDesktopMediaList::Worker::OnCaptureCompleted(
|
||||||
|
webrtc::DesktopFrame* frame) {
|
||||||
|
current_frame_.reset(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
NativeDesktopMediaList::NativeDesktopMediaList(
|
||||||
|
scoped_ptr<webrtc::ScreenCapturer> screen_capturer,
|
||||||
|
scoped_ptr<webrtc::WindowCapturer> window_capturer)
|
||||||
|
: screen_capturer_(screen_capturer.Pass()),
|
||||||
|
window_capturer_(window_capturer.Pass()),
|
||||||
|
update_period_(base::TimeDelta::FromMilliseconds(kDefaultUpdatePeriod)),
|
||||||
|
thumbnail_size_(100, 100),
|
||||||
|
view_dialog_id_(-1),
|
||||||
|
observer_(NULL),
|
||||||
|
weak_factory_(this) {
|
||||||
|
base::SequencedWorkerPool* worker_pool = BrowserThread::GetBlockingPool();
|
||||||
|
capture_task_runner_ = worker_pool->GetSequencedTaskRunner(
|
||||||
|
worker_pool->GetSequenceToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
NativeDesktopMediaList::~NativeDesktopMediaList() {
|
||||||
|
capture_task_runner_->DeleteSoon(FROM_HERE, worker_.release());
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeDesktopMediaList::SetUpdatePeriod(base::TimeDelta period) {
|
||||||
|
DCHECK(!observer_);
|
||||||
|
update_period_ = period;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeDesktopMediaList::SetThumbnailSize(
|
||||||
|
const gfx::Size& thumbnail_size) {
|
||||||
|
thumbnail_size_ = thumbnail_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeDesktopMediaList::SetViewDialogWindowId(
|
||||||
|
content::DesktopMediaID::Id dialog_id) {
|
||||||
|
view_dialog_id_ = dialog_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeDesktopMediaList::StartUpdating(DesktopMediaListObserver* observer) {
|
||||||
|
DCHECK(!observer_);
|
||||||
|
DCHECK(screen_capturer_ || window_capturer_);
|
||||||
|
|
||||||
|
observer_ = observer;
|
||||||
|
|
||||||
|
worker_.reset(new Worker(weak_factory_.GetWeakPtr(),
|
||||||
|
screen_capturer_.Pass(), window_capturer_.Pass()));
|
||||||
|
Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
int NativeDesktopMediaList::GetSourceCount() const {
|
||||||
|
return sources_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
const DesktopMediaList::Source& NativeDesktopMediaList::GetSource(
|
||||||
|
int index) const {
|
||||||
|
return sources_[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<DesktopMediaList::Source> NativeDesktopMediaList::GetSources() const {
|
||||||
|
return sources_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeDesktopMediaList::Refresh() {
|
||||||
|
capture_task_runner_->PostTask(
|
||||||
|
FROM_HERE, base::Bind(&Worker::Refresh, base::Unretained(worker_.get()),
|
||||||
|
thumbnail_size_, view_dialog_id_));
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeDesktopMediaList::OnSourcesList(
|
||||||
|
const std::vector<SourceDescription>& new_sources) {
|
||||||
|
typedef std::set<content::DesktopMediaID> SourceSet;
|
||||||
|
SourceSet new_source_set;
|
||||||
|
for (size_t i = 0; i < new_sources.size(); ++i) {
|
||||||
|
new_source_set.insert(new_sources[i].id);
|
||||||
|
}
|
||||||
|
// Iterate through the old sources to find the removed sources.
|
||||||
|
for (size_t i = 0; i < sources_.size(); ++i) {
|
||||||
|
if (new_source_set.find(sources_[i].id) == new_source_set.end()) {
|
||||||
|
observer_->OnSourceRemoved(i);
|
||||||
|
sources_.erase(sources_.begin() + i);
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Iterate through the new sources to find the added sources.
|
||||||
|
if (new_sources.size() > sources_.size()) {
|
||||||
|
SourceSet old_source_set;
|
||||||
|
for (size_t i = 0; i < sources_.size(); ++i) {
|
||||||
|
old_source_set.insert(sources_[i].id);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < new_sources.size(); ++i) {
|
||||||
|
if (old_source_set.find(new_sources[i].id) == old_source_set.end()) {
|
||||||
|
sources_.insert(sources_.begin() + i, Source());
|
||||||
|
sources_[i].id = new_sources[i].id;
|
||||||
|
sources_[i].name = new_sources[i].name;
|
||||||
|
observer_->OnSourceAdded(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DCHECK_EQ(new_sources.size(), sources_.size());
|
||||||
|
|
||||||
|
// Find the moved/changed sources.
|
||||||
|
size_t pos = 0;
|
||||||
|
while (pos < sources_.size()) {
|
||||||
|
if (!(sources_[pos].id == new_sources[pos].id)) {
|
||||||
|
// Find the source that should be moved to |pos|, starting from |pos + 1|
|
||||||
|
// of |sources_|, because entries before |pos| should have been sorted.
|
||||||
|
size_t old_pos = pos + 1;
|
||||||
|
for (; old_pos < sources_.size(); ++old_pos) {
|
||||||
|
if (sources_[old_pos].id == new_sources[pos].id)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
DCHECK(sources_[old_pos].id == new_sources[pos].id);
|
||||||
|
|
||||||
|
// Move the source from |old_pos| to |pos|.
|
||||||
|
Source temp = sources_[old_pos];
|
||||||
|
sources_.erase(sources_.begin() + old_pos);
|
||||||
|
sources_.insert(sources_.begin() + pos, temp);
|
||||||
|
|
||||||
|
observer_->OnSourceMoved(old_pos, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sources_[pos].name != new_sources[pos].name) {
|
||||||
|
sources_[pos].name = new_sources[pos].name;
|
||||||
|
observer_->OnSourceNameChanged(pos);
|
||||||
|
}
|
||||||
|
++pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeDesktopMediaList::OnSourceThumbnail(
|
||||||
|
int index,
|
||||||
|
const gfx::ImageSkia& image) {
|
||||||
|
DCHECK_LT(index, static_cast<int>(sources_.size()));
|
||||||
|
sources_[index].thumbnail = image;
|
||||||
|
observer_->OnSourceThumbnailChanged(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeDesktopMediaList::OnRefreshFinished() {
|
||||||
|
// Give a chance to the observer to stop the refresh work.
|
||||||
|
bool is_continue = observer_->OnRefreshFinished();
|
||||||
|
if (is_continue) {
|
||||||
|
BrowserThread::PostDelayedTask(
|
||||||
|
BrowserThread::UI, FROM_HERE,
|
||||||
|
base::Bind(&NativeDesktopMediaList::Refresh,
|
||||||
|
weak_factory_.GetWeakPtr()),
|
||||||
|
update_period_);
|
||||||
|
}
|
||||||
|
}
|
101
chromium_src/chrome/browser/media/native_desktop_media_list.h
Normal file
101
chromium_src/chrome/browser/media/native_desktop_media_list.h
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
// Copyright 2013 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef CHROME_BROWSER_MEDIA_NATIVE_DESKTOP_MEDIA_LIST_H_
|
||||||
|
#define CHROME_BROWSER_MEDIA_NATIVE_DESKTOP_MEDIA_LIST_H_
|
||||||
|
|
||||||
|
#include "base/basictypes.h"
|
||||||
|
#include "base/memory/scoped_ptr.h"
|
||||||
|
#include "base/memory/weak_ptr.h"
|
||||||
|
#include "base/sequenced_task_runner.h"
|
||||||
|
#include "chrome/browser/media/desktop_media_list.h"
|
||||||
|
#include "content/public/browser/desktop_media_id.h"
|
||||||
|
#include "ui/gfx/image/image_skia.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
class ScreenCapturer;
|
||||||
|
class WindowCapturer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implementation of DesktopMediaList that shows native screens and
|
||||||
|
// native windows.
|
||||||
|
class NativeDesktopMediaList : public DesktopMediaList {
|
||||||
|
public:
|
||||||
|
// Caller may pass NULL for either of the arguments in case when only some
|
||||||
|
// types of sources the model should be populated with (e.g. it will only
|
||||||
|
// contain windows, if |screen_capturer| is NULL).
|
||||||
|
NativeDesktopMediaList(
|
||||||
|
scoped_ptr<webrtc::ScreenCapturer> screen_capturer,
|
||||||
|
scoped_ptr<webrtc::WindowCapturer> window_capturer);
|
||||||
|
~NativeDesktopMediaList() override;
|
||||||
|
|
||||||
|
// DesktopMediaList interface.
|
||||||
|
void SetUpdatePeriod(base::TimeDelta period) override;
|
||||||
|
void SetThumbnailSize(const gfx::Size& thumbnail_size) override;
|
||||||
|
void StartUpdating(DesktopMediaListObserver* observer) override;
|
||||||
|
int GetSourceCount() const override;
|
||||||
|
const Source& GetSource(int index) const override;
|
||||||
|
std::vector<Source> GetSources() const override;
|
||||||
|
void SetViewDialogWindowId(content::DesktopMediaID::Id dialog_id) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
class Worker;
|
||||||
|
friend class Worker;
|
||||||
|
|
||||||
|
// Struct used to represent sources list the model gets from the Worker.
|
||||||
|
struct SourceDescription {
|
||||||
|
SourceDescription(content::DesktopMediaID id, const base::string16& name);
|
||||||
|
|
||||||
|
content::DesktopMediaID id;
|
||||||
|
base::string16 name;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Order comparator for sources. Used to sort list of sources.
|
||||||
|
static bool CompareSources(const SourceDescription& a,
|
||||||
|
const SourceDescription& b);
|
||||||
|
|
||||||
|
// Post a task for the |worker_| to update list of windows and get thumbnails.
|
||||||
|
void Refresh();
|
||||||
|
|
||||||
|
// Called by |worker_| to refresh the model. First it posts tasks for
|
||||||
|
// OnSourcesList() with the fresh list of sources, then follows with
|
||||||
|
// OnSourceThumbnail() for each changed thumbnail and then calls
|
||||||
|
// OnRefreshFinished() at the end.
|
||||||
|
void OnSourcesList(const std::vector<SourceDescription>& sources);
|
||||||
|
void OnSourceThumbnail(int index, const gfx::ImageSkia& thumbnail);
|
||||||
|
void OnRefreshFinished();
|
||||||
|
|
||||||
|
// Capturers specified in SetCapturers() and passed to the |worker_| later.
|
||||||
|
scoped_ptr<webrtc::ScreenCapturer> screen_capturer_;
|
||||||
|
scoped_ptr<webrtc::WindowCapturer> window_capturer_;
|
||||||
|
|
||||||
|
// Time interval between mode updates.
|
||||||
|
base::TimeDelta update_period_;
|
||||||
|
|
||||||
|
// Size of thumbnails generated by the model.
|
||||||
|
gfx::Size thumbnail_size_;
|
||||||
|
|
||||||
|
// ID of the hosting dialog.
|
||||||
|
content::DesktopMediaID::Id view_dialog_id_;
|
||||||
|
|
||||||
|
// The observer passed to StartUpdating().
|
||||||
|
DesktopMediaListObserver* observer_;
|
||||||
|
|
||||||
|
// Task runner used for the |worker_|.
|
||||||
|
scoped_refptr<base::SequencedTaskRunner> capture_task_runner_;
|
||||||
|
|
||||||
|
// An object that does all the work of getting list of sources on a background
|
||||||
|
// thread (see |capture_task_runner_|). Destroyed on |capture_task_runner_|
|
||||||
|
// after the model is destroyed.
|
||||||
|
scoped_ptr<Worker> worker_;
|
||||||
|
|
||||||
|
// Current list of sources.
|
||||||
|
std::vector<Source> sources_;
|
||||||
|
|
||||||
|
base::WeakPtrFactory<NativeDesktopMediaList> weak_factory_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(NativeDesktopMediaList);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CHROME_BROWSER_MEDIA_NATIVE_DESKTOP_MEDIA_LIST_H_
|
|
@ -410,7 +410,7 @@ bool PrintViewManagerBase::RunInnerMessageLoop() {
|
||||||
// be CPU bound, the page overly complex/large or the system just
|
// be CPU bound, the page overly complex/large or the system just
|
||||||
// memory-bound.
|
// memory-bound.
|
||||||
static const int kPrinterSettingsTimeout = 60000;
|
static const int kPrinterSettingsTimeout = 60000;
|
||||||
base::OneShotTimer<base::MessageLoop> quit_timer;
|
base::OneShotTimer quit_timer;
|
||||||
quit_timer.Start(FROM_HERE,
|
quit_timer.Start(FROM_HERE,
|
||||||
TimeDelta::FromMilliseconds(kPrinterSettingsTimeout),
|
TimeDelta::FromMilliseconds(kPrinterSettingsTimeout),
|
||||||
base::MessageLoop::current(), &base::MessageLoop::Quit);
|
base::MessageLoop::current(), &base::MessageLoop::Quit);
|
||||||
|
|
|
@ -503,7 +503,7 @@ class ProcessSingleton::LinuxWatcher
|
||||||
// reads.
|
// reads.
|
||||||
size_t bytes_read_;
|
size_t bytes_read_;
|
||||||
|
|
||||||
base::OneShotTimer<SocketReader> timer_;
|
base::OneShotTimer timer_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(SocketReader);
|
DISALLOW_COPY_AND_ASSIGN(SocketReader);
|
||||||
};
|
};
|
||||||
|
|
|
@ -111,7 +111,7 @@ TtsController* TtsController::GetInstance() {
|
||||||
|
|
||||||
// static
|
// static
|
||||||
TtsControllerImpl* TtsControllerImpl::GetInstance() {
|
TtsControllerImpl* TtsControllerImpl::GetInstance() {
|
||||||
return Singleton<TtsControllerImpl>::get();
|
return base::Singleton<TtsControllerImpl>::get();
|
||||||
}
|
}
|
||||||
|
|
||||||
TtsControllerImpl::TtsControllerImpl()
|
TtsControllerImpl::TtsControllerImpl()
|
||||||
|
|
|
@ -77,7 +77,7 @@ class TtsControllerImpl : public TtsController {
|
||||||
int GetMatchingVoice(const Utterance* utterance,
|
int GetMatchingVoice(const Utterance* utterance,
|
||||||
std::vector<VoiceData>& voices);
|
std::vector<VoiceData>& voices);
|
||||||
|
|
||||||
friend struct DefaultSingletonTraits<TtsControllerImpl>;
|
friend struct base::DefaultSingletonTraits<TtsControllerImpl>;
|
||||||
|
|
||||||
// The current utterance being spoken.
|
// The current utterance being spoken.
|
||||||
Utterance* current_utterance_;
|
Utterance* current_utterance_;
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "base/synchronization/lock.h"
|
#include "base/synchronization/lock.h"
|
||||||
#include "chrome/browser/speech/tts_platform.h"
|
#include "chrome/browser/speech/tts_platform.h"
|
||||||
#include "content/public/browser/browser_thread.h"
|
#include "content/public/browser/browser_thread.h"
|
||||||
|
#include "content/public/common/content_switches.h"
|
||||||
|
|
||||||
#include "library_loaders/libspeechd.h"
|
#include "library_loaders/libspeechd.h"
|
||||||
|
|
||||||
|
@ -32,18 +33,17 @@ struct SPDChromeVoice {
|
||||||
|
|
||||||
class TtsPlatformImplLinux : public TtsPlatformImpl {
|
class TtsPlatformImplLinux : public TtsPlatformImpl {
|
||||||
public:
|
public:
|
||||||
virtual bool PlatformImplAvailable() override;
|
bool PlatformImplAvailable() override;
|
||||||
virtual bool Speak(
|
bool Speak(int utterance_id,
|
||||||
int utterance_id,
|
const std::string& utterance,
|
||||||
const std::string& utterance,
|
const std::string& lang,
|
||||||
const std::string& lang,
|
const VoiceData& voice,
|
||||||
const VoiceData& voice,
|
const UtteranceContinuousParameters& params) override;
|
||||||
const UtteranceContinuousParameters& params) override;
|
bool StopSpeaking() override;
|
||||||
virtual bool StopSpeaking() override;
|
void Pause() override;
|
||||||
virtual void Pause() override;
|
void Resume() override;
|
||||||
virtual void Resume() override;
|
bool IsSpeaking() override;
|
||||||
virtual bool IsSpeaking() override;
|
void GetVoices(std::vector<VoiceData>* out_voices) override;
|
||||||
virtual void GetVoices(std::vector<VoiceData>* out_voices) override;
|
|
||||||
|
|
||||||
void OnSpeechEvent(SPDNotificationType type);
|
void OnSpeechEvent(SPDNotificationType type);
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ class TtsPlatformImplLinux : public TtsPlatformImpl {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TtsPlatformImplLinux();
|
TtsPlatformImplLinux();
|
||||||
virtual ~TtsPlatformImplLinux();
|
~TtsPlatformImplLinux() override;
|
||||||
|
|
||||||
// Initiate the connection with the speech dispatcher.
|
// Initiate the connection with the speech dispatcher.
|
||||||
void Initialize();
|
void Initialize();
|
||||||
|
@ -83,7 +83,7 @@ class TtsPlatformImplLinux : public TtsPlatformImpl {
|
||||||
// uniquely identify a voice across all available modules.
|
// uniquely identify a voice across all available modules.
|
||||||
scoped_ptr<std::map<std::string, SPDChromeVoice> > all_native_voices_;
|
scoped_ptr<std::map<std::string, SPDChromeVoice> > all_native_voices_;
|
||||||
|
|
||||||
friend struct DefaultSingletonTraits<TtsPlatformImplLinux>;
|
friend struct base::DefaultSingletonTraits<TtsPlatformImplLinux>;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(TtsPlatformImplLinux);
|
DISALLOW_COPY_AND_ASSIGN(TtsPlatformImplLinux);
|
||||||
};
|
};
|
||||||
|
@ -94,6 +94,11 @@ SPDNotificationType TtsPlatformImplLinux::current_notification_ =
|
||||||
|
|
||||||
TtsPlatformImplLinux::TtsPlatformImplLinux()
|
TtsPlatformImplLinux::TtsPlatformImplLinux()
|
||||||
: utterance_id_(0) {
|
: utterance_id_(0) {
|
||||||
|
const base::CommandLine& command_line =
|
||||||
|
*base::CommandLine::ForCurrentProcess();
|
||||||
|
if (!command_line.HasSwitch(switches::kEnableSpeechDispatcher))
|
||||||
|
return;
|
||||||
|
|
||||||
BrowserThread::PostTask(BrowserThread::FILE,
|
BrowserThread::PostTask(BrowserThread::FILE,
|
||||||
FROM_HERE,
|
FROM_HERE,
|
||||||
base::Bind(&TtsPlatformImplLinux::Initialize,
|
base::Bind(&TtsPlatformImplLinux::Initialize,
|
||||||
|
@ -111,7 +116,7 @@ void TtsPlatformImplLinux::Initialize() {
|
||||||
// http://crbug.com/317360
|
// http://crbug.com/317360
|
||||||
ANNOTATE_SCOPED_MEMORY_LEAK;
|
ANNOTATE_SCOPED_MEMORY_LEAK;
|
||||||
conn_ = libspeechd_loader_.spd_open(
|
conn_ = libspeechd_loader_.spd_open(
|
||||||
"chrome", "extension_api", NULL, SPD_MODE_SINGLE);
|
"chrome", "extension_api", NULL, SPD_MODE_THREADED);
|
||||||
}
|
}
|
||||||
if (!conn_)
|
if (!conn_)
|
||||||
return;
|
return;
|
||||||
|
@ -146,7 +151,7 @@ void TtsPlatformImplLinux::Reset() {
|
||||||
if (conn_)
|
if (conn_)
|
||||||
libspeechd_loader_.spd_close(conn_);
|
libspeechd_loader_.spd_close(conn_);
|
||||||
conn_ = libspeechd_loader_.spd_open(
|
conn_ = libspeechd_loader_.spd_open(
|
||||||
"chrome", "extension_api", NULL, SPD_MODE_SINGLE);
|
"chrome", "extension_api", NULL, SPD_MODE_THREADED);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TtsPlatformImplLinux::PlatformImplAvailable() {
|
bool TtsPlatformImplLinux::PlatformImplAvailable() {
|
||||||
|
@ -187,6 +192,10 @@ bool TtsPlatformImplLinux::Speak(
|
||||||
libspeechd_loader_.spd_set_voice_rate(conn_, 100 * log10(rate) / log10(3));
|
libspeechd_loader_.spd_set_voice_rate(conn_, 100 * log10(rate) / log10(3));
|
||||||
libspeechd_loader_.spd_set_voice_pitch(conn_, 100 * log10(pitch) / log10(3));
|
libspeechd_loader_.spd_set_voice_pitch(conn_, 100 * log10(pitch) / log10(3));
|
||||||
|
|
||||||
|
// Support languages other than the default
|
||||||
|
if (!lang.empty())
|
||||||
|
libspeechd_loader_.spd_set_language(conn_, lang.c_str());
|
||||||
|
|
||||||
utterance_ = utterance;
|
utterance_ = utterance;
|
||||||
utterance_id_ = utterance_id;
|
utterance_id_ = utterance_id;
|
||||||
|
|
||||||
|
@ -337,8 +346,9 @@ void TtsPlatformImplLinux::IndexMarkCallback(size_t msg_id,
|
||||||
|
|
||||||
// static
|
// static
|
||||||
TtsPlatformImplLinux* TtsPlatformImplLinux::GetInstance() {
|
TtsPlatformImplLinux* TtsPlatformImplLinux::GetInstance() {
|
||||||
return Singleton<TtsPlatformImplLinux,
|
return base::Singleton<
|
||||||
LeakySingletonTraits<TtsPlatformImplLinux> >::get();
|
TtsPlatformImplLinux,
|
||||||
|
base::LeakySingletonTraits<TtsPlatformImplLinux>>::get();
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
|
|
@ -91,7 +91,7 @@ class TtsPlatformImplMac : public TtsPlatformImpl {
|
||||||
int last_char_index_;
|
int last_char_index_;
|
||||||
bool paused_;
|
bool paused_;
|
||||||
|
|
||||||
friend struct DefaultSingletonTraits<TtsPlatformImplMac>;
|
friend struct base::DefaultSingletonTraits<TtsPlatformImplMac>;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(TtsPlatformImplMac);
|
DISALLOW_COPY_AND_ASSIGN(TtsPlatformImplMac);
|
||||||
};
|
};
|
||||||
|
@ -291,7 +291,7 @@ TtsPlatformImplMac::~TtsPlatformImplMac() {
|
||||||
|
|
||||||
// static
|
// static
|
||||||
TtsPlatformImplMac* TtsPlatformImplMac::GetInstance() {
|
TtsPlatformImplMac* TtsPlatformImplMac::GetInstance() {
|
||||||
return Singleton<TtsPlatformImplMac>::get();
|
return base::Singleton<TtsPlatformImplMac>::get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@implementation ChromeTtsDelegate
|
@implementation ChromeTtsDelegate
|
||||||
|
|
|
@ -15,26 +15,26 @@
|
||||||
|
|
||||||
class TtsPlatformImplWin : public TtsPlatformImpl {
|
class TtsPlatformImplWin : public TtsPlatformImpl {
|
||||||
public:
|
public:
|
||||||
virtual bool PlatformImplAvailable() {
|
bool PlatformImplAvailable() override {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool Speak(
|
bool Speak(
|
||||||
int utterance_id,
|
int utterance_id,
|
||||||
const std::string& utterance,
|
const std::string& utterance,
|
||||||
const std::string& lang,
|
const std::string& lang,
|
||||||
const VoiceData& voice,
|
const VoiceData& voice,
|
||||||
const UtteranceContinuousParameters& params);
|
const UtteranceContinuousParameters& params) override;
|
||||||
|
|
||||||
virtual bool StopSpeaking();
|
bool StopSpeaking() override;
|
||||||
|
|
||||||
virtual void Pause();
|
void Pause() override;
|
||||||
|
|
||||||
virtual void Resume();
|
void Resume() override;
|
||||||
|
|
||||||
virtual bool IsSpeaking();
|
bool IsSpeaking() override;
|
||||||
|
|
||||||
virtual void GetVoices(std::vector<VoiceData>* out_voices) override;
|
void GetVoices(std::vector<VoiceData>* out_voices) override;
|
||||||
|
|
||||||
// Get the single instance of this class.
|
// Get the single instance of this class.
|
||||||
static TtsPlatformImplWin* GetInstance();
|
static TtsPlatformImplWin* GetInstance();
|
||||||
|
@ -43,7 +43,7 @@ class TtsPlatformImplWin : public TtsPlatformImpl {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TtsPlatformImplWin();
|
TtsPlatformImplWin();
|
||||||
virtual ~TtsPlatformImplWin() {}
|
~TtsPlatformImplWin() override {}
|
||||||
|
|
||||||
void OnSpeechEvent();
|
void OnSpeechEvent();
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ class TtsPlatformImplWin : public TtsPlatformImpl {
|
||||||
int char_position_;
|
int char_position_;
|
||||||
bool paused_;
|
bool paused_;
|
||||||
|
|
||||||
friend struct DefaultSingletonTraits<TtsPlatformImplWin>;
|
friend struct base::DefaultSingletonTraits<TtsPlatformImplWin>;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(TtsPlatformImplWin);
|
DISALLOW_COPY_AND_ASSIGN(TtsPlatformImplWin);
|
||||||
};
|
};
|
||||||
|
@ -220,6 +220,8 @@ void TtsPlatformImplWin::OnSpeechEvent() {
|
||||||
utterance_id_, TTS_EVENT_SENTENCE, char_position_,
|
utterance_id_, TTS_EVENT_SENTENCE, char_position_,
|
||||||
std::string());
|
std::string());
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -246,8 +248,8 @@ TtsPlatformImplWin::TtsPlatformImplWin()
|
||||||
|
|
||||||
// static
|
// static
|
||||||
TtsPlatformImplWin* TtsPlatformImplWin::GetInstance() {
|
TtsPlatformImplWin* TtsPlatformImplWin::GetInstance() {
|
||||||
return Singleton<TtsPlatformImplWin,
|
return base::Singleton<TtsPlatformImplWin,
|
||||||
LeakySingletonTraits<TtsPlatformImplWin> >::get();
|
base::LeakySingletonTraits<TtsPlatformImplWin>>::get();
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
|
|
@ -21,7 +21,7 @@ const char kAppMenuRegistrarPath[] = "/com/canonical/AppMenu/Registrar";
|
||||||
|
|
||||||
// static
|
// static
|
||||||
GlobalMenuBarRegistrarX11* GlobalMenuBarRegistrarX11::GetInstance() {
|
GlobalMenuBarRegistrarX11* GlobalMenuBarRegistrarX11::GetInstance() {
|
||||||
return Singleton<GlobalMenuBarRegistrarX11>::get();
|
return base::Singleton<GlobalMenuBarRegistrarX11>::get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalMenuBarRegistrarX11::OnWindowMapped(unsigned long xid) {
|
void GlobalMenuBarRegistrarX11::OnWindowMapped(unsigned long xid) {
|
||||||
|
@ -39,7 +39,7 @@ void GlobalMenuBarRegistrarX11::OnWindowUnmapped(unsigned long xid) {
|
||||||
}
|
}
|
||||||
|
|
||||||
GlobalMenuBarRegistrarX11::GlobalMenuBarRegistrarX11()
|
GlobalMenuBarRegistrarX11::GlobalMenuBarRegistrarX11()
|
||||||
: registrar_proxy_(NULL) {
|
: registrar_proxy_(nullptr) {
|
||||||
// libdbusmenu uses the gio version of dbus; I tried using the code in dbus/,
|
// libdbusmenu uses the gio version of dbus; I tried using the code in dbus/,
|
||||||
// but it looks like that's isn't sharing the bus name with the gio version,
|
// but it looks like that's isn't sharing the bus name with the gio version,
|
||||||
// even when |connection_type| is set to SHARED.
|
// even when |connection_type| is set to SHARED.
|
||||||
|
@ -49,11 +49,11 @@ GlobalMenuBarRegistrarX11::GlobalMenuBarRegistrarX11()
|
||||||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
|
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
|
||||||
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS |
|
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS |
|
||||||
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START),
|
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START),
|
||||||
NULL,
|
nullptr,
|
||||||
kAppMenuRegistrarName,
|
kAppMenuRegistrarName,
|
||||||
kAppMenuRegistrarPath,
|
kAppMenuRegistrarPath,
|
||||||
kAppMenuRegistrarName,
|
kAppMenuRegistrarName,
|
||||||
NULL, // TODO: Probalby want a real cancelable.
|
nullptr, // TODO: Probalby want a real cancelable.
|
||||||
static_cast<GAsyncReadyCallback>(OnProxyCreatedThunk),
|
static_cast<GAsyncReadyCallback>(OnProxyCreatedThunk),
|
||||||
this);
|
this);
|
||||||
}
|
}
|
||||||
|
@ -84,9 +84,9 @@ void GlobalMenuBarRegistrarX11::RegisterXID(unsigned long xid) {
|
||||||
"RegisterWindow",
|
"RegisterWindow",
|
||||||
g_variant_new("(uo)", xid, path.c_str()),
|
g_variant_new("(uo)", xid, path.c_str()),
|
||||||
G_DBUS_CALL_FLAGS_NONE, -1,
|
G_DBUS_CALL_FLAGS_NONE, -1,
|
||||||
NULL,
|
nullptr,
|
||||||
NULL,
|
nullptr,
|
||||||
NULL);
|
nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalMenuBarRegistrarX11::UnregisterXID(unsigned long xid) {
|
void GlobalMenuBarRegistrarX11::UnregisterXID(unsigned long xid) {
|
||||||
|
@ -105,14 +105,14 @@ void GlobalMenuBarRegistrarX11::UnregisterXID(unsigned long xid) {
|
||||||
"UnregisterWindow",
|
"UnregisterWindow",
|
||||||
g_variant_new("(u)", xid),
|
g_variant_new("(u)", xid),
|
||||||
G_DBUS_CALL_FLAGS_NONE, -1,
|
G_DBUS_CALL_FLAGS_NONE, -1,
|
||||||
NULL,
|
nullptr,
|
||||||
NULL,
|
nullptr,
|
||||||
NULL);
|
nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalMenuBarRegistrarX11::OnProxyCreated(GObject* source,
|
void GlobalMenuBarRegistrarX11::OnProxyCreated(GObject* source,
|
||||||
GAsyncResult* result) {
|
GAsyncResult* result) {
|
||||||
GError* error = NULL;
|
GError* error = nullptr;
|
||||||
GDBusProxy* proxy = g_dbus_proxy_new_for_bus_finish(result, &error);
|
GDBusProxy* proxy = g_dbus_proxy_new_for_bus_finish(result, &error);
|
||||||
if (error) {
|
if (error) {
|
||||||
g_error_free(error);
|
g_error_free(error);
|
||||||
|
@ -128,7 +128,7 @@ void GlobalMenuBarRegistrarX11::OnProxyCreated(GObject* source,
|
||||||
g_signal_connect(registrar_proxy_, "notify::g-name-owner",
|
g_signal_connect(registrar_proxy_, "notify::g-name-owner",
|
||||||
G_CALLBACK(OnNameOwnerChangedThunk), this);
|
G_CALLBACK(OnNameOwnerChangedThunk), this);
|
||||||
|
|
||||||
OnNameOwnerChanged(NULL, NULL);
|
OnNameOwnerChanged(nullptr, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalMenuBarRegistrarX11::OnNameOwnerChanged(GObject* /* ignored */,
|
void GlobalMenuBarRegistrarX11::OnNameOwnerChanged(GObject* /* ignored */,
|
||||||
|
|
|
@ -28,7 +28,7 @@ class GlobalMenuBarRegistrarX11 {
|
||||||
void OnWindowUnmapped(unsigned long xid);
|
void OnWindowUnmapped(unsigned long xid);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend struct DefaultSingletonTraits<GlobalMenuBarRegistrarX11>;
|
friend struct base::DefaultSingletonTraits<GlobalMenuBarRegistrarX11>;
|
||||||
|
|
||||||
GlobalMenuBarRegistrarX11();
|
GlobalMenuBarRegistrarX11();
|
||||||
~GlobalMenuBarRegistrarX11();
|
~GlobalMenuBarRegistrarX11();
|
||||||
|
|
|
@ -17,7 +17,7 @@ class FilePath;
|
||||||
namespace chrome {
|
namespace chrome {
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PATH_START = 1000,
|
PATH_START = 2000,
|
||||||
|
|
||||||
DIR_APP = PATH_START, // Directory where dlls and data reside.
|
DIR_APP = PATH_START, // Directory where dlls and data reside.
|
||||||
DIR_LOGS, // Directory where logs should be written.
|
DIR_LOGS, // Directory where logs should be written.
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
#include "third_party/skia/include/core/SkMatrix.h"
|
#include "third_party/skia/include/core/SkMatrix.h"
|
||||||
#include "third_party/skia/include/core/SkPaint.h"
|
#include "third_party/skia/include/core/SkPaint.h"
|
||||||
#include "third_party/skia/include/core/SkPoint.h"
|
#include "third_party/skia/include/core/SkPoint.h"
|
||||||
#include "third_party/skia/include/core/SkTemplates.h"
|
|
||||||
#include "third_party/skia/include/core/SkTypeface.h"
|
#include "third_party/skia/include/core/SkTypeface.h"
|
||||||
#include "ui/gfx/geometry/rect.h"
|
#include "ui/gfx/geometry/rect.h"
|
||||||
#include "url/gurl.h"
|
#include "url/gurl.h"
|
||||||
|
@ -315,7 +314,7 @@ int32_t PepperFlashRendererHost::OnNavigate(
|
||||||
bool rejected = false;
|
bool rejected = false;
|
||||||
while (header_iter.GetNext()) {
|
while (header_iter.GetNext()) {
|
||||||
std::string lower_case_header_name =
|
std::string lower_case_header_name =
|
||||||
base::StringToLowerASCII(header_iter.name());
|
base::ToLowerASCII(header_iter.name());
|
||||||
if (!IsSimpleHeader(lower_case_header_name, header_iter.values())) {
|
if (!IsSimpleHeader(lower_case_header_name, header_iter.values())) {
|
||||||
rejected = true;
|
rejected = true;
|
||||||
|
|
||||||
|
|
|
@ -544,7 +544,6 @@ void PrepareFrameAndViewForPrint::CopySelection(
|
||||||
// on the page).
|
// on the page).
|
||||||
WebPreferences prefs = preferences;
|
WebPreferences prefs = preferences;
|
||||||
prefs.javascript_enabled = false;
|
prefs.javascript_enabled = false;
|
||||||
prefs.java_enabled = false;
|
|
||||||
|
|
||||||
blink::WebView* web_view = blink::WebView::create(this);
|
blink::WebView* web_view = blink::WebView::create(this);
|
||||||
owns_web_view_ = true;
|
owns_web_view_ = true;
|
||||||
|
|
|
@ -135,7 +135,8 @@ bool PrintWebViewHelper::PrintPagesNative(blink::WebFrame* frame,
|
||||||
printed_page_params.page_size = page_size_in_dpi[i];
|
printed_page_params.page_size = page_size_in_dpi[i];
|
||||||
printed_page_params.content_area = content_area_in_dpi[i];
|
printed_page_params.content_area = content_area_in_dpi[i];
|
||||||
Send(new PrintHostMsg_DidPrintPage(routing_id(), printed_page_params));
|
Send(new PrintHostMsg_DidPrintPage(routing_id(), printed_page_params));
|
||||||
printed_page_params.metafile_data_handle = INVALID_HANDLE_VALUE;
|
// Send the rest of the pages with an invalid metafile handle.
|
||||||
|
printed_page_params.metafile_data_handle = base::SharedMemoryHandle();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ class LibSpeechdLoader {
|
||||||
decltype(&::spd_set_synthesis_voice) spd_set_synthesis_voice;
|
decltype(&::spd_set_synthesis_voice) spd_set_synthesis_voice;
|
||||||
decltype(&::spd_list_modules) spd_list_modules;
|
decltype(&::spd_list_modules) spd_list_modules;
|
||||||
decltype(&::spd_set_output_module) spd_set_output_module;
|
decltype(&::spd_set_output_module) spd_set_output_module;
|
||||||
|
decltype(&::spd_set_language) spd_set_language;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -201,6 +201,19 @@ bool LibSpeechdLoader::Load(const std::string& library_name) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DLOPEN)
|
||||||
|
spd_set_language =
|
||||||
|
reinterpret_cast<decltype(this->spd_set_language)>(
|
||||||
|
dlsym(library_, "spd_set_language"));
|
||||||
|
#endif
|
||||||
|
#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DT_NEEDED)
|
||||||
|
spd_set_language = &::spd_set_language;
|
||||||
|
#endif
|
||||||
|
if (!spd_set_language) {
|
||||||
|
CleanUp(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
loaded_ = true;
|
loaded_ = true;
|
||||||
return true;
|
return true;
|
||||||
|
@ -227,5 +240,6 @@ void LibSpeechdLoader::CleanUp(bool unload) {
|
||||||
spd_set_synthesis_voice = NULL;
|
spd_set_synthesis_voice = NULL;
|
||||||
spd_list_modules = NULL;
|
spd_list_modules = NULL;
|
||||||
spd_set_output_module = NULL;
|
spd_set_output_module = NULL;
|
||||||
|
spd_set_language = NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,7 +228,7 @@ void StreamListenSocket::CloseSocket() {
|
||||||
void StreamListenSocket::WatchSocket(WaitState state) {
|
void StreamListenSocket::WatchSocket(WaitState state) {
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
WSAEventSelect(socket_, socket_event_, FD_ACCEPT | FD_CLOSE | FD_READ);
|
WSAEventSelect(socket_, socket_event_, FD_ACCEPT | FD_CLOSE | FD_READ);
|
||||||
watcher_.StartWatching(socket_event_, this);
|
watcher_.StartWatchingOnce(socket_event_, this);
|
||||||
#elif defined(OS_POSIX)
|
#elif defined(OS_POSIX)
|
||||||
// Implicitly calls StartWatchingFileDescriptor().
|
// Implicitly calls StartWatchingFileDescriptor().
|
||||||
base::MessageLoopForIO::current()->WatchFileDescriptor(
|
base::MessageLoopForIO::current()->WatchFileDescriptor(
|
||||||
|
@ -264,7 +264,7 @@ void StreamListenSocket::OnObjectSignaled(HANDLE object) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// The object was reset by WSAEnumNetworkEvents. Watch for the next signal.
|
// The object was reset by WSAEnumNetworkEvents. Watch for the next signal.
|
||||||
watcher_.StartWatching(object, this);
|
watcher_.StartWatchingOnce(object, this);
|
||||||
|
|
||||||
if (ev.lNetworkEvents == 0) {
|
if (ev.lNetworkEvents == 0) {
|
||||||
// Occasionally the event is set even though there is no new data.
|
// Occasionally the event is set even though there is no new data.
|
||||||
|
|
632
docs-translations/pt-BR/api/browser-window.md
Normal file
632
docs-translations/pt-BR/api/browser-window.md
Normal file
|
@ -0,0 +1,632 @@
|
||||||
|
# BrowserWindow
|
||||||
|
|
||||||
|
A classe `BrowserWindow` lhe dá a habilidade de criar uma janela do browser. Por exemplo:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const BrowserWindow = require('electron').BrowserWindow;
|
||||||
|
|
||||||
|
var win = new BrowserWindow({ width: 800, height: 600, show: false });
|
||||||
|
win.on('closed', function() {
|
||||||
|
win = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
win.loadURL('https://github.com');
|
||||||
|
win.show();
|
||||||
|
```
|
||||||
|
|
||||||
|
Você também pode criar uma janela sem o chrome utilizando a API [Frameless Window](../../../docs/api/frameless-window.md).
|
||||||
|
|
||||||
|
## Classe: BrowserWindow
|
||||||
|
|
||||||
|
`BrowserWindow` é um [EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter).
|
||||||
|
|
||||||
|
Ela cria uma nova `BrowserWindow` com propriedades nativas definidas pelo `options`.
|
||||||
|
|
||||||
|
### `new BrowserWindow([options])`
|
||||||
|
|
||||||
|
`options` Objeto (opcional), propriedades:
|
||||||
|
|
||||||
|
* `width` Integer - Largura da janela em pixels. O padrão é `800`.
|
||||||
|
* `height` Integer - Altura da janela em pixels. O padrão é `600`.
|
||||||
|
* `x` Integer - Deslocamento da janela da esquerda da tela. O padrão é centralizar a janela.
|
||||||
|
* `y` Integer - Deslocamento da janela do topo da tela. O padrão é centralizar a janela.
|
||||||
|
* `useContentSize` Boolean - `width` e `height` seriam utilizados como o tamanho da página web, o que significa que o tamanho real da janela irá incluir o tamanho da moldura da janela e será um pouco maior. O padrão é `false`.
|
||||||
|
* `center` Boolean - Mostra a janela no centro da tela.
|
||||||
|
* `minWidth` Integer - Largura mínima da janela. O padrão é `0`.
|
||||||
|
* `minHeight` Integer - Altura mínima da janela. O padrão é `0`.
|
||||||
|
* `maxWidth` Integer - Largura máxima da janela. O padrão é sem limites.
|
||||||
|
* `maxHeight` Integer - Altura máxima da janela. O padrão é sem limites.
|
||||||
|
* `resizable` Boolean - Se é possível modificar o tamanho da janela. O padrão é `true`.
|
||||||
|
* `alwaysOnTop` Boolean - Se a janela deve sempre ficar à frente de outras janelas. O padrão é `false`.
|
||||||
|
* `fullscreen` Boolean - Se a janela deve estar em tela cheia. Quando definido como `false`, o botão de tela cheia estará escondido ou desabilitado no OS X. O padrão é `false`.
|
||||||
|
* `skipTaskbar` Boolean - Se deve mostrar a janela na barra de tarefas. O padrão é `false`.
|
||||||
|
* `kiosk` Boolean - Modo *kiosk*. O padrão é `false`.
|
||||||
|
* `title` String - Título padrão da janela. O padrão é `"Electron"`.
|
||||||
|
* `icon` [NativeImage](../../../docs/api/native-image.md) - O ícone da janela, quando omitido no Windows, o ícone do executável é utilizado como o ícone da janela.
|
||||||
|
* `show` Boolean - Se a janela deve ser exibida quando criada. O padrão é `true`.
|
||||||
|
* `frame` Boolean - Defina como `false` para criar uma [Frameless Window](../../../docs/api/frameless-window.md). O padrão é `true`.
|
||||||
|
* `acceptFirstMouse` Boolean - Se o *web view* aceita um evento *mouse-down* que ativa a janela simultaneamente. O padrão é `false`.
|
||||||
|
* `disableAutoHideCursor` Boolean - Se deve esconder o cursor quando estiver digitando. O padrão é `false`.
|
||||||
|
* `autoHideMenuBar` Boolean - Esconde a barra de menu automaticamente, a não ser que a tecla `Alt` seja pressionada. O padrão é `false`.
|
||||||
|
* `enableLargerThanScreen` Boolean - Possibilita que o tamanho da janela seja maior que a tela. O padrão é `false`.
|
||||||
|
* `backgroundColor` String - Cor de fundo da janela em hexadecimal, como `#66CD00` ou `#FFF`. Só é implementado no Linux e Windows. O padrão é `#000` (preto).
|
||||||
|
* `darkTheme` Boolean - Força a utilização do tema *dark* na janela, só funciona em alguns ambientes de desktop GTK+3. O padrão é `false`.
|
||||||
|
* `transparent` Boolean - Torna a janela [transparente](../../../docs/api/frameless-window.md). O padrão é `false`.
|
||||||
|
* `type` String - Define o tipo da janela, que aplica propriedades adicionais específicas da plataforma. Por padrão é indefinido e será criada uma janela de aplicativo comum. Possíveis valores:
|
||||||
|
* No Linux, os tipos possíveis são `desktop`, `dock`, `toolbar`, `splash`,
|
||||||
|
`notification`.
|
||||||
|
* No OS X, os tipos possíveis são `desktop`, `textured`. O tipo `textured` adiciona a aparência degradê metálica (`NSTexturedBackgroundWindowMask`). O tipo `desktop` coloca a janela no nível do fundo de tela do desktop (`kCGDesktopWindowLevel - 1`). Note que a janela `desktop` não irá receber foco, eventos de teclado ou mouse, mas você pode usar `globalShortcut` para receber entrada de dados ocasionalmente.
|
||||||
|
* `titleBarStyle` String, OS X - Define o estilo da barra de título da janela. Esta opção está suportada a partir da versão OS X 10.10 Yosemite. Há três possíveis valores:
|
||||||
|
* `default` ou não definido, resulta na barra de título cinza opaca padrão do Mac.
|
||||||
|
* `hidden` resulta numa barra de título oculta e a janela de conteúdo no tamanho máximo, porém a barra de título ainda possui os controles padrões de janela ("semáforo") no canto superior esquerdo.
|
||||||
|
* `hidden-inset` resulta numa barra de título oculta com uma aparência alternativa onde os botões de semáforo estão ligeiramente mais longe do canto da janela.
|
||||||
|
* `webPreferences` Object - Configurações das características da página web, propriedades:
|
||||||
|
* `nodeIntegration` Boolean - Se a integração com node está habilitada. O padrão é `true`.
|
||||||
|
* `preload` String - Define um *script* que será carregado antes que outros scripts rodem na página. Este script sempre terá acesso às APIs do node, não importa se `nodeIntegration` esteja habilitada ou não. O valor deve ser o endereço absoluto do scriot. Quando `nodeIntegration` não está habilitada, o script `preload` pode reintroduzir símbolos globais Node de volta ao escopo global. Veja um exemplo [aqui](process.md#evento-loaded).
|
||||||
|
* `partition` String - Define a sessão utilizada pela página. Se `partition` começa com `persist:`, a página irá utilizar uma sessão persistente disponível para todas as páginas do aplicativo com a mesma `partition`. Se não houver o prefixo `persist:`, a página irá utilizar uma sessão em memória. Ao utilizar a mesma `partition`, várias páginas podem compartilhar a mesma sessão. Se a `partition` for indefinida, então a sessão padrão do aplicativo será utilizada.
|
||||||
|
* `zoomFactor` Number - O fator de *zoom* da página, `3.0` representa `300%`. O padrão é `1.0`.
|
||||||
|
* `javascript` Boolean - Habilita suporte à JavaScript. O padrão é `true`.
|
||||||
|
* `webSecurity` Boolean - Quando definido como `false`, irá desabilitar a política de mesma origem (Geralmente usando sites de teste por pessoas), e definir `allowDisplayingInsecureContent` e `allowRunningInsecureContent` como
|
||||||
|
`true` se estas duas opções não tiverem sido definidas pelo usuário. O padrão é `true`.
|
||||||
|
* `allowDisplayingInsecureContent` Boolean - Permite que uma página https exiba conteúdo como imagens de URLs http. O padrão é `false`.
|
||||||
|
* `allowRunningInsecureContent` Boolean - Permite que uma página https rode JavaScript, CSS ou plugins de URLs http. O padrão é `false`.
|
||||||
|
* `images` Boolean - Habilita suporte a imagens. O padrão é `true`.
|
||||||
|
* `java` Boolean - Habilita suporte a Java. O padrão é `false`.
|
||||||
|
* `textAreasAreResizable` Boolean - Faz com que os elementos *TextArea* elements tenham tamanho variável. O padrão é `true`.
|
||||||
|
* `webgl` Boolean - Habiltia suporte a WebGL. O padrão é `true`.
|
||||||
|
* `webaudio` Boolean - Habilita suporte a WebAudio. O padrão é `true`.
|
||||||
|
* `plugins` Boolean - Se plugins devem ser habilitados. O padrão é `false`.
|
||||||
|
* `experimentalFeatures` Boolean - Habilita as características experimentais do Chromium. O padrão é `false`.
|
||||||
|
* `experimentalCanvasFeatures` Boolean - Habilita as características experimentais de canvas do Chromium. O padrão é `false`.
|
||||||
|
* `overlayScrollbars` Boolean - Habilita sobreposição das barras de rolagem. O padrão é `false`.
|
||||||
|
* `overlayFullscreenVideo` Boolean - Habilita sobreposição do vídeo em tela cheia. O padrão é `false`.
|
||||||
|
* `sharedWorker` Boolean - Habilita suporte a *Shared Worker*. O padrão é `false`.
|
||||||
|
* `directWrite` Boolean - Habilita o sistema de renderização de fontes *DirectWrite* no Windows. O padrão é `true`.
|
||||||
|
* `pageVisibility` Boolean - A página é forçada a permanecer visível ou oculta quando definido, em vez de refletir a visibilidade atual da janela. Usuários podem definir como `true` para evitar que os temporizadores do *DOM* sejam suprimidos. O padrão é `false`.
|
||||||
|
|
||||||
|
## Eventos
|
||||||
|
|
||||||
|
O objeto `BrowserWindow` emite os seguintes eventos:
|
||||||
|
|
||||||
|
**Nota:** Alguns eventos só estão disponíveis em sistemas operacionais específicos e estão rotulados como tal.
|
||||||
|
|
||||||
|
### Evento: 'page-title-updated'
|
||||||
|
|
||||||
|
Retorna:
|
||||||
|
|
||||||
|
* `event` Evento
|
||||||
|
|
||||||
|
Emitido quando o documento muda seu título, chamar `event.preventDefault()` previne que o título nativo da janela mude.
|
||||||
|
|
||||||
|
### Evento: 'close'
|
||||||
|
|
||||||
|
Retorna:
|
||||||
|
|
||||||
|
* `event` Evento
|
||||||
|
|
||||||
|
Emitido quando a janela for fechar. É emitido antes dos eventos `beforeunload` e `unload` do DOM. Chamar `event.preventDefault()` cancela o fechamento.
|
||||||
|
|
||||||
|
Normalmente você utiliza o manipulador de eventos do `beforeunload` para decidir se a janela deve ser fechada, que também será chamado quando a janela é recarregada. No Electron, retornar uma string vazia ou `false` cancela o fechamento. Por exemplo:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
window.onbeforeunload = function(e) {
|
||||||
|
console.log('Não quero ser fechada');
|
||||||
|
|
||||||
|
// Diferente de navegadores comuns, nos quais uma string deve ser retornada e
|
||||||
|
// o usuário deve confirmar se a janela será fechada, o Electron dá mais opções
|
||||||
|
// aos desenvolvedores. Retornar uma string vazia ou false cancela o fechamento.
|
||||||
|
// Você também pode usar a API de diálogo para deixar que o usuário confirme o
|
||||||
|
// fechamento do aplicativo.
|
||||||
|
e.returnValue = false;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Evento: 'closed'
|
||||||
|
|
||||||
|
Emitido quando a janela é fechada. Após você ter recebido este evento, você deve remover a referência da janela e evitar utilizá-la.
|
||||||
|
|
||||||
|
### Evento: 'unresponsive'
|
||||||
|
|
||||||
|
Emitido quando a página web para de responder.
|
||||||
|
|
||||||
|
### Evento: 'responsive'
|
||||||
|
|
||||||
|
Emitido quando a página web que não respondia volta a responder novamente.
|
||||||
|
|
||||||
|
### Evento: 'blur'
|
||||||
|
|
||||||
|
Emitido quando a janela perde foco.
|
||||||
|
|
||||||
|
### Evento: 'focus'
|
||||||
|
|
||||||
|
Emitido quando a janela ganha foco.
|
||||||
|
|
||||||
|
### Evento: 'maximize'
|
||||||
|
|
||||||
|
Emitido quando a janela é maximizada.
|
||||||
|
|
||||||
|
### Evento: 'unmaximize'
|
||||||
|
|
||||||
|
Emitido quando a janela sai do estado maximizado.
|
||||||
|
|
||||||
|
### Evento: 'minimize'
|
||||||
|
|
||||||
|
Emitido quando a janela é minimizada.
|
||||||
|
|
||||||
|
### Evento: 'restore'
|
||||||
|
|
||||||
|
Emitido quando a janela é restaurada do estado minimizado.
|
||||||
|
|
||||||
|
### Evento: 'resize'
|
||||||
|
|
||||||
|
Emitido quando o tamanho da janela está sendo alterado.
|
||||||
|
|
||||||
|
### Evento: 'move'
|
||||||
|
|
||||||
|
Emitido quando está sendo movida para uma nova posição.
|
||||||
|
|
||||||
|
__Note__: No OS X este evento é apenas um apelido de `moved`.
|
||||||
|
|
||||||
|
### Evento: 'moved' _OS X_
|
||||||
|
|
||||||
|
Emitido uma vez quando a janela é movida para uma nova posição.
|
||||||
|
|
||||||
|
### Evento: 'enter-full-screen'
|
||||||
|
|
||||||
|
Emitido quando a janela entra no estado tela cheia.
|
||||||
|
|
||||||
|
### Evento: 'leave-full-screen'
|
||||||
|
|
||||||
|
Emitido quando a janela sai do estado de tela cheia.
|
||||||
|
|
||||||
|
### Evento: 'enter-html-full-screen'
|
||||||
|
|
||||||
|
Emitido quando a janela entra no estado tela cheia, ocasionado por uma api de html.
|
||||||
|
|
||||||
|
### Evento: 'leave-html-full-screen'
|
||||||
|
|
||||||
|
Emitido quando a janela sai do estado de tela cheia, ocasionado por uma api de html.
|
||||||
|
|
||||||
|
### Evento: 'app-command' _Windows_
|
||||||
|
|
||||||
|
Emitido quando um [App Command](https://msdn.microsoft.com/en-us/library/windows/desktop/ms646275(v=vs.85).aspx) é invocado. Estes estão tipicamente relacionado às teclas de mídia do teclado, ou comandos do browser, assim como o botão "Voltar" existente em alguns modelos de mouse no Windows.
|
||||||
|
|
||||||
|
```js
|
||||||
|
someWindow.on('app-command', function(e, cmd) {
|
||||||
|
// Navega a janela 'para trás' quando o usuário pressiona o botão voltar do mouse
|
||||||
|
if (cmd === 'browser-backward' && someWindow.webContents.canGoBack()) {
|
||||||
|
someWindow.webContents.goBack();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Métodos
|
||||||
|
|
||||||
|
O objeto `BrowserWindow` possui os seguintes métodos:
|
||||||
|
|
||||||
|
### `BrowserWindow.getAllWindows()`
|
||||||
|
|
||||||
|
Retorna um array de todas as janelas abertas.
|
||||||
|
|
||||||
|
### `BrowserWindow.getFocusedWindow()`
|
||||||
|
|
||||||
|
Retorna a janela que está focada no aplicativo.
|
||||||
|
|
||||||
|
### `BrowserWindow.fromWebContents(webContents)`
|
||||||
|
|
||||||
|
* `webContents` [WebContents](../../../docs/api/web-contents.md)
|
||||||
|
|
||||||
|
Acha uma janela de acordo com os `webContents` que ela possui.
|
||||||
|
|
||||||
|
### `BrowserWindow.fromId(id)`
|
||||||
|
|
||||||
|
* `id` Integer
|
||||||
|
|
||||||
|
Acha uma janela de acordo com o seu ID.
|
||||||
|
|
||||||
|
### `BrowserWindow.addDevToolsExtension(path)`
|
||||||
|
|
||||||
|
* `path` String
|
||||||
|
|
||||||
|
Adiciona a extenção DevTools localizada no endereço `path`, e retorna o nome da extenção.
|
||||||
|
|
||||||
|
A extenção será lembrada, então você só precisa chamar esta API uma vez, esta API não é para uso de programação.
|
||||||
|
|
||||||
|
### `BrowserWindow.removeDevToolsExtension(name)`
|
||||||
|
|
||||||
|
* `name` String
|
||||||
|
|
||||||
|
Remove a extenção DevTools cujo nome é `name`.
|
||||||
|
|
||||||
|
## Propriedades de Instância
|
||||||
|
|
||||||
|
Objetos criados com `new BrowserWindow` possuem as seguintes propriedades:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Neste exemplo `win` é a nossa instância
|
||||||
|
var win = new BrowserWindow({ width: 800, height: 600 });
|
||||||
|
```
|
||||||
|
|
||||||
|
### `win.webContents`
|
||||||
|
|
||||||
|
Todas os eventos e operações relacionados à pagina web serão feitos através do objeto `WebContents` que a esta janela possui.
|
||||||
|
|
||||||
|
Veja a [documentação do `webContents`](../../../docs/api/web-contents.md) para seus métodos e eventos.
|
||||||
|
|
||||||
|
### `win.id`
|
||||||
|
|
||||||
|
O ID único desta janela.
|
||||||
|
|
||||||
|
## Métodos de instância
|
||||||
|
|
||||||
|
Objetos criados com `new BrowserWindow` possuem os seguintes métodos de instância:
|
||||||
|
|
||||||
|
**Nota:** Alguns métodos só estão disponíveis em sistemas operacionais específicos e estão rotulados como tal.
|
||||||
|
|
||||||
|
### `win.destroy()`
|
||||||
|
|
||||||
|
Força o fechamento da janela, os eventos `unload` e `beforeunload` não serão emitidos para a página web, e o evento `close` também não será emitido para esta janela, mas garante que o evento `closed` será emitido.
|
||||||
|
|
||||||
|
Você só deve utilizar este método quando o processo renderizador (página web) congelar.
|
||||||
|
|
||||||
|
### `win.close()`
|
||||||
|
|
||||||
|
Tenta fechar a janela, tem o mesmo efeito que o usuário manualmente clicar o botão de fechar a janela. Entretanto, a página web pode cancelar o fechamento, veja o [evento close](#evento-close).
|
||||||
|
|
||||||
|
### `win.focus()`
|
||||||
|
|
||||||
|
Foca na janela.
|
||||||
|
|
||||||
|
### `win.isFocused()`
|
||||||
|
|
||||||
|
Retorna um boolean, indicando se a janela está com foco.
|
||||||
|
|
||||||
|
### `win.show()`
|
||||||
|
|
||||||
|
Exibe e dá foco à janela.
|
||||||
|
|
||||||
|
### `win.showInactive()`
|
||||||
|
|
||||||
|
Exibe a janela, porém não dá foco à ela.
|
||||||
|
|
||||||
|
### `win.hide()`
|
||||||
|
|
||||||
|
Esconde a janela.
|
||||||
|
|
||||||
|
### `win.isVisible()`
|
||||||
|
|
||||||
|
Retorna um boolean, indicando se a janela está visível para o usuário.
|
||||||
|
|
||||||
|
### `win.maximize()`
|
||||||
|
|
||||||
|
Maximiza a janela.
|
||||||
|
|
||||||
|
### `win.unmaximize()`
|
||||||
|
|
||||||
|
Sai do estado maximizado da janela.
|
||||||
|
|
||||||
|
### `win.isMaximized()`
|
||||||
|
|
||||||
|
Retorna um boolean, indicando se a janela está maximizada.
|
||||||
|
|
||||||
|
### `win.minimize()`
|
||||||
|
|
||||||
|
Minimiza a janela. Em algumas plataformas, a janela minimizada será exibida no *Dock*.
|
||||||
|
|
||||||
|
### `win.restore()`
|
||||||
|
|
||||||
|
Restaura a janela do estado minimizado para o estado anterior.
|
||||||
|
|
||||||
|
### `win.isMinimized()`
|
||||||
|
|
||||||
|
Retorna um boolean, indicando se a janela está minimizada.
|
||||||
|
|
||||||
|
### `win.setFullScreen(flag)`
|
||||||
|
|
||||||
|
* `flag` Boolean
|
||||||
|
|
||||||
|
Define se a janela deve estar em modo tela cheia.
|
||||||
|
|
||||||
|
### `win.isFullScreen()`
|
||||||
|
|
||||||
|
Retorna um boolean, indicando se a janela está em modo tela cheia.
|
||||||
|
|
||||||
|
### `win.setAspectRatio(aspectRatio[, extraSize])` _OS X_
|
||||||
|
|
||||||
|
* `aspectRatio` A proporção que queremos manter para uma porção do conteúdo da *view*.
|
||||||
|
* `extraSize` Object (opcional) - O tamanho extra não incluído enquanto a proporção é mantida. Propriedades:
|
||||||
|
* `width` Integer
|
||||||
|
* `height` Integer
|
||||||
|
|
||||||
|
Isto fará com que a janela mantenha sua proporção. O `extraSize` permite que o desenvolvedor tenha espaço, definido em pixels, não incluídos no cálculo da proporção. Esta API já leva em consideração a diferença entre o tamanho da janela e o tamanho de seu conteúdo.
|
||||||
|
|
||||||
|
Suponha que exista uma janela normal com um *player* de vídeo HD e seus controles associados. Talvez tenha 15 pixels de controles na borda esquerda, 25 pixels de controles na borda direita e 50 abaixo do player. Para que seja mantida a proporção de 16:9 (proporção padrão para HD em 1920x1080) no próprio player, nós chamaríamos esta função com os argumentos 16/9 e [ 40, 50 ]. Para o segundo argumento, não interessa onde a largura e altura extras estão no conteúdo da view--apenas que elas existam. Apenas some qualquer área de largura e altura extras que você tem dentro da view do conteúdo.
|
||||||
|
|
||||||
|
### `win.setBounds(options)`
|
||||||
|
|
||||||
|
`options` Object, propriedades:
|
||||||
|
|
||||||
|
* `x` Integer
|
||||||
|
* `y` Integer
|
||||||
|
* `width` Integer
|
||||||
|
* `height` Integer
|
||||||
|
|
||||||
|
Redefine o tamanho e move a janela para `width`, `height`, `x`, `y`.
|
||||||
|
|
||||||
|
### `win.getBounds()`
|
||||||
|
|
||||||
|
Retorna um objeto que contém a largura, altura, posição x e y da janela.
|
||||||
|
|
||||||
|
### `win.setSize(width, height)`
|
||||||
|
|
||||||
|
* `width` Integer
|
||||||
|
* `height` Integer
|
||||||
|
|
||||||
|
Redefine o tamanho da janela para largura `width` e altura `height`.
|
||||||
|
|
||||||
|
### `win.getSize()`
|
||||||
|
|
||||||
|
Retorna um array que contém a largura e altura da janela.
|
||||||
|
|
||||||
|
### `win.setContentSize(width, height)`
|
||||||
|
|
||||||
|
* `width` Integer
|
||||||
|
* `height` Integer
|
||||||
|
|
||||||
|
Redefine a área de cliente da janela (a página web) para largura `width` e altura `height`.
|
||||||
|
|
||||||
|
### `win.getContentSize()`
|
||||||
|
|
||||||
|
Retorna um array que contém a largura e altura da área de cliente da janela.
|
||||||
|
|
||||||
|
### `win.setMinimumSize(width, height)`
|
||||||
|
|
||||||
|
* `width` Integer
|
||||||
|
* `height` Integer
|
||||||
|
|
||||||
|
Define o tamanho mínimo da janela para largura `width` e altura `height`.
|
||||||
|
|
||||||
|
### `win.getMinimumSize()`
|
||||||
|
|
||||||
|
Retorna uma array que contém o tamanho mínimo da largura e altura da janela.
|
||||||
|
|
||||||
|
### `win.setMaximumSize(width, height)`
|
||||||
|
|
||||||
|
* `width` Integer
|
||||||
|
* `height` Integer
|
||||||
|
|
||||||
|
Define o tamanho máximo da janela para largura `width` e altura `height`.
|
||||||
|
|
||||||
|
### `win.getMaximumSize()`
|
||||||
|
|
||||||
|
Retorna uma array que contém o tamanho máximo da largura e altura da janela.
|
||||||
|
|
||||||
|
### `win.setResizable(resizable)`
|
||||||
|
|
||||||
|
* `resizable` Boolean
|
||||||
|
|
||||||
|
Define se a janela pode ter seu tamanho redefinido manualmente pelo usuário.
|
||||||
|
|
||||||
|
### `win.isResizable()`
|
||||||
|
|
||||||
|
Retorna um boolean indicando se a janela pode ter seu tamanho redefinido manualmente pelo usuário.
|
||||||
|
|
||||||
|
### `win.setAlwaysOnTop(flag)`
|
||||||
|
|
||||||
|
* `flag` Boolean
|
||||||
|
|
||||||
|
Define se a janela deve estar sempre em cima de outras janelas. Após definir isso, a janela continua sendo uma janela normal, não uma janela *toolbox* que não pode receber foco.
|
||||||
|
|
||||||
|
### `win.isAlwaysOnTop()`
|
||||||
|
|
||||||
|
Retorna um boolean indicando se a janela está sempre em cima de outras janelas.
|
||||||
|
|
||||||
|
### `win.center()`
|
||||||
|
|
||||||
|
Move a janela para o centro da tela.
|
||||||
|
|
||||||
|
### `win.setPosition(x, y)`
|
||||||
|
|
||||||
|
* `x` Integer
|
||||||
|
* `y` Integer
|
||||||
|
|
||||||
|
Move a janela para `x` e `y`.
|
||||||
|
|
||||||
|
### `win.getPosition()`
|
||||||
|
|
||||||
|
Retorna um array com a posição atual da janela.
|
||||||
|
|
||||||
|
### `win.setTitle(title)`
|
||||||
|
|
||||||
|
* `title` String
|
||||||
|
|
||||||
|
Muda o título da janela nativa para `title`.
|
||||||
|
|
||||||
|
### `win.getTitle()`
|
||||||
|
|
||||||
|
Retorna o título da janela nativa.
|
||||||
|
|
||||||
|
**Nota:** O título da página web pode ser diferente do título da janela nativa.
|
||||||
|
|
||||||
|
### `win.flashFrame(flag)`
|
||||||
|
|
||||||
|
* `flag` Boolean
|
||||||
|
|
||||||
|
Inicia ou para de piscar a janela para atrair a atenção do usuário.
|
||||||
|
|
||||||
|
### `win.setSkipTaskbar(skip)`
|
||||||
|
|
||||||
|
* `skip` Boolean
|
||||||
|
|
||||||
|
Faz com que a janela não apareça na barra de tarefas.
|
||||||
|
|
||||||
|
### `win.setKiosk(flag)`
|
||||||
|
|
||||||
|
* `flag` Boolean
|
||||||
|
|
||||||
|
Entra ou sai do modo *kiosk*.
|
||||||
|
|
||||||
|
### `win.isKiosk()`
|
||||||
|
|
||||||
|
Retorna um boolean indicando se janela está no modo *kiosk*.
|
||||||
|
|
||||||
|
### `win.hookWindowMessage(message, callback)` _Windows_
|
||||||
|
|
||||||
|
* `message` Integer
|
||||||
|
* `callback` Function
|
||||||
|
|
||||||
|
Engancha uma mensagem de janela. O `callback` é chamado quando a mensagem é recebida no WndProc.
|
||||||
|
|
||||||
|
### `win.isWindowMessageHooked(message)` _Windows_
|
||||||
|
|
||||||
|
* `message` Integer
|
||||||
|
|
||||||
|
Retorna `true` ou `false` indicando se a mensagem está enganchada ou não.
|
||||||
|
|
||||||
|
### `win.unhookWindowMessage(message)` _Windows_
|
||||||
|
|
||||||
|
* `message` Integer
|
||||||
|
|
||||||
|
Desengancha a mensagem de janela.
|
||||||
|
|
||||||
|
### `win.unhookAllWindowMessages()` _Windows_
|
||||||
|
|
||||||
|
Desengancha todas as mensagens de janela.
|
||||||
|
|
||||||
|
### `win.setRepresentedFilename(filename)` _OS X_
|
||||||
|
|
||||||
|
* `filename` String
|
||||||
|
|
||||||
|
Define o endereço do arquivo que a janela representa, e o ícone do arquivo será exibido na barra de título da janela.
|
||||||
|
|
||||||
|
### `win.getRepresentedFilename()` _OS X_
|
||||||
|
|
||||||
|
Retorna o endereço do arquivo que a janela representa.
|
||||||
|
|
||||||
|
### `win.setDocumentEdited(edited)` _OS X_
|
||||||
|
|
||||||
|
* `edited` Boolean
|
||||||
|
|
||||||
|
Define se o documento da janela foi editado, e o ícone na barra de título se torna cinza quando definido como `true`.
|
||||||
|
|
||||||
|
### `win.isDocumentEdited()` _OS X_
|
||||||
|
|
||||||
|
Retorna um boolean indicando se o documento da janela foi editado.
|
||||||
|
|
||||||
|
### `win.focusOnWebView()`
|
||||||
|
|
||||||
|
### `win.blurWebView()`
|
||||||
|
|
||||||
|
### `win.capturePage([rect, ]callback)`
|
||||||
|
|
||||||
|
* `rect` Object (opcional)- A área da página a ser capturada. Propriedades:
|
||||||
|
* `x` Integer
|
||||||
|
* `y` Integer
|
||||||
|
* `width` Integer
|
||||||
|
* `height` Integer
|
||||||
|
* `callback` Function
|
||||||
|
|
||||||
|
Captura uma imagem da página dentro do `rect`. Após completar, `callback` será chamada com `callback(imagem)`. `imagem` é uma instância de [NativeImage](../../../docs/api/native-image.md) que guarda dados sobre a imagem. Omitir `rect` captura toda a página visível.
|
||||||
|
|
||||||
|
### `win.print([options])`
|
||||||
|
|
||||||
|
Igual a `webContents.print([options])`
|
||||||
|
|
||||||
|
### `win.printToPDF(options, callback)`
|
||||||
|
|
||||||
|
Igual a `webContents.printToPDF(options, callback)`
|
||||||
|
|
||||||
|
### `win.loadURL(url[, options])`
|
||||||
|
|
||||||
|
Igual a `webContents.loadURL(url[, options])`.
|
||||||
|
|
||||||
|
### `win.reload()`
|
||||||
|
|
||||||
|
Igual a `webContents.reload`.
|
||||||
|
|
||||||
|
### `win.setMenu(menu)` _Linux_ _Windows_
|
||||||
|
|
||||||
|
* `menu` Menu
|
||||||
|
|
||||||
|
Define `menu` como a barra de menu da janela, definir como `null` remove a barra de menu.
|
||||||
|
|
||||||
|
### `win.setProgressBar(progress)`
|
||||||
|
|
||||||
|
* `progress` Double
|
||||||
|
|
||||||
|
Define o valor do progresso na barra de progresso. Extensão válida é [0, 1.0].
|
||||||
|
|
||||||
|
Remove a barra de progresso quando `progress` < 0.
|
||||||
|
Muda para o modo indeterminado quando `progress` > 1.
|
||||||
|
|
||||||
|
Na plataforma Linux, apenas suporta o ambiente de desktop Unity, você precisa definir o nome do arquivo como `*.desktop` no campo `desktopName` no `package.json`. Por padrão, irá assumir `app.getName().desktop`.
|
||||||
|
|
||||||
|
### `win.setOverlayIcon(overlay, description)` _Windows 7+_
|
||||||
|
|
||||||
|
* `overlay` [NativeImage](../../../docs/api/native-image.md) - o ícone a ser exibido no canto inferior direito da barra de tarefas. Se este parâmetro for `null`, a sobreposição é eliminada.
|
||||||
|
* `description` String - uma descrição que será providenciada a leitores de tela de acessibilidade.
|
||||||
|
|
||||||
|
Define uma sobreposição de 16px sobre o ícone da barra de tarefas atual, geralmente utilizado para indicar algum tipo de status de aplicação, ou notificar passivamente o usuário.
|
||||||
|
|
||||||
|
### `win.setThumbarButtons(buttons)` _Windows 7+_
|
||||||
|
|
||||||
|
`buttons` Array de objetos `button`:
|
||||||
|
|
||||||
|
`button` Object, propriedades:
|
||||||
|
|
||||||
|
* `icon` [NativeImage](../../../docs/api/native-image.md) - O ícone exibido na barra de ferramentas miniatura.
|
||||||
|
* `tooltip` String (opcional) - O texto do balão de dica do botão.
|
||||||
|
* `flags` Array (opcional) - Controla estados e comportamentos específicos do botão. Utiliza `enabled` por padrão. Pode incluir as seguintes strings:
|
||||||
|
* `enabled` - O botão está ativo e disponível para o usuário.
|
||||||
|
* `disabled` - O botão está desabilitado. Está presente, mas possui um estado visual indicando que não irá responder às ações do usuário.
|
||||||
|
* `dismissonclick` - Quando o botão é clicado, o *flyout* do botão da barra de tarefas fecha imediatamente.
|
||||||
|
* `nobackground` - Não desenhe a borda do botão, apenas utilize a imagem.
|
||||||
|
* `hidden` - O botão não é exibido para o usuário.
|
||||||
|
* `noninteractive` - O botão está habilitado, mas não interage; Não é exibido o estado de botão pressionado. Este valor está destinado a instâncias nas quais o botão é utilizado em uma notificação.
|
||||||
|
* `click` - Função
|
||||||
|
|
||||||
|
Adiciona uma barra de ferramentes miniatura com um conjunto de botões específicos à imagem miniatura de uma janela no layout de um botão de barra de tarefas. Retorna um objeto `Boolean` indicando se a miniatura foi adicionada com sucesso.
|
||||||
|
|
||||||
|
O número de botões na barra de ferramentas miniatura não deve ser maior que 7 devido ao espaço limitado. Uma vez que você define a barra de ferramentas miniatura, ela não pode ser removida por causa da limitação da plataforma. Mas você pode chamar a API com um array vazio para limpar todos os botões.
|
||||||
|
|
||||||
|
### `win.showDefinitionForSelection()` _OS X_
|
||||||
|
|
||||||
|
Mostra um dicionário *pop-up* que procura a palavra selecionada na página.
|
||||||
|
|
||||||
|
### `win.setAutoHideMenuBar(hide)`
|
||||||
|
|
||||||
|
* `hide` Boolean
|
||||||
|
|
||||||
|
Define se a barra de menu da janela deve se esconder automaticamente. Uma vez que for definida, a barra de menu só será exibida quando usuários pressionarem a tecla `Alt`.
|
||||||
|
|
||||||
|
Se a barra de menu já estiver visível, chamar `setAutoHideMenuBar(true)` não irá escondê-la imediatamente.
|
||||||
|
|
||||||
|
### `win.isMenuBarAutoHide()`
|
||||||
|
|
||||||
|
Retorna um boolean indicando se a barra de menu se esconde automaticamente.
|
||||||
|
|
||||||
|
### `win.setMenuBarVisibility(visible)`
|
||||||
|
|
||||||
|
* `visible` Boolean
|
||||||
|
|
||||||
|
Define se a barra de menu deve ser visível. Se a barra de menu se esconde automaticamente, os usuários ainda podem exibí-la ao pressionar a tecla `Alt`.
|
||||||
|
|
||||||
|
### `win.isMenuBarVisible()`
|
||||||
|
|
||||||
|
Retorna um boolean indicando se a barra de menu está visível.
|
||||||
|
|
||||||
|
### `win.setVisibleOnAllWorkspaces(visible)`
|
||||||
|
|
||||||
|
* `visible` Boolean
|
||||||
|
|
||||||
|
Define se a janela deve estar visível em todos os *workspaces*.
|
||||||
|
|
||||||
|
**Nota:** Esta API não faz nada no Windows.
|
||||||
|
|
||||||
|
### `win.isVisibleOnAllWorkspaces()`
|
||||||
|
|
||||||
|
Retorna um boolean indicando se a janela está visível em todos os *workspaces*.
|
||||||
|
|
||||||
|
**Nota:** Esta API sempre retorna `false` no Windows.
|
||||||
|
|
||||||
|
|
142
docs-translations/pt-BR/development/build-instructions-linux.md
Normal file
142
docs-translations/pt-BR/development/build-instructions-linux.md
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
# Instruções de Build (Linux)
|
||||||
|
|
||||||
|
Siga as orientações abaixo pra fazer o build do Electron no Linux.
|
||||||
|
|
||||||
|
## Pré-requisitos
|
||||||
|
|
||||||
|
* Python 2.7.x. Algumas distribuições como CentOS ainda usam Python 2.6.x,
|
||||||
|
então você precisa checar a sua versão do Python com `python -V`.
|
||||||
|
* Node.js v0.12.x. Há várias maneiras de instalar o Node. Você pode baixar o
|
||||||
|
código fonte do [Node.js](http://nodejs.org) e compilar a partir dele.
|
||||||
|
Fazer isto permite que você instale o Node no seu próprio diretório home
|
||||||
|
como um usuário comum.
|
||||||
|
Ou tente repositórios como [NodeSource](https://nodesource.com/blog/nodejs-v012-iojs-and-the-nodesource-linux-repositories).
|
||||||
|
* Clang 3.4 ou mais recente.
|
||||||
|
* Cabeçalhos de desenvolvimento do GTK+ e libnotify.
|
||||||
|
|
||||||
|
No Ubuntu, instale as seguintes bibliotecas:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ sudo apt-get install build-essential clang libdbus-1-dev libgtk2.0-dev \
|
||||||
|
libnotify-dev libgnome-keyring-dev libgconf2-dev \
|
||||||
|
libasound2-dev libcap-dev libcups2-dev libxtst-dev \
|
||||||
|
libxss1 libnss3-dev gcc-multilib g++-multilib
|
||||||
|
```
|
||||||
|
|
||||||
|
No Fedora, instale as seguintes bibliotecas:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ sudo yum install clang dbus-devel gtk2-devel libnotify-devel libgnome-keyring-devel \
|
||||||
|
xorg-x11-server-utils libcap-devel cups-devel libXtst-devel \
|
||||||
|
alsa-lib-devel libXrandr-devel GConf2-devel nss-devel
|
||||||
|
```
|
||||||
|
|
||||||
|
Outras distribuições podem oferecer pacotes similares para instalação através
|
||||||
|
do gerenciador de pacotes como o pacman. Ou você pode compilar a partir do
|
||||||
|
código fonte.
|
||||||
|
|
||||||
|
## Se Você Utilizar Máquinas Virtuais Para Fazer O Build
|
||||||
|
|
||||||
|
Se você planeja fazer o build do Electron numa máquina virtual, você vai precisar
|
||||||
|
de um container de tamanho fixo de pelo menos 25 gigabytes.
|
||||||
|
|
||||||
|
## Baixando o Código
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ git clone https://github.com/atom/electron.git
|
||||||
|
```
|
||||||
|
|
||||||
|
## Bootstrapping
|
||||||
|
|
||||||
|
O script de *boostrap* irá baixar todas as dependências de build necessárias
|
||||||
|
e criar os arquivos de projeto do build. Você deve ter o Python 2.7.x para
|
||||||
|
executar o script com sucesso.
|
||||||
|
Baixar certos arquivos pode demorar bastante. Note que estamos utilizando
|
||||||
|
`ninja` para fazer o build do Electron, então não há um `Makefile` gerado.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ cd electron
|
||||||
|
$ ./script/bootstrap.py -v
|
||||||
|
```
|
||||||
|
|
||||||
|
### Compilação Cruzada
|
||||||
|
|
||||||
|
Se você quer fazer o build para `arm`, você também deve instalar as seguintes
|
||||||
|
dependências:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ sudo apt-get install libc6-dev-armhf-cross linux-libc-dev-armhf-cross \
|
||||||
|
g++-arm-linux-gnueabihf
|
||||||
|
```
|
||||||
|
|
||||||
|
E para fazer a compilação cruzada para `arm` ou `ia32`, você deve passar
|
||||||
|
o parâmetro `--target_arch` para o script `bootstrap.py`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ./script/bootstrap.py -v --target_arch=arm
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
Se você quiser fazer o build para `Release` e `Debug`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ./script/build.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Este script irá fazer com que um executável bem pesado do Electron seja
|
||||||
|
criado no diretório `out/R`. O arquivo possui mais de 1.3 gigabytes.
|
||||||
|
Isso acontece por que o binário do Release contém símbolos de debugging.
|
||||||
|
Para reduzir o tamanho do arquivo, rode o script `create-dist.py`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ./script/create-dist.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Isso irá colocar uma distribuição funcional com arquivos muito menores
|
||||||
|
no diretório `dist`. Depois de rodar o script `create-dist.py`, talvez
|
||||||
|
você queira remover o binário de 1.3+ gigabytes que ainda está em `out/R`.
|
||||||
|
|
||||||
|
Você também pode fazer apenas o build de `Debug`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ./script/build.py -c D
|
||||||
|
```
|
||||||
|
|
||||||
|
Depois de completar o build, você pode encontrar o binário de debug do `electron`
|
||||||
|
em `out/D`.
|
||||||
|
|
||||||
|
## Limpando
|
||||||
|
|
||||||
|
Para limpar os arquivos de build:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ./script/clean.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
Certifique-se de que você tenha instalado todas as dependências do build.
|
||||||
|
|
||||||
|
### Error While Loading Shared Libraries: libtinfo.so.5
|
||||||
|
|
||||||
|
O `clang` prebuilt irá tentar fazer o link com `libtinfo.so.5`. Dependendo
|
||||||
|
da arquitetura do host, faça um link simbólico para o `libncurses` apropriado:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ sudo ln -s /usr/lib/libncurses.so.5 /usr/lib/libtinfo.so.5
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testes
|
||||||
|
|
||||||
|
Teste suas modificações conforme o estilo de código do projeto utilizando:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ./script/cpplint.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Teste funcionalidade utilizando:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ./script/test.py
|
||||||
|
```
|
83
docs-translations/uk-UA/README.md
Normal file
83
docs-translations/uk-UA/README.md
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
Будь ласка, переконайтесь що ви використовуєте документацію, яка відповідає вашій версії Electron.
|
||||||
|
Номер версії повинен бути присутнім в URL адресі сторінки. Якщо це не так, Ви можливо,
|
||||||
|
використовуєте документацію із development гілки,
|
||||||
|
яка може містити зміни в API, які не сумісні з вашою версією Electron.
|
||||||
|
Якщо це так, тоді Ви можете переключитись на іншу версію документації
|
||||||
|
із списку [доступних версій](http://electron.atom.io/docs/) на atom.io,
|
||||||
|
або якщо ви використовуєте інтеррфейс GitHub,
|
||||||
|
тоді відкрийте список "Switch branches/tags" і виберіть потрібну вам
|
||||||
|
версію із списку тегів.
|
||||||
|
|
||||||
|
## Довідник
|
||||||
|
|
||||||
|
* [Підтримувані платформи](tutorial/supported-platforms.md)
|
||||||
|
* [Application Distribution](tutorial/application-distribution.md)
|
||||||
|
* [Mac App Store Submission Guide](tutorial/mac-app-store-submission-guide.md)
|
||||||
|
* [Упаковка додатку](tutorial/application-packaging.md)
|
||||||
|
* [Використання Native Node модулів](tutorial/using-native-node-modules.md)
|
||||||
|
* [Debugging Main Process](tutorial/debugging-main-process.md)
|
||||||
|
* [Використання Selenium and WebDriver](tutorial/using-selenium-and-webdriver.md)
|
||||||
|
* [DevTools Extension](tutorial/devtools-extension.md)
|
||||||
|
* [Використання Pepper Flash плагіну](tutorial/using-pepper-flash-plugin.md)
|
||||||
|
|
||||||
|
## Підручники
|
||||||
|
|
||||||
|
* [Швидкий старт](tutorial/quick-start.md)
|
||||||
|
* [Desktop Environment Integration](tutorial/desktop-environment-integration.md)
|
||||||
|
* [Online/Offline Event Detection](tutorial/online-offline-events.md)
|
||||||
|
|
||||||
|
## API References
|
||||||
|
|
||||||
|
* [Synopsis](api/synopsis.md)
|
||||||
|
* [Process Object](api/process.md)
|
||||||
|
* [Supported Chrome Command Line Switches](api/chrome-command-line-switches.md)
|
||||||
|
* [Environment Variables](api/environment-variables.md)
|
||||||
|
|
||||||
|
### Користувальницькі елементи DOM
|
||||||
|
|
||||||
|
* [`File` Object](api/file-object.md)
|
||||||
|
* [`<webview>` Tag](api/web-view-tag.md)
|
||||||
|
* [`window.open` Function](api/window-open.md)
|
||||||
|
|
||||||
|
### Модулі для Main Process:
|
||||||
|
|
||||||
|
* [app](api/app.md)
|
||||||
|
* [autoUpdater](api/auto-updater.md)
|
||||||
|
* [BrowserWindow](api/browser-window.md)
|
||||||
|
* [contentTracing](api/content-tracing.md)
|
||||||
|
* [dialog](api/dialog.md)
|
||||||
|
* [globalShortcut](api/global-shortcut.md)
|
||||||
|
* [ipcMain](api/ipc-main.md)
|
||||||
|
* [Menu](api/menu.md)
|
||||||
|
* [MenuItem](api/menu-item.md)
|
||||||
|
* [powerMonitor](api/power-monitor.md)
|
||||||
|
* [powerSaveBlocker](api/power-save-blocker.md)
|
||||||
|
* [protocol](api/protocol.md)
|
||||||
|
* [session](api/session.md)
|
||||||
|
* [webContents](api/web-contents.md)
|
||||||
|
* [Tray](api/tray.md)
|
||||||
|
|
||||||
|
### Модулі для Renderer Process (Web Page):
|
||||||
|
|
||||||
|
* [ipcRenderer](api/ipc-renderer.md)
|
||||||
|
* [remote](api/remote.md)
|
||||||
|
* [webFrame](api/web-frame.md)
|
||||||
|
|
||||||
|
### Модулі для Both Processes:
|
||||||
|
|
||||||
|
* [clipboard](api/clipboard.md)
|
||||||
|
* [crashReporter](api/crash-reporter.md)
|
||||||
|
* [nativeImage](api/native-image.md)
|
||||||
|
* [screen](api/screen.md)
|
||||||
|
* [shell](api/shell.md)
|
||||||
|
|
||||||
|
## Розробка
|
||||||
|
|
||||||
|
* [Стиль кодування](development/coding-style.md)
|
||||||
|
* [Source Code Directory Structure](development/source-code-directory-structure.md)
|
||||||
|
* [Technical Differences to NW.js (formerly node-webkit)](development/atom-shell-vs-node-webkit.md)
|
||||||
|
* [Build System Overview](development/build-system-overview.md)
|
||||||
|
* [Build Instructions (OS X)](development/build-instructions-osx.md)
|
||||||
|
* [Build Instructions (Windows)](development/build-instructions-windows.md)
|
||||||
|
* [Build Instructions (Linux)](development/build-instructions-linux.md)
|
||||||
|
* [Setting Up Symbol Server in debugger](development/setting-up-symbol-server.md)
|
97
docs-translations/uk-UA/styleguide.md
Normal file
97
docs-translations/uk-UA/styleguide.md
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
# Electron Documentation Styleguide
|
||||||
|
|
||||||
|
Find the appropriate section for your task: [reading Electron documentation](#reading-electron-documentation)
|
||||||
|
or [writing Electron documentation](#writing-electron-documentation).
|
||||||
|
|
||||||
|
## Написання документації для Electron
|
||||||
|
|
||||||
|
Існує кілька способів за допомогою яких ми ствоюємо документацію для Electron.
|
||||||
|
|
||||||
|
- Maximum one `h1` title per page.
|
||||||
|
- Use `bash` instead of `cmd` in code blocks (because of syntax highlighter).
|
||||||
|
- Doc `h1` titles should match object name (i.e. `browser-window` →
|
||||||
|
`BrowserWindow`).
|
||||||
|
- Hyphen separated filenames, however, are fine.
|
||||||
|
- No headers following headers, add at least a one-sentence description.
|
||||||
|
- Methods headers are wrapped in `code` ticks.
|
||||||
|
- Event headers are wrapped in single 'quotation' marks.
|
||||||
|
- No nesting lists more than 2 levels (unfortunately because of markdown
|
||||||
|
renderer).
|
||||||
|
- Add section titles: Events, Class Methods and Instance Methods.
|
||||||
|
- Use 'will' over 'would' when describing outcomes.
|
||||||
|
- Events and methods are `h3` headers.
|
||||||
|
- Optional arguments written as `function (required[, optional])`.
|
||||||
|
- Optional arguments are denoted when called out in list.
|
||||||
|
- Line length is 80-column wrapped.
|
||||||
|
- Platform specific methods are noted in italics following method header.
|
||||||
|
- ```### `method(foo, bar)` _OS X_```
|
||||||
|
- Prefer 'in the ___ process' over 'on'
|
||||||
|
|
||||||
|
### Переклад документації
|
||||||
|
|
||||||
|
Переклади документації знаходяться в дерикторії `docs-translations`.
|
||||||
|
|
||||||
|
Щоб додати переклад (або частковий переклад) документації:
|
||||||
|
|
||||||
|
- Create a subdirectory named by language abbreviation.
|
||||||
|
- Within that subdirectory, duplicate the `docs` directory, keeping the
|
||||||
|
names of directories and files same.
|
||||||
|
- Translate the files.
|
||||||
|
- Update the `README.md` within your language directory to link to the files
|
||||||
|
you have translated.
|
||||||
|
- Add a link to your translation directory on the main Electron [README](https://github.com/atom/electron#documentation-translations).
|
||||||
|
|
||||||
|
## Читання документації Electron
|
||||||
|
|
||||||
|
Кілька порад для того щоб легше зрозуміти синтаксис документації Electron.
|
||||||
|
|
||||||
|
### Методи
|
||||||
|
|
||||||
|
Приклад [методу](https://developer.mozilla.org/en-US/docs/Glossary/Method)
|
||||||
|
в документації:
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
`methodName(required[, optional]))`
|
||||||
|
|
||||||
|
* `require` String, **required**
|
||||||
|
* `optional` Integer
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
The method name is followed by the arguments it takes. Optional arguments are
|
||||||
|
notated by brackets surrounding the optional argument as well as the comma
|
||||||
|
required if this optional argument follows another argument.
|
||||||
|
|
||||||
|
Below the method is more detailed information on each of the arguments. The type
|
||||||
|
of argument is notated by either the common types:
|
||||||
|
[`String`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String),
|
||||||
|
[`Number`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number),
|
||||||
|
[`Object`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object),
|
||||||
|
[`Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)
|
||||||
|
or a custom type like Electron's [`webContent`](api/web-content.md).
|
||||||
|
|
||||||
|
### Події
|
||||||
|
|
||||||
|
Приклад [події](https://developer.mozilla.org/en-US/docs/Web/API/Event)
|
||||||
|
в документації:
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Подія: 'wake-up'
|
||||||
|
|
||||||
|
Повердає:
|
||||||
|
|
||||||
|
* `time` Текст
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
The event is a string that is used after a `.on` listener method. If it returns
|
||||||
|
a value it and its type is noted below. If you were to listen and respond to
|
||||||
|
this event it might look something like this:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
Alarm.on('wake-up', function(time) {
|
||||||
|
console.log(time)
|
||||||
|
})
|
||||||
|
```
|
|
@ -0,0 +1,53 @@
|
||||||
|
# 使用原生模块
|
||||||
|
|
||||||
|
Electron同样也支持原生模块,但由于和官方的Node相比使用了不同的V8引擎,如果你想编译原生模块,则需要手动设置Electron的headers的位置。
|
||||||
|
|
||||||
|
## 原生Node模块的兼容性
|
||||||
|
|
||||||
|
当Node开始换新的V8引擎版本时,原生模块可能“坏”掉。为确保一切工作正常,你需要检查你想要使用的原生模块是否被Electron内置的Node支持。你可以在[这里](https://github.com/atom/electron/releases)查看Electron内置的Node版本,或者使用`process.version`(参考:[快速入门](https://github.com/atom/electron/blob/master/docs/tutorial/quick-start.md))查看。
|
||||||
|
|
||||||
|
考虑到[NAN](https://github.com/nodejs/nan/)可以使你的开发更容易对多版本Node的支持,建议使用它来开发你自己的模块。你也可以使用[NAN](https://github.com/nodejs/nan/)来移植旧的模块到新的Node版本,以使它们可以在新的Electron下良好工作。
|
||||||
|
|
||||||
|
## 如何安装原生模块
|
||||||
|
|
||||||
|
如下三种方法教你安装原生模块:
|
||||||
|
|
||||||
|
### 最简单方式
|
||||||
|
|
||||||
|
最简单的方式就是通过[`electron-rebuild`](https://github.com/paulcbetts/electron-rebuild)包重新编译原生模块,它帮你自动完成了下载headers、编译原生模块等步骤:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm install --save-dev electron-rebuild
|
||||||
|
|
||||||
|
# 每次运行"npm install"时,也运行这条命令
|
||||||
|
./node_modules/.bin/electron-rebuild
|
||||||
|
|
||||||
|
# 在windows下如果上述命令遇到了问题,尝试这个:
|
||||||
|
.\node_modules\.bin\electron-rebuild.cmd
|
||||||
|
```
|
||||||
|
|
||||||
|
### 通过npm安装
|
||||||
|
|
||||||
|
你当然也可以通过`npm`安装原生模块。大部分步骤和安装普通模块时一样,除了以下一些系统环境变量你需要自己操作:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export npm_config_disturl=https://atom.io/download/atom-shell
|
||||||
|
export npm_config_target=0.33.1
|
||||||
|
export npm_config_arch=x64
|
||||||
|
export npm_config_runtime=electron
|
||||||
|
HOME=~/.electron-gyp npm install module-name
|
||||||
|
```
|
||||||
|
|
||||||
|
### 通过node-gyp安装
|
||||||
|
|
||||||
|
你需要告诉`node-gyp`去哪下载Electron的headers,以及下载什么版本:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ cd /path-to-module/
|
||||||
|
$ HOME=~/.electron-gyp node-gyp rebuild --target=0.29.1 --arch=x64 --dist-url=https://atom.io/download/atom-shell
|
||||||
|
```
|
||||||
|
|
||||||
|
`HOME=~/.electron-gyp`设置了去哪找开发时的headers。
|
||||||
|
`--target=0.29.1`设置了Electron的版本
|
||||||
|
`--dist-url=...`设置了Electron的headers的下载地址
|
||||||
|
`--arch=x64`设置了该模块为适配64bit操作系统而编译
|
119
docs-translations/zh-CN/tutorial/using-selenium-and-webdriver.md
Normal file
119
docs-translations/zh-CN/tutorial/using-selenium-and-webdriver.md
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
# 使用Selenium和WebDriver
|
||||||
|
|
||||||
|
引自[ChromeDriver - WebDriver for Chrome][chrome-driver]:
|
||||||
|
|
||||||
|
> WebDriver是一款开源的支持多浏览器的自动化测试工具。它提供了操作网页、用户输入、JavaScript执行等能力。ChromeDriver是一个实现了WebDriver与Chromium联接协议的独立服务。它也是由开发了Chromium和WebDriver的团队开发的。
|
||||||
|
|
||||||
|
为了能够使`chromedriver`和Electron一起正常工作,我们需要告诉它Electron在哪,并且让它相信Electron就是Chrome浏览器。
|
||||||
|
|
||||||
|
## 通过WebDriverJs配置
|
||||||
|
|
||||||
|
[WebDriverJs](https://code.google.com/p/selenium/wiki/WebDriverJs) 是一个可以配合WebDriver做测试的node模块,我们会用它来做个演示。
|
||||||
|
|
||||||
|
### 1. 启动ChromeDriver
|
||||||
|
|
||||||
|
首先,你要下载`chromedriver`,然后运行以下命令:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ./chromedriver
|
||||||
|
Starting ChromeDriver (v2.10.291558) on port 9515
|
||||||
|
Only local connections are allowed.
|
||||||
|
```
|
||||||
|
|
||||||
|
记住`9515`这个端口号,我们后面会用到
|
||||||
|
|
||||||
|
### 2. 安装WebDriverJS
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ npm install selenium-webdriver
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 联接到ChromeDriver
|
||||||
|
|
||||||
|
在Electron下使用`selenium-webdriver`和其平时的用法并没有大的差异,只是你需要手动设置连接ChromeDriver,以及Electron的路径:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const webdriver = require('selenium-webdriver');
|
||||||
|
|
||||||
|
var driver = new webdriver.Builder()
|
||||||
|
// "9515" 是ChromeDriver使用的端口
|
||||||
|
.usingServer('http://localhost:9515')
|
||||||
|
.withCapabilities({
|
||||||
|
chromeOptions: {
|
||||||
|
// 这里设置Electron的路径
|
||||||
|
binary: '/Path-to-Your-App.app/Contents/MacOS/Atom',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.forBrowser('electron')
|
||||||
|
.build();
|
||||||
|
|
||||||
|
driver.get('http://www.google.com');
|
||||||
|
driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');
|
||||||
|
driver.findElement(webdriver.By.name('btnG')).click();
|
||||||
|
driver.wait(function() {
|
||||||
|
return driver.getTitle().then(function(title) {
|
||||||
|
return title === 'webdriver - Google Search';
|
||||||
|
});
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
driver.quit();
|
||||||
|
```
|
||||||
|
|
||||||
|
## 通过WebdriverIO配置
|
||||||
|
|
||||||
|
[WebdriverIO](http://webdriver.io/)也是一个配合WebDriver用来测试的node模块
|
||||||
|
|
||||||
|
### 1. 启动ChromeDriver
|
||||||
|
|
||||||
|
首先,下载`chromedriver`,然后运行以下命令:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ chromedriver --url-base=wd/hub --port=9515
|
||||||
|
Starting ChromeDriver (v2.10.291558) on port 9515
|
||||||
|
Only local connections are allowed.
|
||||||
|
```
|
||||||
|
|
||||||
|
记住`9515`端口,后面会用到
|
||||||
|
|
||||||
|
### 2. 安装WebdriverIO
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ npm install webdriverio
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 连接到ChromeDriver
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const webdriverio = require('webdriverio');
|
||||||
|
var options = {
|
||||||
|
host: "localhost", // 使用localhost作为ChromeDriver服务器
|
||||||
|
port: 9515, // "9515"是ChromeDriver使用的端口
|
||||||
|
desiredCapabilities: {
|
||||||
|
browserName: 'chrome',
|
||||||
|
chromeOptions: {
|
||||||
|
binary: '/Path-to-Your-App/electron', // Electron的路径
|
||||||
|
args: [/* cli arguments */] // 可选参数,类似:'app=' + /path/to/your/app/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var client = webdriverio.remote(options);
|
||||||
|
|
||||||
|
client
|
||||||
|
.init()
|
||||||
|
.url('http://google.com')
|
||||||
|
.setValue('#q', 'webdriverio')
|
||||||
|
.click('#btnG')
|
||||||
|
.getTitle().then(function(title) {
|
||||||
|
console.log('Title was: ' + title);
|
||||||
|
})
|
||||||
|
.end();
|
||||||
|
```
|
||||||
|
|
||||||
|
## 工作流程
|
||||||
|
|
||||||
|
无需重新编译Electron,只要把app的源码放到[Electron的资源目录](https://github.com/atom/electron/blob/master/docs/tutorial/application-distribution.md)里就可直接开始测试了。
|
||||||
|
|
||||||
|
当然,你也可以在运行Electron时传入参数指定你app的所在文件夹。这步可以免去你拷贝-粘贴你的app到Electron的资源目录。
|
||||||
|
|
||||||
|
[chrome-driver]: https://sites.google.com/a/chromium.org/chromedriver/
|
|
@ -58,6 +58,7 @@ select the tag that matches your version.
|
||||||
|
|
||||||
### Modules for the Renderer Process (Web Page):
|
### Modules for the Renderer Process (Web Page):
|
||||||
|
|
||||||
|
* [desktopCapturer](api/desktop-capturer.md)
|
||||||
* [ipcRenderer](api/ipc-renderer.md)
|
* [ipcRenderer](api/ipc-renderer.md)
|
||||||
* [remote](api/remote.md)
|
* [remote](api/remote.md)
|
||||||
* [webFrame](api/web-frame.md)
|
* [webFrame](api/web-frame.md)
|
||||||
|
|
|
@ -123,7 +123,6 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
|
||||||
* `allowRunningInsecureContent` Boolean - Allow a https page to run
|
* `allowRunningInsecureContent` Boolean - Allow a https page to run
|
||||||
JavaScript, CSS or plugins from http URLs. Default is `false`.
|
JavaScript, CSS or plugins from http URLs. Default is `false`.
|
||||||
* `images` Boolean - Enables image support. Default is `true`.
|
* `images` Boolean - Enables image support. Default is `true`.
|
||||||
* `java` Boolean - Enables Java support. Default is `false`.
|
|
||||||
* `textAreasAreResizable` Boolean - Make TextArea elements resizable. Default
|
* `textAreasAreResizable` Boolean - Make TextArea elements resizable. Default
|
||||||
is `true`.
|
is `true`.
|
||||||
* `webgl` Boolean - Enables WebGL support. Default is `true`.
|
* `webgl` Boolean - Enables WebGL support. Default is `true`.
|
||||||
|
@ -135,8 +134,6 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
|
||||||
canvas features. Default is `false`.
|
canvas features. Default is `false`.
|
||||||
* `overlayScrollbars` Boolean - Enables overlay scrollbars. Default is
|
* `overlayScrollbars` Boolean - Enables overlay scrollbars. Default is
|
||||||
`false`.
|
`false`.
|
||||||
* `overlayFullscreenVideo` Boolean - Enables overlay fullscreen video. Default
|
|
||||||
is `false`
|
|
||||||
* `sharedWorker` Boolean - Enables Shared Worker support. Default is `false`.
|
* `sharedWorker` Boolean - Enables Shared Worker support. Default is `false`.
|
||||||
* `directWrite` Boolean - Enables DirectWrite font rendering system on
|
* `directWrite` Boolean - Enables DirectWrite font rendering system on
|
||||||
Windows. Default is `true`.
|
Windows. Default is `true`.
|
||||||
|
@ -750,3 +747,9 @@ Sets whether the window should be visible on all workspaces.
|
||||||
Returns whether the window is visible on all workspaces.
|
Returns whether the window is visible on all workspaces.
|
||||||
|
|
||||||
**Note:** This API always returns false on Windows.
|
**Note:** This API always returns false on Windows.
|
||||||
|
|
||||||
|
### `win.setIgnoreMouseEvents(ignore)` _OS X_
|
||||||
|
|
||||||
|
* `ignore` Boolean
|
||||||
|
|
||||||
|
Ignore all moused events that happened in the window.
|
||||||
|
|
69
docs/api/desktop-capturer.md
Normal file
69
docs/api/desktop-capturer.md
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
# desktopCapturer
|
||||||
|
|
||||||
|
The `desktopCapturer` module can be used to get available sources that can be
|
||||||
|
used to be captured with `getUserMedia`.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// In the renderer process.
|
||||||
|
var desktopCapturer = require('electron').desktopCapturer;
|
||||||
|
|
||||||
|
desktopCapturer.getSources({types: ['window', 'screen']}, function(error, sources) {
|
||||||
|
if (error) throw error;
|
||||||
|
for (var i = 0; i < sources.length; ++i) {
|
||||||
|
if (sources[i].name == "Electron") {
|
||||||
|
navigator.webkitGetUserMedia({
|
||||||
|
audio: false,
|
||||||
|
video: {
|
||||||
|
mandatory: {
|
||||||
|
chromeMediaSource: 'desktop',
|
||||||
|
chromeMediaSourceId: sources[i].id,
|
||||||
|
minWidth: 1280,
|
||||||
|
maxWidth: 1280,
|
||||||
|
minHeight: 720,
|
||||||
|
maxHeight: 720
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, gotStream, getUserMediaError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function gotStream(stream) {
|
||||||
|
document.querySelector('video').src = URL.createObjectURL(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUserMediaError(e) {
|
||||||
|
console.log('getUserMediaError');
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Methods
|
||||||
|
|
||||||
|
The `desktopCapturer` module has the following methods:
|
||||||
|
|
||||||
|
### `desktopCapturer.getSources(options, callback)`
|
||||||
|
|
||||||
|
* `options` Object
|
||||||
|
* `types` Array - An array of String that lists the types of desktop sources
|
||||||
|
to be captured, available types are `screen` and `window`.
|
||||||
|
* `thumbnailSize` Object (optional) - The suggested size that thumbnail should
|
||||||
|
be scaled, it is `{width: 150, height: 150}` by default.
|
||||||
|
* `callback` Function
|
||||||
|
|
||||||
|
Starts a request to get all desktop sources, `callback` will be called with
|
||||||
|
`callback(error, sources)` when the request is completed.
|
||||||
|
|
||||||
|
The `sources` is an array of `Source` objects, each `Source` represents a
|
||||||
|
captured screen or individual window, and has following properties:
|
||||||
|
* `id` String - The id of the captured window or screen used in
|
||||||
|
`navigator.webkitGetUserMedia`. The format looks like `window:XX` or
|
||||||
|
`screen:XX` where `XX` is a random generated number.
|
||||||
|
* `name` String - The described name of the capturing screen or window. If the
|
||||||
|
source is a screen, the name will be `Entire Screen` or `Screen <index>`; if
|
||||||
|
it is a window, the name will be the window's title.
|
||||||
|
* `thumbnail` [NativeImage](NativeImage.md) - A thumbnail image.
|
||||||
|
|
||||||
|
**Note:** There is no guarantee that the size of `source.thumbnail` is always
|
||||||
|
the same as the `thumnbailSize` in `options`. It also depends on the scale of
|
||||||
|
the screen or window.
|
|
@ -68,4 +68,4 @@ Returns the `webContents` that sent the message, you can call
|
||||||
`event.sender.send` to reply to the asynchronous message, see
|
`event.sender.send` to reply to the asynchronous message, see
|
||||||
[webContents.send][webcontents-send] for more information.
|
[webContents.send][webcontents-send] for more information.
|
||||||
|
|
||||||
[webcontents-send]: web-contents.md#webcontentssendchannel-args
|
[webcontents-send]: web-contents.md#webcontentssendchannel-arg1-arg2-
|
||||||
|
|
|
@ -26,7 +26,9 @@ Create a new `MenuItem` with the following method:
|
||||||
* `visible` Boolean
|
* `visible` Boolean
|
||||||
* `checked` Boolean
|
* `checked` Boolean
|
||||||
* `submenu` Menu - Should be specified for `submenu` type menu item, when
|
* `submenu` Menu - Should be specified for `submenu` type menu item, when
|
||||||
it's specified the `type: 'submenu'` can be omitted for the menu item
|
it's specified the `type: 'submenu'` can be omitted for the menu item.
|
||||||
|
If the value is not a `Menu` then it will be automatically converted to one
|
||||||
|
using `Menu.buildFromTemplate`.
|
||||||
* `id` String - Unique within a single menu. If defined then it can be used
|
* `id` String - Unique within a single menu. If defined then it can be used
|
||||||
as a reference to this item by the position attribute.
|
as a reference to this item by the position attribute.
|
||||||
* `position` String - This field allows fine-grained definition of the
|
* `position` String - This field allows fine-grained definition of the
|
||||||
|
|
|
@ -11,7 +11,7 @@ both processes.
|
||||||
|
|
||||||
The basic rule is: if a module is [GUI][gui] or low-level system related, then
|
The basic rule is: if a module is [GUI][gui] or low-level system related, then
|
||||||
it should be only available in the main process. You need to be familiar with
|
it should be only available in the main process. You need to be familiar with
|
||||||
the concept of [main process vs. renderer process][mai-process] scripts to be
|
the concept of [main process vs. renderer process][main-process] scripts to be
|
||||||
able to use those modules.
|
able to use those modules.
|
||||||
|
|
||||||
The main process script is just like a normal Node.js script:
|
The main process script is just like a normal Node.js script:
|
||||||
|
|
|
@ -25,7 +25,7 @@ myNotification.onclick = function () {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
While code and user experience across operating systems are similar, but there
|
While code and user experience across operating systems are similar, there
|
||||||
are fine differences.
|
are fine differences.
|
||||||
|
|
||||||
### Windows
|
### Windows
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
'atom/browser/api/lib/tray.coffee',
|
'atom/browser/api/lib/tray.coffee',
|
||||||
'atom/browser/api/lib/web-contents.coffee',
|
'atom/browser/api/lib/web-contents.coffee',
|
||||||
'atom/browser/lib/chrome-extension.coffee',
|
'atom/browser/lib/chrome-extension.coffee',
|
||||||
|
'atom/browser/lib/desktop-capturer.coffee',
|
||||||
'atom/browser/lib/guest-view-manager.coffee',
|
'atom/browser/lib/guest-view-manager.coffee',
|
||||||
'atom/browser/lib/guest-window-manager.coffee',
|
'atom/browser/lib/guest-window-manager.coffee',
|
||||||
'atom/browser/lib/init.coffee',
|
'atom/browser/lib/init.coffee',
|
||||||
|
@ -53,6 +54,7 @@
|
||||||
'atom/renderer/lib/web-view/web-view.coffee',
|
'atom/renderer/lib/web-view/web-view.coffee',
|
||||||
'atom/renderer/lib/web-view/web-view-attributes.coffee',
|
'atom/renderer/lib/web-view/web-view-attributes.coffee',
|
||||||
'atom/renderer/lib/web-view/web-view-constants.coffee',
|
'atom/renderer/lib/web-view/web-view-constants.coffee',
|
||||||
|
'atom/renderer/api/lib/desktop-capturer.coffee',
|
||||||
'atom/renderer/api/lib/exports/electron.coffee',
|
'atom/renderer/api/lib/exports/electron.coffee',
|
||||||
'atom/renderer/api/lib/ipc.coffee',
|
'atom/renderer/api/lib/ipc.coffee',
|
||||||
'atom/renderer/api/lib/ipc-renderer.coffee',
|
'atom/renderer/api/lib/ipc-renderer.coffee',
|
||||||
|
@ -81,6 +83,8 @@
|
||||||
'atom/browser/api/atom_api_content_tracing.cc',
|
'atom/browser/api/atom_api_content_tracing.cc',
|
||||||
'atom/browser/api/atom_api_cookies.cc',
|
'atom/browser/api/atom_api_cookies.cc',
|
||||||
'atom/browser/api/atom_api_cookies.h',
|
'atom/browser/api/atom_api_cookies.h',
|
||||||
|
'atom/browser/api/atom_api_desktop_capturer.cc',
|
||||||
|
'atom/browser/api/atom_api_desktop_capturer.h',
|
||||||
'atom/browser/api/atom_api_download_item.cc',
|
'atom/browser/api/atom_api_download_item.cc',
|
||||||
'atom/browser/api/atom_api_download_item.h',
|
'atom/browser/api/atom_api_download_item.h',
|
||||||
'atom/browser/api/atom_api_dialog.cc',
|
'atom/browser/api/atom_api_dialog.cc',
|
||||||
|
@ -200,8 +204,6 @@
|
||||||
'atom/browser/ui/atom_menu_model.h',
|
'atom/browser/ui/atom_menu_model.h',
|
||||||
'atom/browser/ui/cocoa/atom_menu_controller.h',
|
'atom/browser/ui/cocoa/atom_menu_controller.h',
|
||||||
'atom/browser/ui/cocoa/atom_menu_controller.mm',
|
'atom/browser/ui/cocoa/atom_menu_controller.mm',
|
||||||
'atom/browser/ui/cocoa/event_processing_window.h',
|
|
||||||
'atom/browser/ui/cocoa/event_processing_window.mm',
|
|
||||||
'atom/browser/ui/file_dialog.h',
|
'atom/browser/ui/file_dialog.h',
|
||||||
'atom/browser/ui/file_dialog_gtk.cc',
|
'atom/browser/ui/file_dialog_gtk.cc',
|
||||||
'atom/browser/ui/file_dialog_mac.mm',
|
'atom/browser/ui/file_dialog_mac.mm',
|
||||||
|
@ -376,6 +378,10 @@
|
||||||
'chromium_src/chrome/browser/extensions/global_shortcut_listener_x11.h',
|
'chromium_src/chrome/browser/extensions/global_shortcut_listener_x11.h',
|
||||||
'chromium_src/chrome/browser/extensions/global_shortcut_listener_win.cc',
|
'chromium_src/chrome/browser/extensions/global_shortcut_listener_win.cc',
|
||||||
'chromium_src/chrome/browser/extensions/global_shortcut_listener_win.h',
|
'chromium_src/chrome/browser/extensions/global_shortcut_listener_win.h',
|
||||||
|
'chromium_src/chrome/browser/media/desktop_media_list.h',
|
||||||
|
'chromium_src/chrome/browser/media/desktop_media_list_observer.h',
|
||||||
|
'chromium_src/chrome/browser/media/native_desktop_media_list.cc',
|
||||||
|
'chromium_src/chrome/browser/media/native_desktop_media_list.h',
|
||||||
'chromium_src/chrome/browser/printing/print_job.cc',
|
'chromium_src/chrome/browser/printing/print_job.cc',
|
||||||
'chromium_src/chrome/browser/printing/print_job.h',
|
'chromium_src/chrome/browser/printing/print_job.h',
|
||||||
'chromium_src/chrome/browser/printing/print_job_manager.cc',
|
'chromium_src/chrome/browser/printing/print_job_manager.cc',
|
||||||
|
|
|
@ -196,7 +196,7 @@ def create_chrome_version_h():
|
||||||
def touch_config_gypi():
|
def touch_config_gypi():
|
||||||
config_gypi = os.path.join(SOURCE_ROOT, 'vendor', 'node', 'config.gypi')
|
config_gypi = os.path.join(SOURCE_ROOT, 'vendor', 'node', 'config.gypi')
|
||||||
with open(config_gypi, 'w+') as f:
|
with open(config_gypi, 'w+') as f:
|
||||||
content = '\n{}'
|
content = "\n{'variables':{}}"
|
||||||
if f.read() != content:
|
if f.read() != content:
|
||||||
f.write(content)
|
f.write(content)
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ LINUX_DEPS = [
|
||||||
'libgtk2.0-dev',
|
'libgtk2.0-dev',
|
||||||
'libnotify-dev',
|
'libnotify-dev',
|
||||||
'libnss3-dev',
|
'libnss3-dev',
|
||||||
|
'libxtst-dev',
|
||||||
'gcc-multilib',
|
'gcc-multilib',
|
||||||
'g++-multilib',
|
'g++-multilib',
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,8 +7,8 @@ import sys
|
||||||
|
|
||||||
|
|
||||||
BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \
|
BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \
|
||||||
'http://gh-contractor-zcbenz.s3.amazonaws.com/libchromiumcontent'
|
'http://github-janky-artifacts.s3.amazonaws.com/libchromiumcontent'
|
||||||
LIBCHROMIUMCONTENT_COMMIT = '17a4337f7948a45b5ea4b8f391df152ba8db5979'
|
LIBCHROMIUMCONTENT_COMMIT = 'cfbe8ec7e14af4cabd1474386f54e197db1f7ac1'
|
||||||
|
|
||||||
PLATFORM = {
|
PLATFORM = {
|
||||||
'cygwin': 'win32',
|
'cygwin': 'win32',
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue